Microsoft MVP성태의 닷넷 이야기
C#으로 만든 DLL 배포하기 [링크 복사], [링크+제목 복사],
조회: 20700
글쓴 사람
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가 보이고
자동 배포한 컴퓨터에선 보이지 않습니다.

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

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

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

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

감사합니다

[guest]
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;


[guest]
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());
}
[guest]
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());
}

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

[guest]

... 76  77  78  79  80  81  82  83  [84]  85  86  87  88  89  90  ...
NoWriterDateCnt.TitleFile(s)
381윤용한5/29/200611142    답변글 [답변]: ATL Event에서 스크립트가 값을 다시 돌려주는 방법은?
382윤용한5/29/200611760        답변글 [답변]: [답변]: ATL Event에서 스크립트가 값을 다시 돌려주는 방법은?
383정성태5/30/200612039            답변글 [답변]: [답변]: [답변]: ATL Event에서 스크립트가 값을 다시 돌려주는 방법은?
378guest5/26/200611521managed 와 unmanaged 의 차이가 뭐져?
379정성태5/26/200611832    답변글 [답변]: managed 와 unmanaged 의 차이가 뭐져? [1]
384guest5/30/200611322        답변글 감사합니다.
376노기도5/16/200611647vb6의 GetObjectContext 를 2005에서는 어떻게 사용해야 하나요? [3]
375이덕희5/15/200613723SmartClient 강좌를 보고... 엑박이 나옵니다... [2]파일 다운로드1
3745/12/200612681데이타셋을 레코드셋으로 변경하는 방법...... [2]파일 다운로드1
373아폴론5/12/200611477스마트 클라이언트.. 강좌대로 했는데.. 이런 에러가 나네요. [1]파일 다운로드1
372정보문5/11/200612242DHCP를 쓰는 이유 [1]
366임경훈5/8/200612073지정된 웹서버에서 ASP.NET 버전 1.1이 실행되고 있지 않아 ASP.NET 웹 응용 프로그램 또는 웹서비스를 실행할수 없습니다 [2]
365꿈의공장5/8/200611807스마트 클라이언트 사용시 안보이는 현상 [1]
364조준현5/3/2006112352.0 스마트클라이언트에서.. public 메소드등을 스크립트에서 접근하는 방법이..? [2]
363혁이5/2/200613729스마트 클라이언트에 farpoint 컨트롤 올리기 2번째 질문입니다 [1]파일 다운로드1
361혁이4/28/200612265스마트 클라이언트에 FarPointSpread를 올렸는데요. 보이지가 않습니다..음.. [1]
360꿈의공장4/28/200612213스마트클라이언트와 오라클에 연결 [1]
359박호성4/28/200611550ASP.NET에서 COM Object를 사용하려면? [1]
358임동오4/27/200612177ASP -> COM+ Proxy 연결문제입니다. 151초동안 아무응답없습니다. ㅠㅠ
362정성태4/30/200613737    답변글 [답변]: ASP -> COM+ Proxy 연결문제입니다. 151초동안 아무응답없습니다. ㅠㅠ
354노기도4/24/200611465시스템 구성에 대해 의견을 듣고 십습니다.
355정성태4/25/200611494    답변글 [답변]: 시스템 구성에 대해 의견을 듣고 십습니다.
356노기도4/25/200610856        답변글 [답변]: 귀찮게 해드려 죄송스럽지만.
357정성태4/25/200611321            답변글 [답변]: [답변]: 귀찮게 해드려 죄송스럽지만. [1]
352산들바람4/19/200611008이번겨울방학때세도나를 여행하려구하는데요,,,
353정성태4/20/200617907    답변글 [답변]: 이번겨울방학때세도나를 여행하려구하는데요,,,
... 76  77  78  79  80  81  82  83  [84]  85  86  87  88  89  90  ...