Microsoft MVP성태의 닷넷 이야기
C#으로 만든 DLL 배포하기 [링크 복사], [링크+제목 복사]
조회: 3609
글쓴 사람
cab2da (cab2da at naver.com)
홈페이지
첨부 파일
 
안녕하세요?

질문이 있어 글 남깁니다.

목적 :
 C#을 이용해 만든 dll 을
 EXCEL 에서 사용할려고 합니다.

수작업으로 아래와 같이 실행해 주면 사용이 가능해 집니다.
  1. 해당 dll 파일을 사용자의 컴퓨터에 저장
  2. RegAsm.exe 파일이 있는 경로에서 명령프롬프트 실행(관리자 권한으로)
  3. 아래 명령문 실행
     C:\Program Files (x86)\...path...\Tools>RegAsm /codebase C:\DLL\ExcelTest.dll

수작업으로 배포하는 부분을 자동화하고 싶습니다.
즉 C#으로 프로젝트를 만들어서 사용자의 컴퓨터에서 setup.exe를 실행하면 dll 을 사용할 수 있게 하고 싶습니다.

감사합니다

-----------------------------------------------------------------------------------
ExcelTest.dll 은 Resources 폴더에 추가한 상태고 빌드 작업을 [포함 리소스]로 설정한 상태입니다.

ExcelTest.dll 소스코드
namespace ExcelTest
{
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class CSharpTools
    {
        [ComVisible(true)]
        public string AddBrackets(string value)
        {
            return "[" + value + "]";
        }

    }
}

DLL 배포하기 위해 작업한 소스 코드
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Principal;
using System.Windows.Forms;

namespace RegisterTest
{
    static class Program
    {
        /// <summary>
        /// 해당 응용 프로그램의 주 진입점입니다.
        /// </summary>
        [STAThread]
        static void Main()
        {
            //ClickOnce - 관리자 권한 상승하는 방법
            //출처 : https://www.sysnet.pe.kr/2/0/950
            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;
            }

            // 컴파일 배포시 단이 exe 로 배포하고 , 참조하는 dll은 리소스 파일에 추가하여 (참조리소스)
            // 단일 실행파일로 만들어 배포함.
            // 프로그램은 실행시 참조 dll 파일을 생성하고 리소스 파일에 있는 원 파일을 읽어서 대체함.
            string strDllPath = "";
            string strFullFileName = "";
            try
            {
                strDllPath = Application.ExecutablePath.Replace("/", "\\");
                int intPos = strDllPath.LastIndexOf("\\");
                if (intPos >= 1)
                    strDllPath = strDllPath.Substring(0, intPos).Trim('\\');

                strFullFileName = strDllPath + "\\ExcelTest.dll";
                FileInfo fileinfo = new FileInfo(strFullFileName);
                if (fileinfo.Exists == false)
                {
                    byte[] aryData = Resource1.ExcelTest; //리소드 디자인에 저장한 이름
                    FileStream fileStream = new FileStream(fileinfo.FullName, FileMode.CreateNew);
                    fileStream.Write(aryData, 0, aryData.Length);
                    fileStream.Close();
                }
                // 출처: https://lovelypang.tistory.com/73 [코코몽과 토토몽]
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }

            // dll 파일 레지스트리에 등록하기
            // 출처: https://developer-joe.tistory.com/148
            try
            {
                Console.WriteLine("This program is registering .TLB to Windows registry.");

                var proc = new ProcessStartInfo();

                // .dll을 이용해서 .tlb생성 및 레지스트리 등록 명령어
                // regasm의 사용법은 DOS창(커맨더 창)에서 regasm /?을 하면
                // regasm을 아래와같이 이 파일의 경로를 표시하지 않으면 현재의 프로그램의 실행 파일과 같은 위치에
                // regasm.exe가 있어야 된다.
                //string mCmd = "regasm ExcelTest.dll /tlb:ExcelTest.tlb";
                string mCmd = "regasm ExcelTest.dll /tlb:ExcelTest.tlb";
                proc.UseShellExecute = true;

                //아래 경로에 .DLL가 있어야하고 .tlb가 이 위치에 생성이 되고 regasm.exe도 이 위치에서
                //작업을 하게된다.
                proc.WorkingDirectory = @strDllPath;

                //위의 regasm EthernetClientLib.dll /tlb:EthernetClientLib.tlb를 실행시킬 명령어
                proc.FileName = "cmd.exe";

                //아래 속성의 runas 자체가 관리자 권한으로 실행시키겠다는 설정값이다.
                proc.Verb = "runas";
                proc.Arguments = "/C " + mCmd;
                proc.WindowStyle = ProcessWindowStyle.Hidden;
                Process rt = Process.Start(proc);

                Debug.WriteLine("##### .tlb 생성 및 레지스트리 등록을 마쳤습니다.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

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

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

            return false;
        }

    }
}

-----------------------------------------------------------------------------------
참고한 사이트
C# 코드상에서 .tlb 생성 및 레지스트리 등록하는 법
https://developer-joe.tistory.com/148

regasm.exe로 어셈블리 등록 시 시스템 변경 사항 (1) - .NET 2.0 + x86/x64/AnyCPU
; https://www.sysnet.pe.kr/2/0/1286
 
regasm.exe로 어셈블리 등록 시 시스템 변경 사항 (2) - .NET 4.0 + .NET 2.0
; https://www.sysnet.pe.kr/2/0/1287

regasm.exe로 어셈블리 등록 시 시스템 변경 사항 (3) - Type Library
; https://www.sysnet.pe.kr/2/0/1288






[최초 등록일: ]
[최종 수정일: 4/9/2019 ]


비밀번호

댓글 쓴 사람
 



2019-04-09 07시38분
수작업 1~3단계를 잘 구현하신 것 같은데... 어떤 문제가 있는 건가요?
정성태
2019-04-10 10시41분
[cab2da] 수작업으로 하면 사용자 컴퓨터에서 dll을 정상적으로 사용을 할 수 있는데
setup.exe를 이용해 실행하면 오류는 발생하지 않는데
dll 을 인식하지 못해 사용할 수 없습니다.
엑셀 VBA 편집기에서 참조를 눌러보면
수작업으로 배포한 컴퓨터에선 ExcelTest가 보이고
자동 배포한 컴퓨터에선 보이지 않습니다.

[손님]
2019-04-11 11시37분
이런 경우에는 원칙을 생각하시면 됩니다. 딱히 수작업이나 코드로 하는 거나 다를 바가 없기 때문에 안 된다는 것은 어딘가 오류가 있다는 것입니다. 따라서, 1) 파일이 로컬에 있는지 확인하고 2) regasm으로 인한 등록이 레지스트리에 잘 되었는지 확인하면 됩니다. 그냥 보면 regasm 과정 중에 오류가 있을 듯한데, 어쨌든 중요한 것은 코드로 했다고 달라질 만한 작업은 아닙니다.
정성태
2019-04-11 12시10분
[cab2da] 안녕하세요?

setup 파일을 실행하면 dll 파일도 포함되는지 궁금하여
strDllPath 에 있는 경로로 가보니 해당 파일이 있었습니다.
(숨긴 항목도 보이게 하니 AppData 폴더의 하위 폴더에 있더군요)

레지스트로에 잘 되었는지는 확인하는 방법을 찾아셔 확인해 보겠습니다.

아무래도 regasm.exe를 찾아서 해당 경로에서 실행하는 것으로 해야 할 듯 합니다.
(오류가 발생하지 않고 등록을 마쳤다고 하니...)

감사합니다

[손님]
2019-04-11 01시33분
그런데... 설마 "Debug.WriteLine("##### .tlb 생성 및 레지스트리 등록을 마쳤습니다.");" 코드가 수행되었다고 해서 regasm이 성공했다고 생각하는 건 아니죠?
정성태
2019-04-15 02시39분
[cab2da] 코드 중 일부를 아래처럼 수정하고
레지스트리 편집기에서
[EXCELTEST]를 찾기했는데...
찾지를 못하는군요.
무엇인가를 놓치고 있는 듯 합니다

string mCmd = @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /codebase " + strFullFileName;


[손님]
2019-04-15 02시54분
FileName부터 cmd.exe를 주었는데 왜 그런 식으로 한 거죠?

이런 경우, FileName = "regasm.exe"로 하고 Arguments에 "/codebase …[dll_path]…"로 설정해야 합니다.

그리고 정상적으로 명령어가 실행되었는지 proc.StandardOutput을 이용해 확인하세요.
정성태
2019-04-16 10시47분
[cab2da] 안녕하세요?

아래의 코드로 테스트 해 보니
proc.StandardOutputEncoding 이 null로 나오는군요.

검토해 주셔서 감사합니다.

try
{
    ProcessStartInfo proc = new ProcessStartInfo();
    proc.UseShellExecute = true;
    proc.FileName = "RegAsm.exe";
    proc.WorkingDirectory = @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\";
    proc.Verb = "runas";
    proc.Arguments = "/codebase " + strFullFileName;
    proc.WindowStyle = ProcessWindowStyle.Hidden;
    Process.Start(proc);

    string result = "";
    if (proc.StandardOutputEncoding != null)
        result = proc.StandardOutputEncoding.ToString();
    else
        result = "null";
    MessageBox.Show(result);
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message.ToString());
}
[손님]
2019-04-16 04시22분
아래의 글을 참고하세요.

Process.Start로 실행한 콘솔 프로그램의 출력 결과를 얻는 방법
; http://www.sysnet.pe.kr/2/0/11870

정성태
2019-04-18 03시51분
[cab2da] 아래처럼 구문을 수정하고 실행하니 catch 부분에서 메세지박스가 출력되네요.
오류 : 지정된 파일을 찾을 수 없다

아마도
Process proc = Process.Start(psi);
이 구문에서 오류가 발생하는 듯 합니다.

소중한 시간 할애하여 검토해 주셔서 감사합니다.


----------------------------------------------------------
try
{
    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = "RegAsm.exe";
    psi.WorkingDirectory = @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\";
    psi.Verb = "runas";
    psi.Arguments = "/codebase " + strFullFileName;
    psi.WindowStyle = ProcessWindowStyle.Hidden;
    psi.RedirectStandardOutput = true;
    psi.UseShellExecute = false;

    MessageBox.Show("시작" + strFullFileName);

    Process proc = Process.Start(psi);
    string txt = proc.StandardOutput.ReadToEnd();

    MessageBox.Show(txt);
}
catch (Exception ex)
{
    MessageBox.Show("오류 : " + ex.Message.ToString());
}

----------------------------------------------------------

[손님]

1  2  [3]  4  5  6  7  8  9  10  11  12  13  14  15  ...
NoWriterDateCnt.TitleFile(s)
5367박순기8/8/2020250디버깅 시 반전되는 부분 글 색상이나 배경색을 변경하는 방법 [3]파일 다운로드1
5366간절함8/7/2020318하나의 솔루션에서, 32비트 프로젝트에서 다른 64비트 프로젝트 참조하는 방법 궁금합니다. [4]
5365영귤8/6/2020242TimeSpan 구할 때 시간대를 바꿔도 같은 값이 나오는 것 같습니다. [1]
5364박순기8/5/2020303visual studio의 menu bar font size 변경방법 문의 [2]파일 다운로드1
5363클락8/1/2020511c# 9.0 출간 준비 중이신가요? [2]
5361하태7/29/2020264안녕하세요! 바이너리데이터 파싱 질문 드리겠습니다!. [2]
5360진우7/28/2020377엑셀에서 발생하는 모든 이벤트를 감지 할수 있는지 궁금합니다. [6]파일 다운로드1
5358홍길동7/22/2020221개체에서 open 속성이나 매서드가 지원 되지 않읍니다.라고 오류창이 뜨는데. [1]
5357손동섭7/22/2020367책 예제코드... [3]
5355neska7/21/2020252안녕하세요 문의 드립니다 [1]
5354민성7/15/2020424안녕하세요 db연결 문자 보안 [2]
5353형성재7/14/2020290Visual Studio Setup Project에서 VC++2010재배포패키지설치 [4]
5352윤식7/10/2020596닷넷코어 빌드 시 runtimeconfig 파일을 없앨 수 있는지.. [4]
5351runryan7/2/2020551C# 에서 C++ dll 병렬 사용 [1]
5350홍성호6/29/2020796C++에서 정의된 구조체(공유메모리)를 C#으로 공유메모리에서 구조체 변환시 에러가 발생 합니다. [1]파일 다운로드1
5349jerome.lee6/24/2020377logon credential provider 관련 문의드립니다. [1]
5348776/19/2020456시작하세요 C# 8.0프로그래밍 책에 대한 질문입니다. [8]
5347민성6/19/2020369안녕하세요 WPF Binding에서요 [1]
5346dimohy6/18/2020376Task.WhenAll() 메소드를 이용한 코드를 좀더 짧게 사용하고 싶은데 다른 표현이 있을까요? [3]
5345질문요6/12/2020428idc vs 집 속도 [2]
5344하태6/2/2020542c++ .ilb에서 c# dll 호출 질문 드리겠습니다 (콜백함수 전달) [4]
5343하태6/2/2020581안녕하십니까! c# dll을 c++ .lib에서 호출 질문 드립니다. [4]
5342진우5/30/2020686c++ 에서 C# DLL 사용 문의 [2]
5341미나리5/28/2020564스레드 lock키워드 관련 질문드립니다 [3]
5339민성5/27/2020326WPF cmd을 실행을 할때 파라미터 넘기는 방법 [1]
5338서영준5/26/2020558.Net Core Blazor 서버에 Xing API를 이용한 통신 요청 [5]파일 다운로드1
1  2  [3]  4  5  6  7  8  9  10  11  12  13  14  15  ...