2013-04-01 18 views
6

Chcę zezwolić użytkownikom na uruchamianie narzędzia wiersza poleceń jako administrator z poziomu mojego programu bez uprawnień administratora i dla mojego programu, aby uzyskać dane wyjściowe. Narzędzie jest niezależne, ale jest dystrybuowane z moim programem.Uruchom nowy proces jako administrator i odczytaj standardowe wyjście.

Mogę redirect the output of a program i mogę run a program as administrator, ale nie mogę wykonać obu jednocześnie.

Jedyne, co mogę dostać się do pracy w tej chwili jest za pomocą cmd.exe przekierować dane wyjściowe do pliku, np:

using System.Windows.Forms; 
using System.Diagnostics; 
using System.IO; 
using System.Reflection; 

string appDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
string utilityPath = Path.Combine(appDirectory, "tools", "utility.exe"); 
string tempFile = Path.GetTempFileName(); 

Process p = new Process(); 
// hide the command window 
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
p.StartInfo.FileName = "cmd.exe"; 
// run the tool, redirect the output to the temp file and then close. 
p.StartInfo.Arguments = " /C \"\"" + utilityPath + "\" > \"" + tempFile + "\"\""; 
p.StartInfo.Verb = "runas"; // run as administrator 
p.Start(); 
p.WaitForExit(); 

// get the output, delete the file and show the output to the user 
string output = File.ReadAllText(tempFile); 
File.Delete(tempFile); 
MessageBox.Show(output); 

ten ma dwa problemy: 1) Używa pliku tymczasowego i 2) UAC jest dla cmd.exe, a nie narzędzia. Czy na pewno jest lepszy sposób na zrobienie tego?

+0

Jeśli wszystko, co cię interesuje, to jak wychwycić wyniki innego procesu, to jest to zduplikowane pytanie; patrz np. [Jak uchwycić standardowe wyjście/błąd w Process.Start()?] (Http://stackoverflow.com/questions/3633653/how-to-capture-the-standard-output-error-of-- process -start? rq = 1). – stakx

+0

Myślę, że to, czego nie udało mi się wyjaśnić, było uprzywilejowaną różnicą. Moja aplikacja działa jako standardowy użytkownik, a narzędzie działa jako administrator. O ile mogę powiedzieć, normalny sposób przekierowania wyjścia nie działa w tej sytuacji. – ChrisD

Odpowiedz

3

Zamiast wykonywania za pomocą nowego cmd, spróbuj bezpośrednio uruchomić narzędzie. Zamiast przekierowywać do pliku, przekieruj standardowe wyjście, aby odczytać je z twojego programu. Aby uruchomić jako administrator, musisz użyć nazwy użytkownika i hasła administratora (pobranych z here). Musisz ustawić swoją metodę jako unsafe:

unsafe public static void Main(string[] args){ 
    Process p = new Process(); 
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
    // set admin user and password 
    p.StartInfo.UserName = "adminusername"; 
    char[] chArray = "adminpassword".ToCharArray(); 
    System.Security.SecureString str; 
    fixed (char* chRef = chArray) { 
     str = new System.Security.SecureString(chRef, chArray.Length); 
    } 
    p.StartInfo.Password = str; 
    // run and redirect as usual 
    p.StartInfo.FileName = utilityPath; 
    p.StartInfo.UseShellExecute = false; 
    p.StartInfo.RedirectStandardOutput = true; 
    p.Start(); 
    string output = p.StandardOutput.ReadToEnd(); 
    Console.WriteLine(output); 
    p.WaitForExit(); 
} 
+2

Powinieneś użyć 'using (Process p = new Process())' lub wywołaj 'p.Dispose()' after 'p.WaitForExit()'. –

+0

Występuje błąd "Obiekt procesu musi mieć właściwość UseShellExecute ustawioną na wartość false w celu przekierowania strumieni IO". Więc dodaję "p.StartInfo.UseShellExecute = false;" ale potem przestaje działać jako administrator: "Wymagana operacja wymaga podniesienia". – ChrisD

+0

Sprawdź nową odpowiedź –

0

This robi magię, choć jej nie testowane.

Jest napisany w języku C++, ale można łatwo utworzyć wrapper API, aby można go było wywołać z języka C#, używając DllImport.

Powiązane problemy