Programowe podnoszenie uprawnień do procesu?

147

Próbuję zainstalować usługę za pomocą InstallUtil.exe, ale została wywołana za pośrednictwem Process.Start. Oto kod:

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

gdzie m_strInstallUtiljest w pełni kwalifikowaną ścieżką i plikiem exe do „InstallUtil.exe” oraz strExePathw pełni kwalifikowaną ścieżką / nazwą do mojej usługi.

Uruchamianie składni wiersza poleceń z wiersza polecenia z podwyższonym poziomem uprawnień działa; uruchamianie z mojej aplikacji (przy użyciu powyższego kodu) nie działa. Zakładam, że mam do czynienia z problemem podniesienia uprawnień procesu, więc jak uruchomić proces w stanie podwyższonym? Czy muszę na to patrzeć ShellExecute?

To wszystko w systemie Windows Vista. Uruchamiam proces w debugerze VS2008 z uprawnieniami administratora.

Próbowałem też ustawić, startInfo.Verb = "runas";ale to nie rozwiązało problemu.

Scott Marlowe
źródło
Po dodaniu startInfo.UseShellExecute = true;oprócz startInfo.Verb = "runas";tego działało dobrze dla mnie.
Matt

Odpowiedzi:

172

Możesz wskazać, że nowy proces powinien być uruchamiany z podwyższonymi uprawnieniami, ustawiając właściwość Verb obiektu startInfo na „runas” w następujący sposób:

startInfo.Verb = "runas";

Spowoduje to, że system Windows będzie zachowywał się tak, jakby proces został uruchomiony z Eksploratora za pomocą polecenia menu „Uruchom jako administrator”.

Oznacza to, że pojawi się monit UAC i będzie musiał zostać potwierdzony przez użytkownika: jeśli jest to niepożądane (na przykład, ponieważ mogłoby się to zdarzyć w środku długiego procesu), musisz uruchomić cały proces hosta z podwyższone uprawnienia przez tworzenie i osadzanie manifestu aplikacji (UAC), aby wymagać poziomu wykonania `` najwyższego dostępnego '': spowoduje to wyświetlenie monitu UAC zaraz po uruchomieniu aplikacji i spowoduje, że wszystkie procesy podrzędne będą działać z podwyższonymi uprawnieniami bez dodatkowych monitów .

Edycja: Widzę, że właśnie zredagowałeś swoje pytanie, stwierdzając, że „runy” nie działają dla Ciebie. To naprawdę dziwne, tak jak powinno (i robi dla mnie w kilku aplikacjach produkcyjnych). Jednak wymaganie, aby proces nadrzędny działał z podwyższonymi prawami poprzez osadzenie manifestu, zdecydowanie powinno działać.

mdb
źródło
9
„Runy” też mi nie pasowały. Może to działa tylko z wyłączoną funkcją UAC?
Dirk Vollmar
18
@LukePuplett Dziękuję im. To świetny sposób na złagodzenie instalacji zestawu root-kit bez faktycznego całkowitego oddzielenia ról użytkowników.
Colton
6
@Sparksis, ale jest też inny punkt widzenia. Ludzie, którzy wiedzą, jak chronić swój system operacyjny, wiedzą, jak to zrobić bez UAC. A fałszywi użytkownicy, którzy nie wiedzą, co jest obroną, klikają „TAK” za każdym razem, gdy widzą okno UAC. Również nic nie może powstrzymać złych hakerów-twórców wirusów przed wykorzystaniem exploitów do ominięcia tego;) Więc zgadzam się z LukePuplett =)
Jet
24
Wygląda na to, że musisz również ustawić, startInfo.ShellExecute=trueaby to zadziałało ... również nie byłem w stanie zmusić tej metody do pracy z plikami wykonywalnymi, które znajdują się w udziale sieciowym (przed uruchomieniem muszę je skopiować do lokalnego katalogu tymczasowego). ..
TCC
7
@Jet Przepraszamy, ale to zły sposób myślenia. Za każdym razem, gdy podczas instalacji pojawi się okno dialogowe UAC, oznacza to awarię systemu. Cenne jest to, gdy widzisz pole UAC bez uruchamiania czegoś wymagającego podniesienia. Nie ma znaczenia, jak profesjonalista - którykolwiek z nas - myśli, że jesteśmy na naszych komputerach, nie możesz w magiczny sposób zablokować zerowego pobierania plików (np. Ostatniego na oficjalnej stronie Nagrody Nobla). Jeśli przeglądałeś tę stronę i otrzymałeś monit UAC, wiedziałbyś, że coś jest nie tak. Gdy UAC jest wyłączone, nigdy nie wiesz, że właśnie dołączyłeś do botnetu. Koszt wcześniejszego ostrzeżenia to konieczność sporadycznego kliknięcia Tak
Podstawowy
46

Ten kod łączy powyższe wszystko razem i ponownie uruchamia bieżącą aplikację wpf z uprawnieniami administratora:

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)

Aktualizacja: preferowany jest manifest aplikacji:

Kliknij prawym przyciskiem myszy projekt w programie Visual Studio, dodaj, nowy plik manifestu aplikacji, zmień plik, aby ustawić wymagany administrator, jak pokazano powyżej.

Problem z oryginalnym sposobem: jeśli umieścisz kod restartu w app.xaml.cs przy uruchomieniu, nadal może on na krótko uruchomić okno główne, mimo że wywołano polecenie Shutdown. Moje główne okno wybuchło, jeśli init app.xaml.cs nie został uruchomiony iw pewnych warunkach wyścigowych to zrobił.

Curtis Yallop
źródło
Poniżej znajdziesz ulepszenia.
JCCyC,
requireAdministrator nie działał w moim przypadku. Więc musiałem to zrobić po swojemu. To rozwiązało mój problem! Dziękuję Ci. Ale musiałem ustawić opcję Single Instance Application na false.
chris
To zadziałało dla mnie. Oryginał przekazałem również string[] argsdo procesu odrodzenia.
DotNetPadawan
7
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN\Administrators")]

To zrobi bez UAC - nie ma potrzeby rozpoczynania nowego procesu. Jeśli uruchomiony użytkownik jest członkiem grupy administratorów, jak w moim przypadku.

hB0
źródło
3
Używając tego kodu, pojawia się błąd dotyczący uprawnień: „Żądanie uprawnienia elementu bezpieczeństwa nie powiodło się” :(
Leonardo
Być może „Jeśli uruchomiony użytkownik jest członkiem administratora” *
hB0
1
ciekawe - to może
dotyczyć
1

Aby podnieść stan, należy użyć funkcji podszywania się.

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

Po zakończeniu nie zapomnij cofnąć podszywanego kontekstu.

Vijesh VP
źródło
28
Nie powiedziałeś, jak zdobyć accessToken. LogonUser zapewni użytkownikowi ograniczony kontekst zabezpieczeń, gdy włączona jest kontrola konta użytkownika.
cwa
Jeśli korzystasz z VSTS, możesz uzyskać osobisty token dostępu w Ustawieniach w portalu internetowym. (Poszukaj ikony ustawień obok zdjęcia użytkownika). MSDocs
Su Llewellyn