Microsoft MVP성태의 닷넷 이야기
.NET Framework: 191. ClickOnce - 관리자 권한 상승하는 방법 [링크 복사], [링크+제목 복사]
조회: 58282
글쓴 사람
홈페이지
첨부 파일
ClickOnce - 관리자 권한 상승하는 방법

개인적으로, ClickOnce 에서 아쉬운 것이 있었다면 "관리자 권한 상승(Run as administrator)"이 불가능하다는 것입니다. 이전에도 제 웹 사이트 게시판에 아래와 같은 질문이 있었는데요.

[질문/답변] 클릭원스를 비스타에서 실행시 
; https://www.sysnet.pe.kr/3/0/822

ClickOnce에 배포되는 .exe.manifest의 requestedExecutionLevel 값을 강제로 requireAdministrator 값을 주어도 "The Execution level requested by this application is not supported" 라는 오류 메시지만 클라이언트에 출력되고 동작되지 않습니다.

실제로 저 역시, 위에 제가 답변했던 그대로, 관리자 권한이 필요한 부분을 별도로 NT 서비스로 제작하고 클릭원스의 Bootstrapper에 넣어서 배포를 한 적이 있었습니다.

그런데, 갑자기... 오늘은 ^^; 늘 보아왔던 "작업관리자"의 "Show processes from all users" 버튼이 눈에 들어왔습니다.

clickonce_run_as_adminrights_0.png

'그렇지! ClickOnce로 배포된 응용 프로그램도 자신을 실행할 때 권한상승시켜서 재실행하면 되지 않을까!' 라는 간단한 해답이었습니다. 1년이나 지나서 이런 생각이 드는군요. ^^;




구현 방법은 모두 공개되어 있습니다. 자신의 프로세스를 권한 상승시켜서 재실행하는 방법은 다음의 글에서 자세하게 소개해주고 있습니다.

Add a UAC shield to a button when elevation is required for admin tasks
; http://www.codeproject.com/KB/vista-security/UAC_Shield_for_Elevation.aspx

위의 방법을 클릭원스 상황에 맞게 적용시키면 되는데요. Form 이 실행되기 전에 "권한 상승된 프로세스"인지 스스로 점검하고, 그렇지 않은 경우라면 권한 상승시켜서 실행시키는 코드로 적절하게 바꾸는 것인데, 아래에 간단하게 실어보았습니다.

===== Program.cs =====
static class Program
{
    [STAThread]
    static void Main()
    {
        if (IsAdministrator() == false)
        {
            try
            {
                ProcessStartInfo procInfo = new ProcessStartInfo();
                procInfo.UseShellExecute = true;
                procInfo.FileName = Application.ExecutablePath;
                procInfo.WorkingDirectory = Environment.CurrentDirectory;
                procInfo.Verb = "runas";
                Process.Start(procInfo);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

            return;
        }

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public static bool IsAdministrator()
    {
        WindowsIdentity identity = WindowsIdentity.GetCurrent();

        if (null != identity)
        {
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        return false;
    }
}

===== Form1.cs =====
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        if (Program.IsAdministrator() == true)
        {
            this.Text += " (Administrator)";
        }
    }
}

예제 삼아서, 제 홈페이지에 위의 코드를 빌드시켜서 클릭원스로 배포한 경로는 다음과 같습니다.

WindowsFormsApplication1
; https://www.sysnet.pe.kr/temp/app/runasadmin/publish.htm

"Install" 버튼을 눌러서 실행시키면, 배포가 완료된 후 아래와 같이 권한 상승 창이 뜨고,

clickonce_run_as_adminrights_1.png

이후, 원했던 데로 "관리자 권한"으로 실행된 클릭원스 응용 프로그램을 확인할 수 있습니다. ^^ (다른 코드 없으니, 두려워하지 마시고 ^^ 그냥 실행해 보셔도 됩니다.)

clickonce_run_as_adminrights_2.png

물론, 여전히 권한 상승창은 사용자에게 귀찮은 작업이므로 "Bootstrapper + NT 서비스 배포"는 유용할 수 있습니다. 어쨌든, 이로써 클릭원스 배포의 한가지 장벽이 허물어지는군요. ^^



[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]





[최초 등록일: ]
[최종 수정일: 11/20/2010 ]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer@outlook.com

비밀번호

댓글 쓴 사람
 



2010-11-26 09시20분
[lancers] 그런데, 프로그램을 실행할 때마다 매번 사용자에게 권한상승 확인을 누르라고 하는 것도 만만치 않은 일이 된다는 거죠. -_-;
참고로 그 서비스를 만들었던 곳에서는.. 이제 더 이상 그 서비스를 사용하지 않는다는..
알다시피 그 서비스를 사용했던 목적이 있었는데, 그걸 꽤 엽기적인 방법(?)으로 다른 방식으로 처리했다는...
[손님]
2010-11-26 10시38분
엽기적인 방법이라? ^^;;;
정성태
2010-11-26 11시42분
[정중희] CAS 등록 및 신뢰된 사이트 등록을 위해 만들었던 설치 모듈에 위와 같이 권한 상승 기능을 넣고 배포 테스트를 했는데
아래와 같이 권한상승이 필요하다는 에러가 나네요? 혹시 어떤 이유에서 일까요?
혹시나 해서 배포바이너리 Setup.exe를 독립적으로 실행시키면 상승된 권한으로 실행이 되는데도 동일한 에러가 납니다.

ERROR DETAILS
    Following errors were detected during this operation.
    * [2010-11-26 오전 11:30:22] System.Runtime.InteropServices.COMException
        - 요청한 작업을 수행하려면 권한 상승이 필요합니다. (Exception from HRESULT: 0x800702E4)
        - Source: System.Deployment
        - Stack trace:
            at System.Deployment.Application.NativeMethods.CorLaunchApplication(UInt32 hostType, String applicationFullName, Int32 manifestPathsCount, String[] manifestPaths, Int32 activationDataCount, String[] activationData, PROCESS_INFORMATION processInformation)
            at System.Deployment.Application.ComponentStore.ActivateApplication(DefinitionAppId appId, String activationParameter, Boolean useActivationParameter)
            at System.Deployment.Application.SubscriptionStore.ActivateApplication(DefinitionAppId appId, String activationParameter, Boolean useActivationParameter)
            at System.Deployment.Application.ApplicationActivator.Activate(DefinitionAppId appId, AssemblyManifest appManifest, String activationParameter, Boolean useActivationParameter)
            at System.Deployment.Application.ApplicationActivator.PerformDeploymentActivation(Uri activationUri, Boolean isShortcut, String textualSubId, String deploymentProviderUrlFromExtension, BrowserSettings browserSettings, String& errorPageUrl)
            at System.Deployment.Application.ApplicationActivator.ActivateDeploymentWorker(Object state)

[손님]
2010-11-26 11시46분
[정중희] 아 한가지 이상한점을 발견하였습니다.

웹을 통하여 설치를 할때는 권한상승 요구 문제가 발생하는데
브라우저를 모두 닫고 Setup.exe 만가지고 설치를 하게 되면
잘 설치가 되네요. 이건 무슨조화인지?
[손님]
2010-11-26 12시50분
정중희님... 그러니까 문제를 정리해 보면.
CAS 등록을 위한 코드 실행을 iexplorer.exe가 없이 setup.exe 만으로 실행하면 정상적으로 실행되는데, 클릭원스를 이용해서 실행하면 "권한상승"창이 떠서 확인을 했는데도 불구하고 0x800702E4 오류가 발생한다는 것인가요?

가볍게 재현 가능한 소스 코드를 올려주시면 한번 시도해보도록 하겠습니다.
정성태
2010-11-26 04시58분
[정중희] 코드를 약간 첨부하였습니다.
WinForm형식이구요.
실행시 신뢰된 사이트에 등록하고, CAS 권한 설정을 등록하는 기능을 합니다.
먼저 권한 상승을 하고 이후에 작업을 진행하도록 하였는데, 권한상승 시 에러가 나는듯 합니다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Security;
using System.Security.Policy;
using System.Runtime.InteropServices;

namespace SetupSecurity
{
    public partial class SetupSecurity : Form
    {
        public static Guid CLSID_InternetSecurityManager = new Guid("7b8a2d94-0ac9-11d1-896c-00c04fb6bfc4");
        public static Guid IID_IInternetSecurityManager = new Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b");

        private const uint SZM_CREATE = 0;
        private const uint SZM_DELETE = 1;

        public const uint ZoneLocalMachine = 0;
        public const uint ZoneIntranet = 1;
        public const uint ZoneTrusted = 2;
        public const uint ZoneInternet = 3;
        public const uint ZoneUntrusted = 4;

        public SetupSecurity()
        {
            InitializeComponent();

            if (Program.IsAdministrator() == true)
            {
                this.Text += " (Administrator)";
            }
        }

        private void SetupSecurity_Load(object sender, EventArgs e)
        {
            btnOk.Visible = false;
                        
            AddSiteToZone(ZoneTrusted, "HTTP://XXX.XXX.XX.XX");
            AddUrlCodeGroup("XXXXXXXX", "http://XXX.XXX.XX.XX/*", "XXX Assembly의 권한집합입니다.");

            btnOk.Visible = true;
        }
[손님]
2010-11-26 10시27분
정중희님... 혹시나 싶어서 확인 질문드리는 건데요? 위에 올려주신 코드는, static void Main() 처리의 권한 상승을 위한 재실행 부분을 일부러 빼신 건가요? 아니면, 실제 테스트 코드에서 그 부분을 빼고 돌려보신 건가요?
정성태
2010-11-27 04시54분
[정중희] 물론 static void main 부분은 권한상승을 위한 재실행 부분을 설명해 주신 그대로 넣은 상태입니다.
그럼에도 불구하고 권한상승을 요구하는 이유가 뭘까 궁금합니다.
[손님]
2010-11-27 08시34분
에... 또 그러니까... 이상해서 다시 질문드리게 되는데요."그럼에도 불구하고 권한상승을 요구하는 이유" 라고 표현하셨는데, "재실행 시 권한상승" 창이 한번 뜨게 되고, 확인을 했는데 다시 실행되는 과정에서 SetupSecurity_Load 메서드에서 AddSiteToZone 메서드를 실행하면서 "요청한 작업을 수행하려면 권한 상승이 필요합니다. (Exception from HRESULT: 0x800702E4) - Source: System.Deployment"라는 오류가 발생한다는 것이죠?
정성태
2010-11-27 08시50분
http://www.sysnet.pe.kr/temp/app/runasadmin/publish.htm
위의 예제 응용 프로그램에 "신뢰할 수 있는 사이트 등록" 기능을 추가했습니다.

신뢰할 수 있는 사이트 자동등록 하기
; http://wonx.egloos.com/1661425

위에서 소개한 AddSiteToZone 메서드만 추가기능 구현해보았습니다.
정성태
2010-11-29 05시06분
[정중희] 죄송하지만 제가 쓰고 있는 IDE가 VS2005여서 샘플파일을 그대로 수행해보지는 않았습니다.
다만 내부 코드들을 보았을때 제가 사용하는 부분과 동일하게 작성되어 있음을 확인하였습니다.
위의 신뢰된 사이트 등록 코드도 마찬가지이구요. 다만 배포사이트에 들어가서 배포를 위해
'실행' 버튼을 누르고 'Setup.exe를 실행 또는 저장하겠습니까?' 라는 질문에서 '실행' 버튼을 누르면
권한상승창이 뜨게 되고, 이때 '예'를 눌러 진행하면 설치 중 'Application cannot be started, Contact the application vendor.' 이라는 에러가 뜨게 됩니다. 이때 Details 버튼을 눌러 에러 메시지를 확인하면 아래와같은 에러가 나옵니다.

PLATFORM VERSION INFO
Windows : 6.1.7600.0 (Win32NT)
Common Language Runtime : 4.0.30319.1
System.Deployment.dll : 4.0.30319.1 (RTMRel.030319-0100)
clr.dll : 4.0.30319.1 (RTMRel.030319-0100)
dfdll.dll : 4.0.30319.1 (RTMRel.030319-0100)
dfshim.dll : 4.0.31106.0 (Main.031106-0000)

SOURCES
Deployment url : http://.../SetupSecurity/SetupSecurity.application
Server : Microsoft-IIS/5.1
X-Powered-By : ASP.NET

IDENTITIES
Deployment Identity : SetupSecurity.application, Version=1.0.0.13, Culture=ko, PublicKeyToken=c793062a7786dbe6, processorArchitecture=x86

APPLICATION SUMMARY
* Online only application.

ERROR SUMMARY
Below is a summary of the errors, details of these errors are listed later in the log.
* Activation of http://.../SetupSecurity/SetupSecurity.application resulted in exception. Following failure messages were detected:
+ 요청한 작업을 수행하려면 권한 상승이 필요합니다. (Exception from HRESULT: 0x800702E4)

COMPONENT STORE TRANSACTION FAILURE SUMMARY
No transaction error was detected.

WARNINGS
There were no warnings during this operation.

OPERATION PROGRESS STATUS
* [2010-11-29 오후 4:17:55] : Activation of http://.../SetupSecurity/SetupSecurity.application has started.
* [2010-11-29 오후 4:17:55] : Processing of deployment manifest has successfully completed.

ERROR DETAILS
Following errors were detected during this operation.
* [2010-11-29 오후 4:17:55] System.Runtime.InteropServices.COMException
- 요청한 작업을 수행하려면 권한 상승이 필요합니다. (Exception from HRESULT: 0x800702E4)
- Source: System.Deployment
- Stack trace:
at System.Deployment.Application.NativeMethods.CorLaunchApplication(UInt32 hostType, String applicationFullName, Int32 manifestPathsCount, String[] manifestPaths, Int32 activationDataCount, String[] activationData, PROCESS_INFORMATION processInformation)
at System.Deployment.Application.ComponentStore.ActivateApplication(DefinitionAppId appId, String activationParameter, Boolean useActivationParameter)
at System.Deployment.Application.SubscriptionStore.ActivateApplication(DefinitionAppId appId, String activationParameter, Boolean useActivationParameter)
at System.Deployment.Application.ApplicationActivator.Activate(DefinitionAppId appId, AssemblyManifest appManifest, String activationParameter, Boolean useActivationParameter)
at System.Deployment.Application.ApplicationActivator.PerformDeploymentActivation(Uri activationUri, Boolean isShortcut, String textualSubId, String deploymentProviderUrlFromExtension, BrowserSettings browserSettings, String& errorPageUrl)
at System.Deployment.Application.ApplicationActivator.ActivateDeploymentWorker(Object state)

COMPONENT STORE TRANSACTION DETAILS
* Transaction at [2010-11-29 오후 4:17:55]
+ System.Deployment.Internal.Isolation.StoreOperationSetDeploymentMetadata
- Status: Set
- HRESULT: 0x0
+ System.Deployment.Internal.Isolation.StoreTransactionOperationType (27)
- HRESULT: 0x0

꼼꼼한 답변에 감사드립니다.
[손님]
2010-11-29 11시16분
아래의 별도 답글로 설명을 했으니, 참고하세요. ^^

[답변] 클릭원스 - 요청한 작업을 수행하려면 권한 상승이 필요합니다. (Exception from HRESULT: 0x800702E4)
; http://www.sysnet.pe.kr/2/0/954
정성태
2010-12-03 02시36분
[저는 누구일까요?] 헙~! 실행했더니 디스크가 포멧됐어요...

^^' 농담입니다.

잘 봤습니다.
[손님]
2010-12-03 02시48분
"포멧" 아니죠. "포맷" 맞습니다~~~. ^^
정성태
2013-11-18 11시56분
How can I launch an unelevated process from my elevated process and vice versa?
; http://blogs.msdn.com/b/oldnewthing/archive/2013/11/18/10468726.aspx
정성태
2016-03-06 12시38분
[손님] 좋은 글 감사 합니다.
UCOMIEnumString 더 이상 쓰이지 않고 아래로 변경 되었네요.

System.Runtime.InteropServices.ComTypes.IEnumString
[손님]

[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
12207정성태4/2/202034스크립트: 19. Windows PowerShell의 NonInteractive 모드
12206정성태4/2/202022오류 유형: 613. 파일 잠금이 바로 안 풀린다면? - The process cannot access the file '...' because it is being used by another process.
12205정성태4/2/202023스크립트: 18. Powershell에서는 cmd.exe의 명령어를 지원하진 않습니다.
12204정성태4/1/202018스크립트: 17. Powershell 명령어에 ';' (semi-colon) 문자가 포함된 경우
12203정성태3/18/202074오류 유형: 612. warning: 'C:\ProgramData/Git/config' has a dubious owner: '...'.
12202정성태3/18/202094개발 환경 구성: 486. .NET Framework 프로젝트를 위한 GitLab CI/CD Runner 구성
12201정성태3/18/202035오류 유형: 611. git-credential-manager.exe: Using credentials for username "Personal Access Token".
12200정성태3/18/2020135VS.NET IDE: 145. NuGet + Github 라이브러리 디버깅 관련 옵션 3가지 - "Enable Just My Code" / "Enable Source Link support" / "Suppress JIT optimization on module load (Managed only)"
12199정성태3/17/202039오류 유형: 610. C# - CodeDomProvider 사용 시 Unhandled Exception: System.IO.DirectoryNotFoundException: Could not find a part of the path '...\f2_6uod0.tmp'.
12198정성태3/17/202036오류 유형: 609. SQL 서버 접속 시 "Cannot open user default database. Login failed."
12197정성태3/17/2020126VS.NET IDE: 144. .NET Core 콘솔 응용 프로그램을 배포(publish) 시 docker image 자동 생성 - 두 번째 이야기
12196정성태3/17/202067오류 유형: 608. The ServicedComponent being invoked is not correctly configured (Use regsvcs to re-register).
12195정성태3/17/2020173.NET Framework: 902. C# - 프로세스의 모든 핸들을 열람 - 세 번째 이야기
12194정성태3/16/202045오류 유형: 607. PostgreSQL - Npgsql.NpgsqlException: sorry, too many clients already
12193정성태3/16/202082개발 환경 구성: 485. docker - SAP Adaptive Server Enterprise 컨테이너 실행
12192정성태3/14/202090개발 환경 구성: 484. docker - Sybase Anywhere 16 컨테이너 실행
12191정성태3/14/2020131개발 환경 구성: 483. docker - OracleXE 컨테이너 실행
12190정성태3/14/202046오류 유형: 606. Docker Desktop 업그레이드 시 "The process cannot access the file 'C:\Program Files\Docker\Docker\resources\dockerd.exe' because it is being used by another process."
12189정성태3/13/202088개발 환경 구성: 482. Facebook OAuth 처리 시 상태 정보 전달 방법과 "유효한 OAuth 리디렉션 URI" 설정 규칙
12188정성태3/14/202052Windows: 167. 부팅 시점에 실행되는 chkdsk 결과를 확인하는 방법
12187정성태3/12/202040오류 유형: 605. NtpClient was unable to set a manual peer to use as a time source because of duplicate error on '...'.
12186정성태3/12/202055오류 유형: 604. The SysVol Permissions for one or more GPOs on this domain controller and not in sync with the permissions for the GPOs on the Baseline domain controller.
12185정성태3/11/202053오류 유형: 603. The browser service was unable to retrieve a list of servers from the browser master...
12184정성태3/11/202059오류 유형: 602. Automatic certificate enrollment for local system failed (0x800706ba) The RPC server is unavailable.
12183정성태3/12/202059오류 유형: 601. Warning: DsGetDcName returned information for \\[...], when we were trying to reach [...].
[1]  2  3  4  5  6  7  8  9  10  11  12  13  14  15  ...