필요한 경우에만 권한을 높이는 방법은 무엇입니까?


85

이 질문은 Windows Vista에 적용됩니다!

일반적으로 관리자 권한없이 작동하는 응용 프로그램이 있습니다. 관리 권한이 필요한 활동이 하나 있지만 대부분의 경우 사용자가 해당 기능을 사용하지 않을 것이라는 것을 알고있을 때 더 높은 권한으로 응용 프로그램 자체를 시작하고 싶지 않습니다.

특정 이벤트 (예 : 버튼 누르기)에 대한 응용 프로그램의 권한을 높일 수있는 특정 방법을 생각하고 있습니다. 예:

사용자가이 버튼을 클릭하면 UAC 대화 상자 또는 동의 메시지가 표시됩니다. 어떻게 할 수 있습니까?

답변:


58

현재 실행중인 프로세스를 향상시킬 수 있다고 생각하지 않습니다. 내가 이해하는 바와 같이 시작시 프로세스에 관리자 권한이 부여되는 것은 Windows Vista에 내장되어 있습니다. UAC를 활용하는 다양한 프로그램을 살펴보면 관리 작업을 수행해야 할 때마다 실제로 별도의 프로세스를 실행하는 것을 볼 수 있습니다 (작업 관리자는 하나, Paint.NET은 다른 하나, 후자는 실제로 .NET 응용 프로그램입니다). ).

이 문제에 대한 일반적인 해결책은 상승 된 프로세스를 시작할 때 명령 줄 인수를 지정하는 것입니다 (abatishchev의 제안은이 작업을 수행하는 한 가지 방법입니다). 이렇게하면 시작된 프로세스가 특정 대화 상자 만 표시 한 다음이 작업이 완료된 후 종료됩니다. 완료되었습니다. 따라서 새로운 프로세스가 시작되었다가 종료되었다는 사실을 사용자가 거의 알아 차릴 수 없으며, 동일한 앱 내에서 새 대화 상자가 열린 것처럼 표시됩니다 (특히 해커가 메인 창을 만들려면 상위 프로세스의 하위 프로세스). 상승 된 액세스를위한 UI가 필요하지 않은 경우 더욱 좋습니다.

Vista에서 UAC에 대한 전체 토론을 보려면 주제에 대한 기사통해이 문서 를 참조하는 것이 좋습니다 (코드 예제는 C ++로되어 있지만 C #에서 대부분의 작업을 수행하려면 WinAPI 및 P / Invoke를 사용해야 할 것 같습니다. 어쨌든). UAC를 준수하는 프로그램을 설계하는 것은 결코 쉬운 일이 아니지만 이제 최소한 올바른 접근 방식을 봤기를 바랍니다.


4
Windows 7에 변경 사항이 있습니까? 아니면 "아니요, 새 프로세스를 사용하십시오"라는 대답이 유지됩니까? 감사합니다 ...
Radim Vansa 2011-06-20

2
Windows 7에 변화가 없습니다. 죄송합니다. (내가 아는 한, 저는 Win7의 일반 사용자 / 개발자입니다.)
Noldorin

2
이것이 바로 작업 관리자가하는 방식입니다. 모든 사용자에 대한 작업을 표시하기 위해 버튼을 클릭하면 현재 작업 관리자가 존재하고 관리자 권한으로 다른 작업 관리자를 호출합니다.
Natalie Adams

3
@NathanAdams 기술적으로 새 작업 관리자를 먼저 엽니 다. 그렇지 않으면 오프닝은 무엇입니까? :-)
wizzwizz4 2016-04-20

16

거기 에 말했듯 :

Process.StartInfo.UseShellExecute = true;
Process.StartInfo.Verb = "runas";

레지스트리로 필요한 모든 작업을 수행하기 위해 관리자로 프로세스를 실행하지만 일반 권한으로 앱으로 돌아갑니다.


여기에는 새로운 프로세스가 포함됩니다. 권리? 나는 현재 프로세스 자체의 권한 상승을 찾고있었습니다.
Hemant

Process.GetCurrentProcess () 사용 시도
abatishchev

27
현재 실행중인 프로세스를 높일 수 없습니다.
Jacob Proffitt

1
이것은 사실이 아닙니다. 프로세스의 소유자를 변경하고 관리 권한을 부여하는 사용자에 대한 DACL 및 ACL 값을 설정할 수 있습니다 ....
Nightforce2 2011 년

4
@ nightforce2 : 이미 관리 권한이있는 경우에만 작동합니다 (예 : 이미 승격 된 경우). 그렇지 않으면 AdjustTokenPrivileges 등이 단순히 실패 할 것입니다.
Ben Schwehn

13

다음 MSDN KB 문서 981778은 응용 프로그램을 '자체 상승'하는 방법을 설명합니다.

http://support.microsoft.com/kb/981778

Visual C ++, Visual C #, Visual Basic.NET의 다운로드 가능한 샘플이 포함되어 있습니다.

이 접근 방식은 별도의 프로세스를 시작해야하는 필요성을 해결하지만 실제로는 다시 시작되어 상승 ​​된 사용자로 실행되는 원래 애플리케이션입니다. 그럼에도 불구하고 별도의 실행 파일에서 코드를 복제하는 것이 실용적이지 않은 일부 상황에서는 여전히 매우 유용 할 수 있습니다.

고도를 제거하려면 응용 프로그램을 종료해야합니다.


1
버튼을 사용하기에는 편리하지만 메뉴 항목에 대해 동일한 기능을 원할 때 정말 복잡한 엉망이됩니다.
Nyerguds

3
@Todd 당신은 여기에 코드를 찾을 수 있습니다 https://code.msdn.microsoft.com/windowsapps/CSUACSelfElevation-644673d3
Matthiee

답변의 링크가 작동하지 않고 댓글의 링크가 2608 항목의 긴 목록을 가리 킵니다.
DonBoitnott



2

아마도 누군가가 다음과 같은 간단한 예에 도움이 될 것입니다.

using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Security.Principal;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    internal static class Program
    {
        private class Form1 : Form
        {
            internal Form1()
            {
                var button = new Button{ Dock = DockStyle.Fill };
                button.Click += (sender, args) => RunAsAdmin();
                Controls.Add(button);

                ElevatedAction();
            }
        }

        [STAThread]
        internal static void Main(string[] arguments)
        {
            if (arguments?.Contains("/run_elevated_action") == true)
            {
                ElevatedAction();
                return;
            }

            Application.Run(new Form1());
        }

        private static void RunAsAdmin()
        {
            var path = Assembly.GetExecutingAssembly().Location;
            using (var process = Process.Start(new ProcessStartInfo(path, "/run_elevated_action")
            {
                Verb = "runas"
            }))
            {
                process?.WaitForExit();
            }
        }

        private static void ElevatedAction()
        {
            MessageBox.Show($@"IsElevated: {IsElevated()}");
        }

        private static bool IsElevated()
        {
            using (var identity = WindowsIdentity.GetCurrent())
            {
                var principal = new WindowsPrincipal(identity);

                return principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
        }

    }
}

1

나는 이것이 오래된 게시물이라는 것을 알고 있지만 이것은 MarcP의 제안을 접하는 다른 사람에 대한 응답입니다. 그가 참조한 msdn 게시물은 실제로 모든 코드 예제에서 응용 프로그램을 다시 시작합니다. 코드 샘플 runas은 다른 제안에서 이미 제안 된 동사를 사용합니다 .

확인하기 위해 코드를 다운로드했지만 이것은 원래 msdn 기사에서 가져온 것입니다.

4. 예를 클릭하여 권한 상승을 승인합니다. 그런 다음 원래 응용 프로그램이 다시 시작되어 관리자 권한으로 실행됩니다.
5. 응용 프로그램을 닫습니다.


1
문제의 MSDN 링크를 추가 할 수 있습니까? MarcP라는 사용자를 찾을 수 없습니다.
Alf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.