https://docs.microsoft.com/ko-kr/visualstudio/deployment/walkthrough-downloading-assemblies-on-demand-with-the-clickonce-deployment-api?view=vs-2022 

 

주문형 어셈블리 다운로드(ClickOnce API) - Visual Studio (Windows)

ClickOnce 애플리케이션의 특정 어셈블리를 선택 사항으로 표시하고 공용 언어 런타임에 필요할 때 다운로드하는 방법을 알아봅니다.

docs.microsoft.com

 

 

 

연습: ClickOnce 배포 API를 통해 주문형 어셈블리 다운로드

 

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

 참고

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

사전 요구 사항

이 연습을 완료하려면 다음 구성 요소 중 하나가 필요합니다.

  • Windows SDK. Windows SDK는 Microsoft 다운로드 센터에서 다운로드할 수 있습니다.
  • Visual Studio.

프로젝트 만들기

주문형 어셈블리를 사용하는 프로젝트를 만들려면

  1. ClickOnceOnDemand라는 디렉터리를 만듭니다.
  2. Windows SDK 명령 프롬프트 또는 Visual Studio 명령 프롬프트를 엽니다.
  3. ClickOnceOnDemand 디렉터리로 변경합니다.
  4. 다음 명령을 사용하여 퍼블릭/프라이빗 키 쌍을 생성합니다.
    sn -k TestKey.snk
    
  5. cmd복사
  6. 메모장 또는 다른 텍스트 편집기를 사용하여 Message라는 단일 속성을 사용하여 DynamicClass라는 클래스를 정의합니다.
    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!");
                }
            }
        }
    }
    
  7. C#복사
  8. 사용하는 언어에 따라 ClickOnceLibrary.cs 또는 ClickOnceLibrary.vb 라는 파일로 텍스트를 ClickOnceOnDemand 디렉터리에 저장합니다.
  9. 파일을 어셈블리로 컴파일합니다.
    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
  10. C#복사
  11. 어셈블리를 위한 퍼블릭 키 토큰을 얻으려면 다음 명령을 사용합니다.
    sn -T ClickOnceLibrary.dll
    
  12. cmd복사
  13. 텍스트 편집기를 사용하여 새 파일을 만들고 다음 코드를 입력합니다. 이 코드는 필요한 경우 ClickOnceLibrary 어셈블리를 다운로드하는 Windows Forms 애플리케이션을 만듭니다.
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Reflection;
    using System.Deployment.Application;
    using Microsoft.Samples.ClickOnceOnDemand;
    
    namespace ClickOnceOnDemand
    {
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Unrestricted=true)]
        public class Form1 : Form
        {
            // 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>();
    
            public static void Main()
            {
                Form1 NewForm = new Form1();
                Application.Run(NewForm);
            }
    
            public Form1()
            {
                // Configure form. 
                this.Size = new Size(500, 200);
                Button getAssemblyButton = new Button();
                getAssemblyButton.Size = new Size(130, getAssemblyButton.Size.Height);
                getAssemblyButton.Text = "Test Assembly";
                getAssemblyButton.Location = new Point(50, 50);
                this.Controls.Add(getAssemblyButton);
                getAssemblyButton.Click += new EventHandler(getAssemblyButton_Click);
    
                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," +  
                "Version=1.0.0.0, Culture=en, PublicKeyToken=03689116d3a4ae33");
                    }
                    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);
            }
    
            private void getAssemblyButton_Click(object sender, EventArgs e)
            {
                DynamicClass dc = new DynamicClass();
                MessageBox.Show("Message: " + dc.Message);
            }
        }
    }
    
  14. C#복사
  15. 코드에서 LoadFile에 대한 호출을 찾습니다.
  16. PublicKeyToken을 이전에 검색한 값으로 설정합니다.
  17. 파일을 Form1.cs 또는 Form1.vb 로 저장합니다.
  18. 다음 명령을 사용하여 실행 파일로 컴파일합니다.
    csc /target:exe /reference:ClickOnceLibrary.dll Form1.cs
    
  19. C#복사

어셈블리를 선택 사항으로 표시

MageUI.exe를 사용하여 ClickOnce 애플리케이션에서 어셈블리를 선택 사항으로 표시하려면

  1. MageUI.exe 를 사용하여 연습: ClickOnce 애플리케이션 수동으로 배포에 설명된 대로 애플리케이션 매니페스트를 만듭니다. 애플리케이션 매니페스트에 대해 다음 설정을 사용합니다.
    • 애플리케이션 매니페스트의 이름을 ClickOnceOnDemand 로 지정합니다.
    • 파일 페이지의 ClickOnceLibrary.dll 행에서 파일 형식 열을 없음 으로 설정합니다.
    • 파일 페이지의 ClickOnceLibrary.dll 행에서 Group 열에 ClickOnceLibrary.dll을 입력합니다.
  2. MageUI.exe 를 사용하여 연습: ClickOnce 애플리케이션 수동으로 배포에 설명된 대로 배포 매니페스트를 만듭니다. 배포 매니페스트에 대해 다음 설정을 사용합니다.
    • 배포 매니페스트의 이름을 ClickOnceOnDemand로 지정합니다.

새 어셈블리 테스트

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

  1. 웹 서버에 ClickOnce 배포를 업로드합니다.
  2. 배포 매니페스트에 URL을 입력하여 웹 브라우저에서 ClickOnce로 배포된 애플리케이션을 시작합니다. ClickOnceClickOnceOnDemand 애플리케이션을 호출하고 adatum.com 루트 디렉터리에 업로드하면 URL은 다음과 같습니다.
    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. 복사
  4. 기본 폼이 나타나면 Button을 누릅니다. 메시지 상자 창에 "Hello, World!"라는 문자열이 표시되어야 합니다.

참조


권장 콘텐츠

  • ClickOnce 애플리케이션 - Visual Studio (Windows)

    게시 마법사를 사용하여 처음으로 ClickOnce 애플리케이션을 게시하는 방법을 알아봅니다. Project 디자이너의 게시 페이지에서 나중에 변경합니다.

  • ClickOnce 앱 수동 배포 - Visual Studio (Windows)

    명령줄 버전 또는 매니페스트 생성 및 편집 도구의 그래픽 버전 중 하나를 사용 하 여 ClickOnce 배포를 만드는 방법에 대해 알아봅니다.

  • 로컬 & 원격 데이터 액세스(ClickOnce 앱) - Visual Studio (Windows)

    로컬 및 원격으로 데이터를 읽고 쓰기 위해 ClickOnce 제공하는 다양한 옵션에 대해 알아봅니다.

  • ClickOnce 및 응용 프로그램 설정 - Visual Studio (Windows)

    응용 프로그램 설정 파일이 ClickOnce 응용 프로그램에서 작동 하는 방법 및 사용자가 다음 버전으로 업그레이드 하는 경우 설정 ClickOnce 마이그레이션하는 방법에 대해 알아봅니다.

  • ClickOnce 업데이트 전략 선택 - Visual Studio (Windows)

    ClickOnce 애플리케이션에서 자동 업데이트를 지원하는 방법과 사용할 수 있는 업데이트 전략을 알아봅니다.

  • ClickOnce 응용 프로그램에 대 한 코드 액세스 보안 - Visual Studio (Windows)

    ClickOnce 응용 프로그램에 대 한 코드 액세스 보안 및 코드 액세스 보안 권한을 구성 하는 방법에 대해 알아봅니다.

  • ClickOnce 애플리케이션 보안 - Visual Studio (Windows)

    ClickOnce 응용 프로그램에 대 한 코드에 대 한 액세스를 제한할 수 있는 .NET Framework의 코드 액세스 보안 제약 조건에 대 한 영향에 대해 알아봅니다.

  • ApplicationDeployment 클래스 (System.Deployment.Application)

    현재 배포를 프로그래밍 방식으로 업데이트하도록 지원하고 요청 시에 파일을 다운로드하도록 처리합니다.Supports updates of the current deployment programmatically, and handles on-demand downloading of files. 이 클래스는 상속될 수 없습니다.This class cannot be inherited.

무료 .NET용 컴포넌트

===================================================

ComponentFactory/Krypton (오리지널)

https://github.com/ComponentFactory/Krypton

 

GitHub - ComponentFactory/Krypton: Krypton WinForms components for .NET

Krypton WinForms components for .NET. Contribute to ComponentFactory/Krypton development by creating an account on GitHub.

github.com

NuGet : https://www.nuget.org/packages/KryptonToolkitSuite/4.6.501

 

KryptonToolkitSuite 4.6.501

Krypton WinForms components for .NET

www.nuget.org


 

ComponentFactory/Krypton에서 분기된 프로젝트

https://github.com/megakraken/Krypton

 

GitHub - megakraken/Krypton: Krypton WinForms components for .NET

Krypton WinForms components for .NET. Contribute to megakraken/Krypton development by creating an account on GitHub.

github.com

NuGet : https://www.nuget.org/packages/Krypton.Components.Suite/4.5.9

 

Krypton.Components.Suite 4.5.9

Krypton Suite of .NET WinForms Controls

www.nuget.org

 


 

※ Visual Studio Community 2019에서 사용 가능 확인함.

※ 두가지 중 뭐가 좋은지 확인 되지 않음 그건 사용 자분들이 ^^

Visual Studio에서 빌드(Build) 또는 디버그(Debug) 시에 발행하는 경고 오류가 하기와 같은 형식으로 발생할 경우 해결 방법

※ 경고라서 특별히 프로그램 실행하는데 문제는 안되나… 꺼림직해서…

경고    1    포함된 interop 어셈블리 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE.dll'에 대한 참조는 ‘~~~~~~~~~~~~~.dll' 어셈블리가 해당 어셈블리에 대해 만든 간접 참조로 인해 만들어졌습니다. 두 어셈블리 중 하나에서 'Interop 형식 포함' 속성을 변경하십시오.   ~~~~

경고    2    포함된 interop 어셈블리 'c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE80.dll'에 대한 참조는 ‘~~~~~~~~~~~~~.dll' 어셈블리가 해당 어셈블리에 대해 만든 간접 참조로 인해 만들어졌습니다. 두 어셈블리 중 하나에서 'Interop 형식 포함' 속성을 변경하십시오.    ~~~~~

상기 오류 발생한 경우 프로젝트 참조에서 해당 참조를 선택하여 “Interop 형식 포함(Embed Interop Types)”를 False로 변경한다.

   

출처 : 자작(userpark.net)

오류가 발생된 환경은 아래와 같으며, 아래 환경기준으로 설명하겠습니다.

  • OS : Microsoft Windows 7 Pro. 64bit
  • VisualStudio 2012
  • Team Foundation Server 2012

PC명을 변경하였을시 Team Foundation Server와 VisualStudio 팀프로젝트 이용시 오류가 발생 된다.

 

해당 솔루션을 오픈 시 PC명이 변경되었으니 “tf workspaces /updateComputerName:oldComputerName” 명령을 이용하여 변경하라고 한다.

(이 부분은 벌써 처리한 후라서 기억이 가물가물합니다.)

 

실행창을 열어 “cmd.exe”를 실행합니다.

저 명령대로 “tf workspaces”라고 실행하여 보면 경로를 찾을 수 없다고 나옵니다.

사용자별로 틀리겠지만 “Windows 7 64bit”환경에서는 “C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\” 경로에 tf.exe가 있습니다.

 

그래서 전체 경로를 포함한 명령을 실행하여 현재 Workspace들을 확인합니다.

C:\>"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf" workspaces

변경하기 위해서는

C:\>"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf" workspaces /updateComputerName:{이전 PC명}

이라고 하면 여기서도 오류를 발생합니다.

/updateComputerName 또는 /updateUserName을 지정할 때에는 /collection 옵션을 지정해야 합니다.

그럼 최종 명령은

"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf" workspaces /updateComputerName:JHPARK-NOTE /collection:http://tfs2012.hi-techeng.co.kr:8080/tfs/HITECHENG

C:\>"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\tf" workspaces /updateComputerName:{이전 PC명} /collection:http://{Team Foondation Server URL}:{Port(기본:8080)}/tfs/{팀 프로젝트 컬렉션}

그 이후 이전 PC명으로 된 Workspace를 절대 삭제하지 않는것을 권장합니다.

혹여 삭제를 하였을 경우 새로 솔루션을 소수제어에 추가하고 충돌해결을 해야 하는 번거러운 작업을 경험하게 되실 겁니다.(제가 그랬습니다.)

대략 적으로 설명을 하였는데 이해가 되었는지 모르겠습니다. 저만의 방식과 해결후 정리 개념으로 작성하다보니…

 

기타 참고 문헌 :

(한글) http://msdn.microsoft.com/ko-kr/library/54dkh0y3%28v=vs.100%29   

(영문) http://msdn.microsoft.com/en-us/library/54dkh0y3%28v=vs.100%29.aspx

+ Recent posts