연습: ClickOnce 응용 프로그램용 사용자 지정 설치 관리자 만들기
.exe 파일을 기반으로 하는 모든 ClickOnce 응용 프로그램은 사용자 지정 설치 관리자를 통해 자동으로 설치되고 업데이트될 수 있습니다. 사용자 지정 설치 관리자는 설치 중에 보안 및 유지 관리 작업을 위한 사용자 지정 대화 상자를 비롯하여 사용자 지정 사용자 환경을 구현할 수 있습니다. 사용자 지정 설치 관리자는 InPlaceHostingManager 클래스를 사용하여 설치 작업을 수행합니다. 이 연습에서는 ClickOnce 응용 프로그램을 자동으로 설치하는 사용자 지정 설치 관리자를 만드는 방법을 보여 줍니다.
사용자 지정 ClickOnce 응용 프로그램 설치 관리자를 만들려면
ClickOnce 응용 프로그램에서 System.Deployment 및 System.Windows.Forms에 대한 참조를 추가합니다.
응용 프로그램에 새 클래스를 추가하고 임의의 이름을 지정합니다. 이 연습에서는 이름으로 MyInstaller를 사용합니다.
새 클래스의 맨 위에 다음 Imports 또는 using 문을 추가합니다.
Imports System.Deployment.Application Imports System.Windows.Forms
using System.Deployment.Application; using System.Windows.Forms;
클래스에 다음 메서드를 추가합니다.
이러한 메서드는 InPlaceHostingManager 메서드를 호출하여 배포 매니페스트를 다운로드하고, 적절한 사용 권한을 어설션하고, 사용자에게 설치 권한을 요청하고, ClickOnce 캐시에 응용 프로그램을 다운로드하여 설치합니다. 사용자 지정 설치 관리자는 ClickOnce 응용 프로그램이 사전 신뢰되도록 지정하거나 AssertApplicationRequirements 메서드가 호출될 때까지 신뢰 결정을 미룰 수 있습니다. 이 코드는 응용 프로그램을 사전 신뢰합니다.
참고
사전 신뢰를 통해 지정되는 사용 권한은 사용자 지정 설치 관리자 코드의 사용 권한보다 높을 수 없습니다.
Dim WithEvents iphm As InPlaceHostingManager = Nothing Public Sub InstallApplication(ByVal deployManifestUriStr As String) Try Dim deploymentUri As New Uri(deployManifestUriStr) iphm = New InPlaceHostingManager(deploymentUri, False) MessageBox.Show("Created the object.") Catch uriEx As UriFormatException MessageBox.Show("Cannot install the application: " & _ "The deployment manifest URL supplied is not a valid URL." & _ "Error: " & uriEx.Message) Return Catch platformEx As PlatformNotSupportedException MessageBox.Show("Cannot install the application: " & _ "This program requires Windows XP or higher. " & _ "Error: " & platformEx.Message) Return Catch argumentEx As ArgumentException MessageBox.Show("Cannot install the application: " & _ "The deployment manifest URL supplied is not a valid URL." & _ "Error: " & argumentEx.Message) Return End Try iphm.GetManifestAsync() End Sub Private Sub iphm_GetManifestCompleted(ByVal sender As Object, ByVal e As GetManifestCompletedEventArgs) Handles iphm.GetManifestCompleted ' Check for an error. If (e.Error IsNot Nothing) Then ' Cancel download and install. MessageBox.Show("Could not download manifest. Error: " & e.Error.Message) Return End If ' Dim isFullTrust As Boolean = CheckForFullTrust(e.ApplicationManifest) ' Verify this application can be installed. Try ' the true parameter allows InPlaceHostingManager ' to grant the permissions requested in the application manifest. iphm.AssertApplicationRequirements(True) Catch ex As Exception MessageBox.Show("An error occurred while verifying the application. " & _ "Error text: " & ex.Message) Return End Try ' Use the information from GetManifestCompleted() to confirm ' that the user wants to proceed. Dim appInfo As String = "Application Name: " & e.ProductName appInfo &= ControlChars.Lf & "Version: " & e.Version.ToString() appInfo &= ControlChars.Lf & "Support/Help Requests: " If Not (e.SupportUri Is Nothing) Then appInfo &= e.SupportUri.ToString() Else appInfo &= "N/A" End If appInfo &= ControlChars.Lf & ControlChars.Lf & _ "Confirmed that this application can run with its requested permissions." ' If isFullTrust Then ' appInfo &= ControlChars.Lf & ControlChars.Lf & _ ' "This application requires full trust in order to run." ' End If appInfo &= ControlChars.Lf & ControlChars.Lf & "Proceed with installation?" Dim dr As DialogResult = MessageBox.Show(appInfo, _ "Confirm Application Install", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) If dr <> System.Windows.Forms.DialogResult.OK Then Return End If ' Download the deployment manifest. ' Usually, this shouldn't throw an exception unless ' AssertApplicationRequirements() failed, or you did not call that method ' before calling this one. Try iphm.DownloadApplicationAsync() Catch downloadEx As Exception MessageBox.Show("Cannot initiate download of application. Error: " & downloadEx.Message) Return End Try End Sub #If 0 Then Private Function CheckForFullTrust(ByVal appManifest As XmlReader) As Boolean Dim isFullTrust As Boolean = False If (appManifest Is Nothing) Then Throw New ArgumentNullException("appManifest cannot be null.") End If Dim xaUnrestricted As XAttribute xaUnrestricted = XDocument.Load(appManifest) _ .Element("{urn:schemas-microsoft-com:asm.v1}assembly") _ .Element("{urn:schemas-microsoft-com:asm.v2}trustInfo") _ .Element("{urn:schemas-microsoft-com:asm.v2}security") _ .Element("{urn:schemas-microsoft-com:asm.v2}applicationRequestMinimum") _ .Element("{urn:schemas-microsoft-com:asm.v2}PermissionSet") _ .Attribute("Unrestricted") ' Attributes never have a namespace If xaUnrestricted Then If xaUnrestricted.Value = "true" Then Return True End If End If Return False End Function #End If Private Sub iphm_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs) Handles iphm.DownloadProgressChanged ' you can show percentage of task completed using e.ProgressPercentage End Sub Private Sub iphm_DownloadApplicationCompleted(ByVal sender As Object, ByVal e As DownloadApplicationCompletedEventArgs) Handles iphm.DownloadApplicationCompleted ' Check for an error. If (e.Error IsNot Nothing) Then ' Cancel download and install. MessageBox.Show("Could not download and install application. Error: " & e.Error.Message) Return End If ' Inform the user that their application is ready for use. MessageBox.Show("Application installed! You may now run it from the Start menu.") End Sub
InPlaceHostingManager iphm = null; public void InstallApplication(string deployManifestUriStr) { try { Uri deploymentUri = new Uri(deployManifestUriStr); iphm = new InPlaceHostingManager(deploymentUri, false); } catch (UriFormatException uriEx) { MessageBox.Show("Cannot install the application: " + "The deployment manifest URL supplied is not a valid URL. " + "Error: " + uriEx.Message); return; } catch (PlatformNotSupportedException platformEx) { MessageBox.Show("Cannot install the application: " + "This program requires Windows XP or higher. " + "Error: " + platformEx.Message); return; } catch (ArgumentException argumentEx) { MessageBox.Show("Cannot install the application: " + "The deployment manifest URL supplied is not a valid URL. " + "Error: " + argumentEx.Message); return; } iphm.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>(iphm_GetManifestCompleted); iphm.GetManifestAsync(); } void iphm_GetManifestCompleted(object sender, GetManifestCompletedEventArgs e) { // Check for an error. if (e.Error != null) { // Cancel download and install. MessageBox.Show("Could not download manifest. Error: " + e.Error.Message); return; } // bool isFullTrust = CheckForFullTrust(e.ApplicationManifest); // Verify this application can be installed. try { // the true parameter allows InPlaceHostingManager // to grant the permissions requested in the applicaiton manifest. iphm.AssertApplicationRequirements(true) ; } catch (Exception ex) { MessageBox.Show("An error occurred while verifying the application. " + "Error: " + ex.Message); return; } // Use the information from GetManifestCompleted() to confirm // that the user wants to proceed. string appInfo = "Application Name: " + e.ProductName; appInfo += "\nVersion: " + e.Version; appInfo += "\nSupport/Help Requests: " + (e.SupportUri != null ? e.SupportUri.ToString() : "N/A"); appInfo += "\n\nConfirmed that this application can run with its requested permissions."; // if (isFullTrust) // appInfo += "\n\nThis application requires full trust in order to run."; appInfo += "\n\nProceed with installation?"; DialogResult dr = MessageBox.Show(appInfo, "Confirm Application Install", MessageBoxButtons.OKCancel, MessageBoxIcon.Question); if (dr != System.Windows.Forms.DialogResult.OK) { return; } // Download the deployment manifest. iphm.DownloadProgressChanged += new EventHandler<DownloadProgressChangedEventArgs>(iphm_DownloadProgressChanged); iphm.DownloadApplicationCompleted += new EventHandler<DownloadApplicationCompletedEventArgs>(iphm_DownloadApplicationCompleted); try { // Usually this shouldn't throw an exception unless AssertApplicationRequirements() failed, // or you did not call that method before calling this one. iphm.DownloadApplicationAsync(); } catch (Exception downloadEx) { MessageBox.Show("Cannot initiate download of application. Error: " + downloadEx.Message); return; } } /* private bool CheckForFullTrust(XmlReader appManifest) { if (appManifest == null) { throw (new ArgumentNullException("appManifest cannot be null.")); } XAttribute xaUnrestricted = XDocument.Load(appManifest) .Element("{urn:schemas-microsoft-com:asm.v1}assembly") .Element("{urn:schemas-microsoft-com:asm.v2}trustInfo") .Element("{urn:schemas-microsoft-com:asm.v2}security") .Element("{urn:schemas-microsoft-com:asm.v2}applicationRequestMinimum") .Element("{urn:schemas-microsoft-com:asm.v2}PermissionSet") .Attribute("Unrestricted"); // Attributes never have a namespace if (xaUnrestricted != null) if (xaUnrestricted.Value == "true") return true; return false; } */ void iphm_DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e) { // Check for an error. if (e.Error != null) { // Cancel download and install. MessageBox.Show("Could not download and install application. Error: " + e.Error.Message); return; } // Inform the user that their application is ready for use. MessageBox.Show("Application installed! You may now run it from the Start menu."); } void iphm_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { // you can show percentage of task completed using e.ProgressPercentage }
코드에서 설치를 시도하려면 InstallApplication 메서드를 호출합니다. 예를 들어 클래스의 이름을 MyInstaller로 지정한 경우 다음과 같은 방식으로 InstallApplication을 호출할 수 있습니다.
Dim installer As New MyInstaller() installer.InstallApplication("\\myServer\myShare\myApp.application") MessageBox.Show("Installer object created.")
MyInstaller installer = new MyInstaller(); installer.InstallApplication(@"\\myServer\myShare\myApp.application"); MessageBox.Show("Installer object created.");
다음 단계
또한 ClickOnce 응용 프로그램은 업데이트 중에 표시할 사용자 지정 사용자 인터페이스를 비롯하여 사용자 지정 업데이트 논리를 추가할 수도 있습니다. 자세한 내용은 UpdateCheckInfo를 참조하십시오. 또한 ClickOnce 응용 프로그램은 <customUX> 요소를 사용하여 시작 메뉴 항목, 바로 가기 및 프로그램 추가/제거 항목을 표시하지 않을 수도 있습니다. 자세한 내용은 <entryPoint> 요소(ClickOnce 응용 프로그램) 및 ShortcutAppId를 참조하십시오.