Süreç ayrıcalığını programlı olarak yükseltmek mi?


149

InstallUtil.exe kullanarak bir hizmet yüklemeye çalışıyorum, ancak çağrıldı Process.Start. İşte kod:

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

m_strInstallUtil"InstallUtil.exe" için tam olarak nitelenmiş yol ve exe nerede ve hizmetimin strExePathtam olarak nitelenmiş yolu / adıdır.

Komut satırı sözdizimini yükseltilmiş bir komut isteminden çalıştırmak çalışır; uygulamamdan çalıştırmak (yukarıdaki kodu kullanarak) değil. Bazı işlem yükseltme sorunlarıyla uğraştığımı varsayıyorum, bu yüzden işlemimi yükseltilmiş bir durumda nasıl çalıştırırım? Bunun için bakmam gerekiyor ShellExecutemu?

Bunların hepsi Windows Vista'da. İşlemi, yönetici ayrıcalığına yükseltilmiş VS2008 hata ayıklayıcısında çalıştırıyorum.

Ayarı da denedim startInfo.Verb = "runas";ama sorunu çözmedi.


1
Buna startInfo.UseShellExecute = true;ek olarak ekledikten sonra benim için startInfo.Verb = "runas";iyi çalıştı.
Matt

Yanıtlar:


174

StartInfo nesnenizin Verb özelliğini aşağıdaki gibi 'runas' olarak ayarlayarak yeni işlemin yükseltilmiş izinlerle başlatılması gerektiğini belirtebilirsiniz:

startInfo.Verb = "runas";

Bu, Windows'un işlemin Explorer'dan "Yönetici Olarak Çalıştır" menü komutuyla başlatılmış gibi davranmasına neden olur.

Bu, UAC isteminin ortaya çıkacağı ve kullanıcı tarafından onaylanması gerektiği anlamına gelir: bu istenmeyen bir durumsa (örneğin, uzun bir sürecin ortasında gerçekleşeceği için), tüm ana bilgisayar işleminizi çalıştırmanız gerekir. 'En yüksek Kullanılabilir ' yürütme düzeyini zorunlu kılmak için bir Uygulama Bildirimi (UAC) Oluşturma ve Yerleştirme yoluyla yükseltilmiş izinler : bu, UAC isteminin uygulamanız başlatılır başlatılmaz görünmesine neden olur ve tüm alt işlemlerin ek bir uyarı olmadan yükseltilmiş izinlerle çalışmasına neden olur .

Düzenleme: Görüyorum ki, "runas" ın işinize yaramadığını belirtmek için sorunuzu düzenlediniz. Bu, olması gerektiği gibi gerçekten garip (ve benim için birkaç prodüksiyon uygulamasında yapıyor). Manifest'i yerleştirerek üst sürecin yüksek haklarla çalışmasını zorunlu kılmak kesinlikle işe yaramalıdır.


9
"runas" da benim için işe yaramadı. Yalnızca UAC kapalıyken çalışıyor olabilir mi?
Dirk Vollmar

18
@LukePuplett onlara teşekkür ederim. Kullanıcı rollerini tamamen ayırmadan kök kiti kurulumunu azaltmanın harika bir yoludur.
Colton

6
@Sparksis, ancak başka bir bakış açısı daha var. İşletim sistemlerini nasıl savunacaklarını bilenler, bunu UAC olmadan nasıl yapacaklarını bilirler. Ve savunmanın ne olduğunu bilmeyen sahte kullanıcılar, UAC penceresini her gördüklerinde 'EVET'i tıklıyorlar. Ayrıca hiçbir şey kötü-bilgisayar korsanlarının-virüs-yazarlarının bunu atlamak için istismarları kullanmasını engelleyemez;) Bu yüzden LukePuplett'e katılıyorum =)
Jet

25
Görünüşe göre startInfo.ShellExecute=truebunun çalışması için de ayarlamanız gerekiyor ... Ayrıca bu yöntemi bir ağ paylaşımındaki yürütülebilir dosyalarla çalışacak şekilde elde edemedim (çalıştırmadan önce yerel geçici dizine kopyalamam gerekiyor). ..
TCC

7
@Jet Üzgünüm ama bu yanlış zihniyet. Yükleme sırasında bir UAC iletişim kutusu her gösterildiğinde, bu sistemin başarısız olmasıdır. Değerli olduğu yer, yükseklik gerektiren bir şey çalıştırmadan bir UAC kutusu gördüğünüzde. Siz - herhangi birimiz - bilgisayarlarımızda olduğumuzu düşünmeniz ne kadar profesyonel olursa olsun, sihirli bir şekilde sıfır gün / arabayla gelen indirmeleri engelleyemezsiniz (örneğin, resmi Nobel Ödülü sitesinde yeni bir tane). Bu siteye göz attıysanız ve bir UAC istemi aldıysanız, bir sorun olduğunu anlarsınız. UAC kapalıyken, bir botnet'e katıldığınızı asla bilemezsiniz. Ön uyarının maliyeti ara sıra Evet'i tıklamak zorunda
Temel

46

Bu kod, yukarıdakileri bir araya getirir ve mevcut wpf uygulamasını yönetici ayrıcalıklarıyla yeniden başlatır:

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)

Güncelleme: Uygulama manifest yolu tercih edilir:

Visual Studio'da projeye sağ tıklayın, yeni uygulama manifest dosyası ekleyin, dosyayı değiştirin, böylece yukarıda gösterildiği gibi Yönetici ayarına sahip olun.

Orijinal yöntemle ilgili bir sorun: Yeniden başlatma kodunu app.xaml.cs OnStartup'a koyarsanız, Kapatma çağrılmasına rağmen ana pencereyi kısa bir süre için başlatabilir. App.xaml.cs init çalıştırılmazsa ana pencerem patladı ve belirli yarış koşullarında bunu yapardı.


İyileştirmeler için aşağıya bakın.
JCCyC

RequiredAdministrator benim durumumda çalışmadı. Bu yüzden senin istediğin gibi yapmak zorunda kaldım. Bu benim sorunumu çözdü! teşekkür ederim. Ancak Tek Örnek Uygulamasını yanlış olarak ayarlamak zorunda kaldım.
chris

Bu benim için çalıştı. Orijinali string[] argsyeniden doğmuş sürece de geçirdim.
DotNetPadawan


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

Bu, UAC olmadan yapacak - yeni bir işlem başlatmaya gerek yok. Çalışan kullanıcı benim durumumda olduğu gibi Yönetici grubunun üyesiyse.


3
Bu kodu kullanarak bir izin hatası alıyorum: "Güvenlik varlığı izni isteği başarısız oldu." :(
Leonardo

Belki "Çalışan kullanıcı Yönetici
üyesiyse

1
ilginç - bu herhangi bir yöntemle devam edebilir, sadece bir eylem yöntemi (Ben bile bir ASPX sayfasında tanımlanan yönteme üzerinde denedim)
Simon_Weaver

1

Eyaleti yükseltmek için Kimliğe Bürünmeyi kullanmalısınız.

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

İşiniz bittiğinde kimliğe bürünülen bağlamı geri almayı unutmayın.


28
AccessToken'ı nasıl alacağınızı söylemediniz. LogonUser, UAC etkinleştirildiğinde bir kullanıcının kısıtlı güvenlik bağlamını sağlayacaktır.
cwa

VSTS kullanıyorsanız, Web Portalındaki Ayarlar'dan bir Kişisel Erişim Jetonu alabilirsiniz. (Kullanıcı resminin yanındaki ayarlar simgesine bakın.) MSDocs
Su Llewellyn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.