C # Windows Service, der kører et installationspakke problem

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har designet en Windows-tjeneste, der regelmæssigt kontrollerer, om en bestemt applikation er installeret, og når den finder, at den ikke er installeret, downloades den fra den delte netværksplacering, er filen en stille og uovervåget installeringseksempel (selvinstallation).


Jeg har problemer med at køre installationsprogrammet, så jeg besluttede at i stedet for at prøve at køre installationsprogrammet, køre en lille hej verden windows-formular app, bare for at se om denne enkle ting virker.


Efter et par forvirrede timer opdagede jeg endelig, at hello world app faktisk kører, men under en anden bruger - specifikt lokal maskine. I de næste par timer fandt jeg ud af, at jeg måtte slukke for UAC (Vista/7) og tillade tjenesten at interagere med skrivebordet. Efter dette fik jeg endelig en besked på mit skrivebord, at en tjeneste forsøger at køre noget, og at jeg måtte beslutte, om jeg ville tillade det eller ej.


Når jeg trykker på tilladelse - jeg er taget til en anden GUI (forskellig fra min desktop) og hello verden løber normalt derefter.


Nu, selvom dette helt sikkert er et fremskridt, er jeg stadig miles væk fra at installere en app under den nuværende brugerkonto.


Et problem, jeg havde, var at indstille Windows-tjenesten til at køre som en bestemt bruger. Når jeg bruger installutil.exe på den slags WS, beder jeg mig om brugernavnet og adgangskoden, jeg indtaster de rigtige (admin privilegerede) data, og det fejler at installere.


Hvad jeg vil opnå er at have en Windows-service installere en tavsinstallationspakke uden at afbryde brugeren på nogen måde. Test-tavsinstallationspakken er netramme 2.0 - Jeg har brug for at installere som om brugeren selv har klikket på det.


Jeg kræver ikke nogen kode (men det ville være velkommen), bare pege mig i den rigtige retning, tak på forhånd!

Bedste reference


Jeg ved ikke, hvordan det er gjort i C #, men jeg vil forklare konceptet.


Når du er i Windows Service, bruger du applikationen en SYSTEM-bruger, fordi programmet kører lige før nogen login er udført.


Også fra win7 kan lokale servicekonti ikke vise GUI på grund af vigtige sikkerhedsproblemer som at forårsage, at applikationen kører cmd.exe nogen form for explorer, der gør det muligt for brugeren at udføre ting, han/hun ikke tror på at gøre (jeg tror, ​​du kan omgå Det er ikke sikkert, men det anbefales ikke alligevel, så gør det ikke).


Så du har 2 muligheder:



  1. Opret en anden applikation, der kører under brugerens session, og du kan kommunikere med den ved hjælp af RPC (som .Net fjernelse). Du kan placere applikationen i brugerens opstart.

  2. Den bedre måde efter min mening bruger CreateProcessAsUser () (jeg ved ikke, hvordan den hedder i C #). Hver bruger har et token, fordi du er en tjeneste, har du tilladelse til at få brugerens primære token, der giver dig mulighed for at oprette processer under brugerens konto.
    CreateProcessAsUser () opretter en proces, og det får også et token til at køre processen som denne bruger.



Nogle få ting om tokens, til CreateProcessAsUser, skal du få brugerens token. Den nemmeste måde at gøre det på fra en Windows-tjeneste (og kun Windows-tjeneste) bruger WTSQuestUserToken. Du giver funktionen sessionens id til brugerens s session og du får tilbage et primært token.


Denne metode er IKKE perfekt, men den er let og velegnet til de fleste tilfælde. Det virker ikke, hvis der er 2 brugere under samme sessionID (sessionID == terminal server session ID), som kan gøres ved hjælp af Run As fra explorer. Men jeg tror jeg fik dette svar nok kompliceret, så hvis du WTSQueryUserToken () er ikke god nok til dig, lad mig vide, og jeg vil forklare mere grundigt (og selvfølgelig bliver det mere komplekst).


Held og lykke!

Andre referencer 1


Du finder en tilstrækkelig detaljeret forklaring på hvorfor du ser den adfærd du beskriver i mine svar her og her, hvis du er nysgerrig.


Men uanset at løsningen er at finde en alternativ tilgang. Windows Services kan ikke vise en brugergrænseflade, og de kan ikke køre i forbindelse med en bestemt bruger. De er simpelthen ikke en levedygtig mulighed for det, du vil gøre. Deaktivering af UAC er også ikke en acceptabel mulighed.


Det er svært at forestille sig, hvorfor du skal gøre det fra en Windows-service i første omgang. En baggrundsproces, der kører, når en bruger logger ind, virker som den bedre tilgang. Det behøver ikke at være nogen grænseflade i det hele taget, men det kan stadig pope op i et vindue eller på anden måde interagere med brugeren, når den vælger det.