c # - Sådan oprettes en Windows Service via en anden Windows-tjeneste

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har lidt problemer med et program, jeg er ved at udvikle.
Her er scenariet: Jeg har to Windows Services (Service A og Service B) skrevet i C #.


Service A er ansvarlig for at overføre data mellem to applikationer (ved hjælp af WebServices, FTP-forbindelser osv.). Det er også ansvarligt for at opdatere Service B.


Service B er ansvarlig for at opdatere Service A og opdatere et webapplikation.


Den grundlæggende drift af opdateringer er (lad os sige, at dette er processen med at opdatere service A, udført af Service B):



  1. Søg efter opdateringer via WebServices

  2. Hvis der er en ny version, skal du stoppe tjenesten (ved hjælp af C # ServiceController).

  3. Sikkerhedskopier aktuelle filer af tjenesten (så jeg kan gøre en tilbagekaldning, hvis noget går galt)

  4. Afinstaller tjenesten (ved hjælp af sc delete kommando)

  5. Download de opdaterede filer af tjenesten (ved hjælp af FTP-forbindelse)

  6. Udfør nogle SQL Server-scripts, hvis der findes

  7. Installer Windows-tjenesten (ved hjælp af sc create-kommandoen)

  8. Start service (ved hjælp af C # ServiceController)



Alt går glat til trin 7. Jeg fandt ud af at problemet er, at brugeren gør opdateringen (brugeren, der kører Service B), ikke har tilladelser til at oprette nye Windows-tjenester, så SC Create returnerer altid noget som '[[SC]] OpenSCManager FAILED 5: Adgang nægtes '
 Bemærk, at jeg havde begge tjenester, der kører med LocalSystem-kontoen. Så jeg regnede med, at denne konto ikke kan oprette nye Windows Services (rette mig, hvis jeg har antaget forkert).


Efter dette har jeg oprettet en ny Windows-bruger, bare for at køre tjenesterne. Ideen var at give denne bruger de nødvendige tilladelser (for at dele fælles, filer og skabe tjenester). Denne bruger kan dog stadig ikke oprette tjenesten.


Her er hvad jeg har prøvet:



  1. Giv brugeren cmd.exe og sc.exe tilladelser (ved hjælp af CACLS).

  2. Brug PsExec til at køre cmd (med -i -s) i stedet for cmd.exe direkte.

  3. Brug af SubInAcl-kommandoen, så brugeren har tilladelser til begge Windows-tjenester. Men her er sagen, da jeg ikke har nogen Service, så det virker ikke.



Nogle bemærkninger: [1]



  • Denne Windows-tjeneste har ikke noget installationsprogram.

  • SC-kommandoen køres ved hjælp af C # ProcessStartInfo.

  • Kommandoen SC angiver brugeren og adgangskoden til den Windows-bruger, jeg har oprettet.

  • Jeg vil virkelig ikke have Windows Services kørt under en brugerkonto med administrative privilegier.



Jeg ved, at denne tråd ligner nogle allerede her Automatisk opdatering af en Windows-tjeneste, men jeg kan ikke finde nogen arbejdsløsning overalt.


Undskyld for den lange tekst

Bedste reference


Jeg tror, ​​at dit grundlæggende design er skørt og mangelfuldt. Du bør ikke slette og oprette tjenester som led i normal service.


Hvad jeg ville gøre ville være at arrangere, at enhver tjeneste, der skal opdateres på plads, var i stand til selv at gøre det. Indsæt grundlæggende koden, der er underlagt opdatering i en DLL. Koden i tjenesten EXE er bare en tynd vært med ansvar for at indlæse hoveddll'en og påberåbe sig den vigtigste behandlingssløjfe. Når EXE bestemmer, at det er på tide at opdatere det, overfører den nye DLL, formodentlig kontrol via en hash, at den downloades korrekt. Dernæst afsluttes behandlingssløjfen, den gamle DLL aflastes, den nye DLL er indlæst, og behandlingssløjfen startes igen.


Denne tilgang er meget mindre påtrængende og undgår alle tilladelses- og rettigheder. Du kan skrive en enkelt tjeneste vært EXE og have flere DLL'er indeholdende logikken.