Domanda

Voglio iniziare un processo figlio (anzi lo stesso, console app) con privilegi elevati, ma con finestra nascosta.

devo fare:

var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
    UseShellExecute = true, // !
    Verb = "runas", 
};

var process = new Process
{
    StartInfo = info
};

process.Start();

e funziona:

var identity = new WindowsPrincipal(WindowsIdentity.GetCurrent());
identity.IsInRole(WindowsBuiltInRole.Administrator); // returns true

Ma UseShellExecute = true crea una nuova finestra e ho anche non posso uscita reindirizzamento.

Così, quando lo faccio successivo:

var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
    RedirectStandardError = true,
    RedirectStandardOutput = true,
    UseShellExecute = false, // !
    Verb = "runas"
};

var process = new Process
{
    EnableRaisingEvents = true,
    StartInfo = info
};

DataReceivedEventHandler actionWrite = (sender, e) =>
{
    Console.WriteLine(e.Data);
};

process.ErrorDataReceived += actionWrite;
process.OutputDataReceived += actionWrite;

process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();

Questa non privilegi e codice di cui sopra restituisce false Elevate. Perchè ??

È stato utile?

Soluzione

ProcessStartInfo.Verb avrà effetto solo se il processo è avviato da ShellExecuteEx (). Che richiede UseShellExecute = true. Riorientare I / O e nascondere la finestra può unica opera se il processo è avviato da CreateProcess (). Che richiede UseShellExecute = false.

Beh, è ??per questo che non funziona. Non sono sicuro se vietando ad avviare un processo nascosto che bypassa UAC è stato intenzionale. Probabilmente. molto , probabilmente.

questo Q + a per il manifesto è necessario visualizzare l'elevazione UAC.

Altri suggerimenti

Nel mio caso, non era male per ottenere i risultati una volta che il processo figlio elevato è fatto. Ecco la soluzione mi è venuta. Esso utilizza un file temporaneo:

var output = Path.GetTempFileName();
var process = Process.Start(new ProcessStartInfo
{
    FileName = "cmd",
    Arguments = "/c echo I'm an admin > " + output, // redirect to temp file
    Verb = "runas", // UAC prompt
    UseShellExecute = true,
});
process.WaitForExit();
string res = File.ReadAllText(output);
// do something with the output
File.Delete(output);

questa risposta .

Questo sembra fornire una soluzione. Ma vi consiglio di provare altri metodi come Named Pipes quando si ha accesso al codice sorgente del processo figlio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top