Meningkatkan hak istimewa proses secara terprogram?

147

Saya mencoba untuk menginstal layanan menggunakan InstallUtil.exe tetapi dipanggil melalui Process.Start. Berikut kodenya:

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

di mana m_strInstallUtiljalur yang sepenuhnya memenuhi syarat dan exe untuk "InstallUtil.exe" dan strExePathjalur / nama yang sepenuhnya memenuhi syarat untuk layanan saya.

Menjalankan sintaks baris perintah dari command prompt yang ditinggikan berfungsi; lari dari aplikasi saya (menggunakan kode di atas) tidak. Saya berasumsi saya sedang berurusan dengan beberapa masalah peningkatan proses, jadi bagaimana saya menjalankan proses saya dalam keadaan tinggi? Apakah saya perlu melihat ShellExecuteini?

Ini semua pada Windows Vista. Saya menjalankan proses dalam debugger VS2008 yang ditingkatkan menjadi hak istimewa admin.

Saya juga mencoba pengaturan startInfo.Verb = "runas";tetapi sepertinya tidak menyelesaikan masalah.

Scott Marlowe
sumber
Setelah saya menambahkan startInfo.UseShellExecute = true;selain startInfo.Verb = "runas";itu berfungsi dengan baik untuk saya.
Matt

Jawaban:

172

Anda dapat menunjukkan proses baru harus dimulai dengan izin yang lebih tinggi dengan mengatur properti Verb objek startInfo Anda ke 'runas', sebagai berikut:

startInfo.Verb = "runas";

Ini akan menyebabkan Windows berperilaku seolah-olah proses telah dimulai dari Explorer dengan perintah menu "Run as Administrator".

Ini berarti UAC prompt akan muncul dan perlu diakui oleh pengguna: jika ini tidak diinginkan (misalnya karena akan terjadi di tengah proses yang panjang), Anda harus menjalankan seluruh proses host dengan izin yang ditinggikan oleh Create and Embed an Application Manifest (UAC) membutuhkan tingkat pelaksanaan 'tertinggi yang tersedia': ini akan menyebabkan permintaan UAC muncul segera setelah aplikasi Anda dimulai, dan menyebabkan semua proses anak berjalan dengan izin yang ditinggikan tanpa permintaan tambahan .

Sunting: Saya melihat Anda baru saja mengedit pertanyaan Anda untuk menyatakan bahwa "runas" tidak berfungsi untuk Anda. Itu benar-benar aneh, sebagaimana mestinya (dan itu berlaku untuk saya di beberapa aplikasi produksi). Namun, mengharuskan proses induk untuk dijalankan dengan hak-hak tinggi dengan menyematkan manifes.

mdb
sumber
9
"runa" juga tidak berhasil untukku. Mungkinkah hanya bekerja dengan UAC dimatikan?
Dirk Vollmar
18
@LukePuplett saya ucapkan terima kasih. Ini cara yang bagus untuk mengurangi instalasi root-kit tanpa benar-benar memisahkan peran pengguna sepenuhnya.
Colton
6
@Parkpark, tetapi ada juga sudut pandang lain. Orang-orang yang tahu bagaimana mempertahankan OS mereka, mereka tahu bagaimana melakukannya tanpa UAC. Dan pengguna tiruan, yang tidak tahu apa pertahanan, mereka mengklik 'YA' setiap kali mereka melihat jendela UAC. Juga tidak ada yang dapat mencegah peretas-virus-penulis menggunakan eksploit untuk mem-bypassnya;) Jadi saya setuju dengan LukePuplett =)
Jet
24
Sepertinya Anda harus mengatur startInfo.ShellExecute=truejuga agar ini berfungsi ... juga saya belum bisa mendapatkan metode ini untuk bekerja dengan file yang dapat dieksekusi yang berada di jaringan berbagi (harus menyalinnya ke direktori temp lokal sebelum menjalankan). ..
TCC
7
@Jet Maaf tapi itu pola pikir yang salah. Setiap kali dialog UAC ditampilkan saat instalasi, itu merupakan kegagalan sistem. Di mana itu berharga adalah ketika Anda melihat kotak UAC tanpa menjalankan sesuatu yang membutuhkan ketinggian. Tidak masalah seberapa pro Anda - siapa pun di antara kita - berpikir kami ada di PC kami, Anda tidak dapat secara ajaib memblokir unduhan nol hari / drive-by (mis. Yang terbaru di situs Hadiah Nobel resmi). Jika Anda meramban situs itu dan mendapatkan prompt UAC, Anda akan tahu ada sesuatu yang salah. Dengan UAC off, Anda tidak akan pernah tahu Anda baru saja bergabung dengan botnet. Biaya peringatan di muka adalah harus mengklik Ya sesekali
Basic
46

Kode ini menyatukan semua di atas dan memulai kembali aplikasi WPF saat ini dengan admin privs:

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)

Pembaruan: Cara manifes aplikasi lebih disukai:

Klik kanan proyek di studio visual, tambahkan, file manifes aplikasi baru, ubah file sehingga Anda memerlukan set Administrator seperti yang ditunjukkan di atas.

Masalah dengan cara aslinya: Jika Anda meletakkan kode restart di app.xaml.cs OnStartup, masih dapat memulai jendela utama secara singkat meskipun Shutdown dipanggil. Jendela utama saya meledak jika app.xaml.cs init tidak dijalankan dan dalam kondisi balapan tertentu ia akan melakukan ini.

Curtis Yallop
sumber
Lihat di bawah untuk perbaikan.
JCCyC
memerlukanAdministrator tidak berfungsi dalam kasus saya. Jadi saya harus melakukannya dengan cara Anda. Ini menyelesaikan masalah saya! Terima kasih. Tetapi saya harus mengatur Aplikasi Single Instance ke false.
chris
Ini berhasil untuk saya. Saya juga menyerahkan yang asli string[] argske proses respawned.
DotNetPadawan
7
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

Ini akan melakukannya tanpa UAC - tidak perlu memulai proses baru. Jika pengguna yang menjalankan adalah anggota grup Admin seperti untuk kasus saya.

hB0
sumber
3
Menggunakan kode ini saya mendapatkan kesalahan izin: "Permintaan izin entitas keamanan gagal." :(
Leonardo
Mungkin "Jika pengguna yang menjalankan memeber dari Admin" *
hB0
1
menarik - ini dapat digunakan pada metode apa pun, bukan hanya metode tindakan (Saya bahkan mencobanya pada metode yang didefinisikan dalam halaman ASPX)
Simon_Weaver
1

Anda harus menggunakan Peniruan identitas untuk meningkatkan status.

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

Jangan lupa untuk membatalkan konteks yang ditiru ketika Anda selesai.

Vijesh VP
sumber
28
Anda belum mengatakan cara mendapatkan accessToken. LogonUser akan memberikan konteks keamanan terbatas pengguna ketika UAC diaktifkan.
cwa
Jika Anda menggunakan VSTS, Anda bisa mendapatkan Token Akses Pribadi dari Pengaturan di Portal Web. (Cari ikon pengaturan di sebelah gambar pengguna.) MSDocs
Su Llewellyn