다음을 통해 공유


연습: 디자이너를 사용하여 ClickOnce 배포 API에서 요청 시 어셈블리 다운로드

기본적으로 ClickOnce 응용 프로그램에 포함된 모든 어셈블리는 응용 프로그램을 처음 실행할 때 다운로드됩니다. 그러나 응용 프로그램의 일부 어셈블리는 소수의 사용자만 사용하는 경우가 있을 수 있습니다. 이 경우 해당 형식 중 하나를 만들 때만 어셈블리를 다운로드하도록 설정할 수도 있습니다. 다음 연습에서는 응용 프로그램의 특정 어셈블리를 "선택적"인 것으로 표시하는 방법과 공용 언어 런타임에서 요청할 때 System.Deployment.Application 네임스페이스의 클래스를 사용하여 이러한 어셈블리를 다운로드하는 방법을 보여 줍니다.

참고

이 절차를 사용하려면 응용 프로그램을 완전 신뢰 수준에서 실행해야 합니다.

참고

표시되는 대화 상자와 메뉴 명령은 활성 설정이나 버전에 따라 도움말에서 설명하는 것과 다를 수 있습니다. 설정을 변경하려면 도구 메뉴에서 설정 가져오기 및 내보내기를 클릭합니다. 자세한 내용은 설정에 대한 작업을 참조하십시오.

프로젝트 만들기

Visual Studio로 요청 시 어셈블리를 사용하는 프로젝트를 만들려면

  1. Visual Studio에서 새 Windows Forms 프로젝트를 만듭니다. 파일 메뉴에서 추가를 가리킨 다음 새 프로젝트를 클릭합니다. 대화 상자에서 클래스 라이브러리 프로젝트를 선택하고 프로젝트 이름을 ClickOnceLibrary로 지정합니다.

    참고

    Visual Basic에서는 프로젝트 속성을 수정하여 이 프로젝트의 루트 네임스페이스를 Microsoft.Samples.ClickOnceOnDemand 또는 선택한 네임스페이스로 변경하는 것이 좋습니다. 편의상 이 연습의 두 프로젝트는 동일한 네임스페이스에 있습니다.

  2. Message라는 속성 하나가 있는 DynamicClass라는 클래스를 정의합니다.

    Public Class DynamicClass
        Sub New()
    
        End Sub
    
        Public ReadOnly Property Message() As String
            Get
                Message = "Hello, world!"
            End Get
        End Property
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Microsoft.Samples.ClickOnceOnDemand
    {
        public class DynamicClass
        {
            public DynamicClass() {}
    
            public string Message
            {
                get
                {
                    return ("Hello, world!");
                }
            }
        }
    }
    
  3. 솔루션 탐색기에서 Windows Forms 프로젝트를 선택합니다. System.Deployment.Application 어셈블리에 대한 참조와 ClickOnceLibrary 프로젝트에 대한 프로젝트 참조를 추가합니다.

    참고

    Visual Basic에서는 프로젝트 속성을 수정하여 이 프로젝트의 루트 네임스페이스를 Microsoft.Samples.ClickOnceOnDemand 또는 선택한 네임스페이스로 변경하는 것이 좋습니다. 편의상 이 연습의 두 프로젝트는 동일한 네임스페이스에 있습니다.

  4. 폼을 마우스 오른쪽 단추로 클릭하고 메뉴에서 코드 보기를 클릭한 후 다음 참조를 폼에 추가합니다.

    Imports System.Reflection
    Imports System.Deployment.Application
    Imports System.Collections.Generic
    Imports Microsoft.Samples.ClickOnceOnDemand
    Imports System.Security.Permissions
    
    using System.Reflection;
    using System.Deployment.Application;
    using Microsoft.Samples.ClickOnceOnDemand;
    using System.Security.Permissions;
    
  5. 요청 시 이 어셈블리를 다운로드하는 다음과 같은 코드를 추가합니다. 이 코드에서는 제네릭 Dictionary 클래스를 사용하여 어셈블리 집합을 그룹 이름에 매핑하는 방법을 보여 줍니다. 이 연습에서는 어셈블리를 하나만 다운로드할 것이므로 그룹에 어셈블리가 하나만 있습니다. 실제 응용 프로그램에서는 응용 프로그램의 한 기능과 관련된 모든 어셈블리를 동시에 다운로드할 수 있습니다. 매핑 테이블을 사용하면 한 기능에 속하는 모든 DLL을 하나의 다운로드 그룹 이름에 연결하여 이 작업을 쉽게 수행할 수 있습니다.

    ' Maintain a dictionary mapping DLL names to download file groups. This is trivial for this sample,
    ' but will be important in real-world applications where a feature is spread across multiple DLLs,
    ' and you want to download all DLLs for that feature in one shot. 
    Dim DllMappingTable As New Dictionary(Of String, String)()
    
    <SecurityPermission(SecurityAction.Demand, ControlAppDomain:=True)> _
    Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
    
        ' Add any initialization after the InitializeComponent() call.
        DllMappingTable("ClickOnceLibrary") = "ClickOnceLibrary"
    End Sub
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf Me.CurrentDomain_AssemblyResolve
    End Sub
    
    Private Function CurrentDomain_AssemblyResolve(ByVal sender As Object, ByVal args As ResolveEventArgs) As System.Reflection.Assembly
        Dim NewAssembly As Assembly = Nothing
    
        If (ApplicationDeployment.IsNetworkDeployed) Then
            Dim Deploy As ApplicationDeployment = ApplicationDeployment.CurrentDeployment
    
            ' Get the DLL name from the argument.
            Dim NameParts As String() = args.Name.Split(",")
            Dim DllName As String = NameParts(0)
            Dim DownloadGroupName As String = DllMappingTable(DllName)
    
            Try
                Deploy.DownloadFileGroup(DownloadGroupName)
            Catch ex As Exception
                MessageBox.Show("Could not download file group from Web server. Contact administrator. Group name: " & DownloadGroupName & "; DLL name: " & args.Name)
                Throw (ex)
            End Try
    
            ' Load the assembly.
            ' Assembly.Load() doesn't work here, as the previous failure to load the assembly
            ' is cached by the CLR. LoadFrom() is not recommended. Use LoadFile() instead.
            Try
                NewAssembly = Assembly.LoadFile(Application.StartupPath & "\" & DllName & ".dll")
            Catch ex As Exception
                Throw (ex)
            End Try
        Else
            ' Major error - not running under ClickOnce, but missing assembly. Don't know how to recover.
            Throw New Exception("Cannot load assemblies dynamically - application is not deployed using ClickOnce.")
        End If
    
        Return NewAssembly
    End Function
    
    // Maintain a dictionary mapping DLL names to download file groups. This is trivial for this sample,
    // but will be important in real-world applications where a feature is spread across multiple DLLs,
    // and you want to download all DLLs for that feature in one shot. 
    Dictionary<String, String> DllMapping = new Dictionary<String, String>();
    
    [SecurityPermission(SecurityAction.Demand, ControlAppDomain=true)]
    public Form1()
    {
        InitializeComponent();
    
        DllMapping["ClickOnceLibrary"] = "ClickOnceLibrary";
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }
    
    /*
     * Use ClickOnce APIs to download the assembly on demand.
     */
    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        Assembly newAssembly = null;
    
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
    
            // Get the DLL name from the Name argument.
            string[] nameParts = args.Name.Split(',');
            string dllName = nameParts[0];
            string downloadGroupName = DllMapping[dllName];
    
            try
            {
                deploy.DownloadFileGroup(downloadGroupName);
            }
            catch (DeploymentException de)
            {
                MessageBox.Show("Downloading file group failed. Group name: " + downloadGroupName + "; DLL name: " + args.Name);
                throw (de);
            }
    
            // Load the assembly.
            // Assembly.Load() doesn't work here, as the previous failure to load the assembly
            // is cached by the CLR. LoadFrom() is not recommended. Use LoadFile() instead.
            try
            {
                newAssembly = Assembly.LoadFile(Application.StartupPath + @"\" + dllName + ".dll");
            }
            catch (Exception e)
            {
                throw (e);
            }
        }
        else
        {
            //Major error - not running under ClickOnce, but missing assembly. Don't know how to recover.
            throw (new Exception("Cannot load assemblies dynamically - application is not deployed using ClickOnce."));
        }
    
    
        return (newAssembly);
    }
    
  6. 보기 메뉴에서 도구 상자를 클릭합니다. Button도구 상자에서 폼으로 끌어 옵니다. 단추를 두 번 클릭하고 Click 이벤트 처리기에 다음 코드를 추가합니다.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim DC As New DynamicClass()
        MessageBox.Show("Message is " & DC.Message)
    End Sub
    
    private void getAssemblyButton_Click(object sender, EventArgs e)
    {
        DynamicClass dc = new DynamicClass();
        MessageBox.Show("Message: " + dc.Message);
    }
    

선택적 어셈블리로 표시

Visual Studio를 사용하여 ClickOnce 응용 프로그램에서 어셈블리를 선택적인 것으로 표시하려면

  1. 솔루션 탐색기에서 Windows Forms 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 클릭합니다. 게시 탭을 선택합니다.

  2. 응용 프로그램 파일 단추를 클릭합니다.

  3. 목록에서 ClickOnceLibrary.dll을 찾습니다. 게시 상태 드롭다운 상자를 포함으로 설정합니다.

  4. 그룹 드롭다운 상자를 확장하고 새로 만들기를 선택합니다. 새 그룹 이름으로 ClickOnceLibrary를 입력합니다.

  5. 계속하여 방법: 게시 마법사를 사용하여 ClickOnce 응용 프로그램 게시의 설명에 따라 응용 프로그램을 게시합니다.

매니페스트 생성 및 편집 도구인 그래픽 클라이언트(MageUI.exe)를 사용하여 ClickOnce 응용 프로그램에서 어셈블리를 선택적인 것으로 표시하려면

  1. 연습: ClickOnce 응용 프로그램 수동 배포의 설명에 따라 ClickOnce 매니페스트를 만듭니다.

  2. MageUI.exe를 닫기 전에 배포의 응용 프로그램 매니페스트가 들어 있는 탭을 선택하고 이 탭 안에서 파일 탭을 선택합니다.

  3. 응용 프로그램 파일 목록에서 ClickOnceLibrary.dll을 찾고 해당 파일 형식 열을 없음으로 설정합니다. 그룹 열에 ClickOnceLibrary.dll을 입력합니다.

새 어셈블리 테스트

요청 시 어셈블리를 테스트하려면

  1. ClickOnce를 사용하여 배포된 응용 프로그램을 시작합니다.

  2. 주 폼이 나타나면 Button을 누릅니다. "Hello, World!"라는 문자열이 메시지 상자 창에 나타나야 합니다.

참고 항목

참조

ApplicationDeployment