Elevare il privilegio del processo a livello di programmazione?

Sto cercando di installare un servizio utilizzando InstallUtil.exe ma invocato tramite Process.Start . Ecco il codice:

 ProcessStartInfo startInfo = new ProcessStartInfo (m_strInstallUtil, strExePath); System.Diagnostics.Process.Start (startInfo); 

dove m_strInstallUtil è il percorso completo ed exe a “InstallUtil.exe” e strExePath è il percorso / nome completo del mio servizio.

Funziona la syntax della riga di comando da un prompt dei comandi con privilegi elevati; l’esecuzione dalla mia app (utilizzando il codice sopra) non lo fa. Immagino di avere a che fare con un problema di elevazione del processo, quindi come potrei eseguire il mio processo in uno stato elevato? Devo guardare ShellExecute per questo?

Questo è tutto su Windows Vista. Sto eseguendo il processo nel debugger VS2008 elevato al privilegio di amministratore.

Ho anche provato a impostare startInfo.Verb = "runas"; ma non sembrava risolvere il problema.

È ansible indicare che il nuovo processo deve essere avviato con autorizzazioni elevate impostando la proprietà Verb dell’object startInfo su “runas”, come segue:

 startInfo.Verb = "runas"; 

Ciò comporterà il comportamento di Windows come se il processo fosse stato avviato da Explorer con il comando di menu “Esegui come amministratore”.

Ciò significa che il prompt UAC verrà visualizzato e dovrà essere riconosciuto dall’utente: se questo non è desiderabile (ad esempio perché si verificherà nel bel mezzo di un lungo processo), sarà necessario eseguire l’intero processo host con autorizzazioni elevate create e incorporate un Application Manifest (UAC) per richiedere il livello di esecuzione ‘highestAvailable’: ciò farà sì che il prompt UAC venga visualizzato non appena l’app viene avviata e causa l’esecuzione di tutti i processi figlio con autorizzazioni elevate senza ulteriori prompt .

Edit: Vedo che hai appena modificato la tua domanda per affermare che “runas” non ha funzionato per te. Questo è davvero strano, come dovrebbe (e fa per me in diverse app di produzione). Tuttavia, richiedere il processo genitore per funzionare con diritti elevati incorporando il manifest dovrebbe sicuramente funzionare.

Questo codice mette insieme quanto sopra e riavvia l’attuale app wpf con i privilegi di amministratore:

 if (IsAdministrator() == false) { // Restart program and run as admin var exeName = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo startInfo = new ProcessStartInfo(exeName); startInfo.Verb = "runas"; System.Diagnostics.Process.Start(startInfo); Application.Current.Shutdown(); return; } private static bool IsAdministrator() { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity); return principal.IsInRole(WindowsBuiltInRole.Administrator); } // To run as admin, alter exe manifest file after building. // Or create shortcut with "as admin" checked. // Or ShellExecute(C# Process.Start) can elevate - use verb "runas". // Or an elevate vbs script can launch programs as admin. // (does not work: "runas /user:admin" from cmd-line prompts for admin pass) 

Aggiornamento: il modo manifest dell’app è preferito:

Fare clic con il tasto destro del mouse su progetto in Visual Studio, aggiungere, nuovo file manifest dell’applicazione, modificare il file in modo da richiedere l’impostazione amministratore come mostrato in precedenza.

Un problema con il modo originale: se si inserisce il codice di riavvio in app.xaml.cs OnStartup, è comunque ansible avviare brevemente la finestra principale anche se è stato chiamato Shutdown. La mia finestra principale è esplosa se app.xaml.cs init non è stata eseguita e in determinate condizioni di gara lo farebbe.

Secondo questo articolo , solo ShellExecute controlla il manifest incorporato e richiede all’utente l’elevazione, se necessario, mentre CreateProcess e altre API no. Spero che sia d’aiuto.

 [PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")] 

Questo lo farà senza UAC – non c’è bisogno di iniziare un nuovo processo. Se l’utente in esecuzione è membro del gruppo Admin come per il mio caso.

È necessario utilizzare la rappresentazione per elevare lo stato.

 WindowsIdentity identity = new WindowsIdentity(accessToken); WindowsImpersonationContext context = identity.Impersonate(); 

Non dimenticare di annullare il contesto rappresentato quando hai finito.