Nâng cao quy trình đặc quyền theo chương trình?


147

Tôi đang cố gắng cài đặt một dịch vụ bằng InstallUtil.exe nhưng được gọi qua Process.Start. Đây là mã:

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

nơi m_strInstallUtillà đường dẫn đầy đủ điều kiện và exe để "InstallUtil.exe" và strExePathlà đầy đủ đường dẫn / tên để dịch vụ của tôi.

Chạy cú pháp dòng lệnh từ một dấu nhắc lệnh nâng cao hoạt động; chạy từ ứng dụng của tôi (sử dụng mã trên) thì không. Tôi giả sử tôi đang xử lý một số vấn đề về độ cao quá trình, vậy làm cách nào để chạy quy trình của tôi ở trạng thái nâng cao? Tôi có cần phải xem xét ShellExecuteđiều này?

Đây là tất cả trên Windows Vista. Tôi đang chạy quy trình trong trình gỡ lỗi VS2008 được nâng lên thành đặc quyền quản trị viên.

Tôi cũng đã thử cài đặt startInfo.Verb = "runas";nhưng dường như không giải quyết được vấn đề.


Sau khi tôi đã thêm startInfo.UseShellExecute = true;vào, startInfo.Verb = "runas";nó hoạt động tốt với tôi.
Matt

Câu trả lời:


172

Bạn có thể chỉ ra quy trình mới sẽ được bắt đầu với quyền nâng cao bằng cách đặt thuộc tính Verb của đối tượng startInfo của bạn thành 'runas', như sau:

startInfo.Verb = "runas";

Điều này sẽ khiến Windows hoạt động như thể quá trình đã được bắt đầu từ Explorer với lệnh menu "Run as Administrator".

Điều này không có nghĩa là lời nhắc UAC sẽ xuất hiện và người dùng cần phải thừa nhận: nếu điều này là không mong muốn (ví dụ vì nó sẽ xảy ra ở giữa một quy trình dài), bạn sẽ cần chạy toàn bộ quy trình máy chủ của mình với nâng cao quyền bằng cách Tạo và nhúng Bản kê khai ứng dụng (UAC) để yêu cầu mức thực thi 'cao nhất có sẵn': điều này sẽ khiến lời nhắc UAC xuất hiện ngay khi ứng dụng của bạn được khởi động và khiến tất cả các tiến trình con chạy với quyền nâng cao mà không cần nhắc thêm .

Chỉnh sửa: Tôi thấy bạn vừa chỉnh sửa câu hỏi của mình để nói rằng "runas" không phù hợp với bạn. Điều đó thực sự kỳ lạ, vì nó nên (và đối với tôi trong một số ứng dụng sản xuất). Yêu cầu quá trình cha mẹ để chạy với quyền nâng cao bằng cách nhúng tệp kê khai chắc chắn sẽ hoạt động.


9
"Runas" cũng không làm việc cho tôi. Có thể là nó chỉ hoạt động với UAC tắt?
Dirk Vollmar

18
@LukePuplett Tôi cảm ơn họ. Đó là một cách tuyệt vời để giảm thiểu cài đặt root-kit mà không thực sự tách biệt hoàn toàn vai trò của người dùng.
Colton

6
@Sparksis, nhưng cũng có một quan điểm khác. Những người biết cách bảo vệ HĐH của họ, họ biết cách làm điều đó mà không cần UAC. Và người dùng giả, những người không biết phòng thủ là gì, họ đang nhấp vào 'CÓ' mỗi khi họ thấy cửa sổ UAC. Ngoài ra, không có gì có thể ngăn chặn những kẻ tấn công xấu, những kẻ viết virus, sử dụng khai thác để vượt qua nó;) Vì vậy, tôi đồng ý với LukePuplett =)
Jet

24
Có vẻ như bạn cũng phải thiết lập startInfo.ShellExecute=trueđể nó hoạt động ... tôi cũng không thể làm cho phương thức này hoạt động với các tệp thực thi trên mạng chia sẻ (phải sao chép chúng vào thư mục tạm thời cục bộ trước khi chạy). ..
TCC

7
@Jet Xin lỗi nhưng đó là suy nghĩ sai lầm. Mỗi khi hộp thoại UAC hiển thị trong khi cài đặt, đó là lỗi hệ thống. Nơi có giá trị là khi bạn nhìn thấy một hộp UAC mà không chạy thứ gì đó yêu cầu độ cao. Không quan trọng bạn chuyên nghiệp như thế nào - bất kỳ ai trong chúng tôi - nghĩ rằng chúng tôi đang ở trên PC của chúng tôi, bạn không thể chặn các lượt tải xuống 0 ngày / lần lái xe một cách kỳ diệu (ví dụ như gần đây trên trang web chính thức của giải thưởng Nobel). Nếu bạn duyệt trang web đó và nhận được lời nhắc UAC, bạn sẽ biết có gì đó không đúng. Khi tắt UAC, bạn sẽ không bao giờ biết mình vừa tham gia một mạng botnet. Chi phí cảnh báo trước là thỉnh thoảng phải bấm Có
Cơ bản

46

Mã này kết hợp tất cả các yếu tố trên lại với nhau và khởi động lại ứng dụng wpf hiện tại với quyền riêng tư của quản trị viên:

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)

Cập nhật: Cách hiển thị ứng dụng được ưa thích:

Nhấp chuột phải vào dự án trong studio trực quan, thêm, tệp kê khai ứng dụng mới, thay đổi tệp để bạn đã đặt Yêu cầu quản trị viên như được hiển thị ở trên.

Một vấn đề với cách ban đầu: Nếu bạn đặt mã khởi động lại trong app.xaml.cs OnStartup, nó vẫn có thể khởi động nhanh cửa sổ chính ngay cả khi Shutdown được gọi. Cửa sổ chính của tôi bật lên nếu init.xaml.cs không chạy và trong một số điều kiện cuộc đua nhất định, nó sẽ làm điều này.


Xem dưới đây để cải thiện.
JCCyC

Yêu cầu quản trị viên đã không làm việc trong trường hợp của tôi. Vì vậy, tôi phải làm theo cách của bạn. Điều này đã giải quyết vấn đề của tôi! cảm ơn bạn. Nhưng tôi đã phải đặt Ứng dụng sơ thẩm thành sai.
chris

Điều này làm việc cho tôi. Tôi cũng đã thông qua bản gốc string[] argscho quá trình hồi sinh.
DotNetPadawan


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

Điều này sẽ làm điều đó mà không cần UAC - không cần bắt đầu một quy trình mới. Nếu người dùng đang chạy là thành viên của nhóm Quản trị viên như trường hợp của tôi.


3
Sử dụng mã này, tôi gặp lỗi về quyền: "Yêu cầu cấp phép thực thể bảo mật không thành công." :(
Leonardo

Có lẽ "Nếu người dùng đang chạy là memeber của Admin" *
hB0

1
thú vị - điều này có thể đi trên bất kỳ phương thức nào, không chỉ là một phương thức hành động (tôi thậm chí đã thử nó trên phương thức được xác định trong trang ASPX)
Simon_Weaver

1

Bạn nên sử dụng Mạo danh để nâng cao trạng thái.

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

Đừng quên hoàn tác bối cảnh mạo danh khi bạn hoàn thành.


28
Bạn chưa nói làm thế nào để có được accessToken. LogonUser sẽ cung cấp bối cảnh bảo mật bị hạn chế của người dùng khi bật UAC.
cwa

Nếu bạn đang sử dụng VSTS, bạn có thể nhận được Mã thông báo truy cập cá nhân từ Cài đặt trong Cổng thông tin web. (Tìm biểu tượng cài đặt bên cạnh ảnh người dùng.) MSDocs
Su Llewellyn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.