연습: 디자이너를 사용하여 ClickOnce 배포 API로 주문형 어셈블리 다운로드

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

참고

System.Deployment.Application 네임스페이스의 ApplicationDeployment 클래스 및 API는 .NET Core 및 .NET 5 이상 버전에서 지원되지 않습니다. .NET 7에서 애플리케이션 배포 속성에 액세스하는 새로운 방법을 지원합니다. 자세한 내용은 .NET에서 ClickOnce 배포 속성 액세스를 참조하세요. .NET 7은 ApplicationDeployment 메서드와 동등한 메서드를 지원하지 않습니다.

참고 항목

이 절차를 사용하려면 완전 신뢰 상태에서 애플리케이션을 실행해야 합니다.

참고

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

프로젝트 만들기

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

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

    참고

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

  2. DynamicClass 라는 이름의 단일 속성으로 Message라는 이름의 클래스를 정의합니다.

    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. 폼을 마우스 오른쪽 단추로 클릭하고 메뉴에서 코드 보기 를 클릭한 후 폼에 다음 참조를 추가합니다.

    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. 
    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 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!"라는 문자열이 표시됩니다.