2010-08-29 33 views
13

Tôi muốn bắt đầu một tiến trình con (thực sự là cùng một ứng dụng bảng điều khiển) với các đặc quyền nâng cao nhưng với cửa sổ ẩn.Đặc quyền nâng cao không hoạt động với UseShellExecute = false

tôi làm gì tiếp theo:

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

var process = new Process 
{ 
    StartInfo = info 
}; 

process.Start(); 

và các công trình này:

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

Nhưng UseShellExecute = true tạo ra một cửa sổ mới và tôi cũng tôi không thể chuyển hướng đầu ra.

Vì vậy, khi tôi làm gì tiếp theo:

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(); 

này không nâng cao đặc quyền và mã trả về trên sai. Tại sao??

+0

BTW, bạn có thể viết 'DataReceivedEventHandler actionWrite = ...' và 'process.ErrorDataReceived + = actionWrite'. – SLaks

+0

Bạn có thể thử nghiệm sử dụng các sự kiện UseShellExecute = true, Verb = "runas" và ErrorDataReceived dưới dạng nhận xét @SLaks không? – Kiquenet

Trả lời

14

ProcessStartInfo.Verb sẽ chỉ có tác dụng nếu quá trình được bắt đầu bởi ShellExecuteEx(). Điều này yêu cầu UseShellExecute = true. Chuyển hướng I/O và ẩn cửa sổ chỉ có thể hoạt động nếu quá trình được khởi tạo bởi CreateProcess(). Điều này yêu cầu UseShellExecute = false.

Vâng, đó là lý do tại sao nó không hoạt động. Không chắc chắn nếu cấm để bắt đầu một quá trình ẩn mà bỏ qua UAC là cố ý. Có lẽ. Rất có thể.

Kiểm tra this Q+A cho tệp kê khai bạn cần để hiển thị lời nhắc độ cao UAC.

+0

Cảm ơn bạn rất nhiều vì mô tả hậu trường của WinAPI. Làm thế nào để bạn nghĩ rằng nó có thể để có được đặc quyền nâng cao theo yêu cầu cho một quá trình với cửa sổ ẩn? Hoặc đây là những thứ độc quyền lẫn nhau? – abatishchev

+0

Và có thể bật/tắt bằng cách sử dụng tệp kê khai không? I E. khi tôi bắt đầu ứng dụng của mình lần đầu tiên (theo cách thủ công) - không sử dụng tệp kê khai, khi thứ hai (theo lập trình) - bắt buộc sử dụng. – abatishchev

+0

Bắt đầu quá trình với các đặc quyền nâng cao mà người dùng không biết về nó là không thể. Bạn cần một .exe riêng biệt để nó có biểu hiện riêng của nó. Về cơ bản bạn chỉ cần phương thức Main(). –

0

Kiểm tra this answer.

Điều này dường như cung cấp giải pháp thay thế. Nhưng tôi khuyên bạn nên thử các phương pháp khác như Named Pipes khi bạn có quyền truy cập vào mã nguồn của quy trình con.

+1

Tôi chưa thử nghiệm phương pháp tiếp cận bài viết UAC, mặc dù nó có chứa một mẫu của chính nó. Nhưng nếu bạn có nghĩa là một mẫu cho tên ống, bạn có thể dễ dàng tìm thấy nhiều người trong số họ (như [this] (http://stackoverflow.com/questions/13806153/example-of-named-pipes) hoặc [this] (http: //www.codeproject.com/Tips/492231/Csharp-Async-Named-Pipes)) với một chút tìm kiếm. Vấn đề là giống như chuyển hướng I/O, bạn có thể sử dụng các luồng văn bản có tên là Pipes, để gửi và nhận dữ liệu (ngay cả khi hai tiến trình nằm trên các máy khác nhau). Tất nhiên bạn phải đối phó với một số sắc thái để có được một ứng dụng hoàn toàn làm việc. –

+0

@abatishchev IMHO, sử dụng Trace to File tốt hơn, không chuyển hướng đầu ra, verb = runas. Đặt tên Pipes là phức tạp hơn và phức tạp để gỡ lỗi dễ dàng. – Kiquenet

2

Trong trường hợp của tôi, nó là ok để có được kết quả đầu ra khi quá trình con nâng cao được thực hiện. Đây là giải pháp tôi đã đưa ra. Nó sử dụng tệp tạm thời:

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); 
+0

điều này thực sự dường như đang làm việc cho tôi. chi tiết phức tạp (cửa sổ 10, F #) - gist tại https://gist.github.com/ImaginaryDevelopment/f4bc33ae75bdf29e5aad8fd4045f193d – Maslow

+0

Câu trả lời được chấp nhận là giải thích, đây là giải pháp .. +1 – caesay

Các vấn đề liên quan