컴파일 된 실행 파일에 DLL 포함


618

기존 DLL을 컴파일 된 C # 실행 파일에 포함시켜 배포 할 수있는 파일이 하나만있을 수 있습니까? 가능하다면 어떻게 할 것인가?

일반적으로 DLL을 외부에두고 설치 프로그램이 모든 것을 처리하도록하는 것이 멋지지만 직장에서 나에게 이것을 요청한 사람이 몇 명있어서 정직하게 알지 못합니다.


.NETZ 유틸리티를 확인하는 것이 좋습니다.이 유틸리티는 선택한 구성표로 어셈블리를 압축합니다. http://madebits.com/netz/help.php#single
Nathan Baulch

2
가능하지만 큰 실행 파일로 끝납니다 (Base64는 dll을 인코딩하는 데 사용됩니다).
Paweł Dyda

ILMerge 외에도 명령 줄 스위치를 사용하지 않으려면 ILMerge-Gui를 권장 합니다. 오픈 소스 프로젝트인데 정말 좋습니다!
tyron

2
@ PawełDyda : 원시 이진 데이터를 PE 이미지에 포함시킬 수 있습니다 ( RCDATA 참조 ). 변환이 필요하지 않거나 권장되지 않습니다.
IInspectable

답변:


761

Costura.Fody 를 사용하는 것이 좋습니다 . 어셈블리에 리소스를 포함하는 가장 쉽고 쉬운 방법입니다. NuGet 패키지로 제공됩니다.

Install-Package Costura.Fody

프로젝트에 추가하면 출력 디렉토리에 복사 된 모든 참조가 기본 어셈블리에 자동으로 포함됩니다 . 프로젝트에 대상을 추가하여 포함 된 파일을 정리할 수 있습니다.

Install-CleanReferencesTarget

또한 pdb를 포함할지, 특정 어셈블리를 제외할지 또는 어셈블리를 즉시 추출할지 지정할 수 있습니다. 내가 아는 한 관리되지 않는 어셈블리도 지원됩니다.

최신 정보

현재 일부 사람들은 DNX 지원 을 추가하려고합니다 .

업데이트 2

최신 Fody 버전의 경우 MSBuild 16 (Visual Studio 2019)이 있어야합니다. Fody 버전 4.2.1은 MSBuild 15를 수행합니다 (참조 : Fody는 MSBuild 16 이상에서만 지원됩니다. 현재 버전 : 15 )


79
이 멋진 제안에 감사드립니다. 패키지를 설치하면 완료됩니다. 기본적으로 어셈블리를 압축합니다.
Daniel

9
나도 '나'가되기를 싫어하지만 나도-이것은 많은 두통을 구했다! 추천 해 주셔서 감사합니다! 이렇게하면 단일 exe로 재배포하는 데 필요한 모든 것을 패키지 할 수 있었고 이제 원래 exe보다 작고 dll이 결합되었습니다 ... 나는 이것을 며칠 동안 만 사용했기 때문에 말할 수 없습니다. ve 그것의 속도를 거두었지만 나쁜 팝업이 나타나지 않으면 내 도구 상자에서 이것이 일반 도구가되는 것을 볼 수 있습니다. 그냥 작동합니다!
mattezell

19
춥다. 그러나 단점은 Windows에서 생성 된 어셈블리가 더 이상 모노 Linux와 바이너리 호환되지 않는다는 것입니다. 즉, 어셈블리를 Linux mono에 직접 배포 할 수 없습니다.
Tyler Long

7
사랑 스럽습니다! vs2018을 사용하는 경우 프로젝트의 루트에있는 FodyWeavers.xml 파일을 잊지 마십시오.
Alan Deep

4
마지막 설명을 보완하기 위해 다음 내용이 포함 된 FodyWeavers.xml을 프로젝트에 추가하십시오 : <? xml version = "1.0"encoding = "utf-8"?> <Weavers VerifyAssembly = "true"> <Costura /> </ Weavers>
HHenn

88

Visual Studio에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 프로젝트 속성-> 리소스-> 리소스 추가-> 기존 파일 추가…를 선택하고 아래 코드를 App.xaml.cs 또는 이와 동등한 코드에 포함하십시오.

public App()
{
    AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");

    dllName = dllName.Replace(".", "_");

    if (dllName.EndsWith("_resources")) return null;

    System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());

    byte[] bytes = (byte[])rm.GetObject(dllName);

    return System.Reflection.Assembly.Load(bytes);
}

여기 내 원래 블로그 게시물이 있습니다 : http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/


6
이 동작을 즉시 사용할 수 있습니다. 내 답변을 확인하십시오 stackoverflow.com/a/20306095/568266
Matthias

4
또한 AshRowe의 블로그에서 매우 유용한 주석에 주목하는 것이 중요합니다. 사용자 정의 테마가 설치되어 있으면 PresentationFramework.Theme 어셈블리를 해결하려고 시도합니다. AshRowe의 제안에 따라 dllName에 PresentationFramework가 포함되어 있는지 간단히 확인할 수 있습니다. if (dllName.ToLower (). Contains ( "presentationframework")) null;
YasharBahman

4
이것에 대한 두 가지 의견. 하나 : bytesnull 인지 확인 하고 그렇다면 null을 반환하십시오. 결국 dll이 리소스에 없을 수도 있습니다 . 2 : 클래스 자체에 해당 어셈블리의 "사용"이없는 경우에만 작동합니다. 커맨드 라인 도구의 경우 실제 프로그램 코드를 새 파일로 옮기고이 작업을 수행하는 작은 새 주 프로그램을 만든 다음 이전 클래스의 원래 주를 호출해야했습니다.
Nyerguds

2
이 방법의 장점은 원하는 기능을 달성하기 위해 외부 라이브러리를 설치하는 데 의존하지 않는다는 것입니다. 이 접근법의 단점은 관리되는 dll과 관련이있을 때만 유용하다는 것입니다-interop dll (적어도 테스트가 진행되는 한)은 assemblyresolve 이벤트를 발생시키지 않으며 Assembly.Load (<interbytes의 바이트 수) .dll>)은 바람직한 효과를 달성하지 못합니다. stackoverflow.com/questions/13113131/… 문제에 대한 나의 2C
XDS

3
누군가 내 문제가 발생하는 경우를 대비하여 .dll이름에 하이픈 (예 :)이 포함되어 있으면 twenty-two.dll밑줄 (예 :)로 바뀝니다 twenty_two.dll. 이 코드 행을 다음과 같이 변경할 수 있습니다.dllName = dllName.Replace(".", "_").Replace("-", "_");
Micah Vertal

87

실제로 관리되는 어셈블리 인 경우 ILMerge 를 사용할 수 있습니다 . 네이티브 DLL의 경우 좀 더해야 할 일이 있습니다.

또한 참조 : 어떻게 C ++ 윈도우는 C # 응용 프로그램 exe 인에 병합 DLL 수 있습니까?


Native DLL 병합에 관심이 있습니다. 자료가 있습니까?
Baiyan Huang


에서 @BaiyanHuang 모양 github.com/boxedapp/bxilmerge는 , 아이디어는 기본 DLL이는 "ILMerge"를 만드는 것입니다.
Artem Razin

나와 같은 VB NET 개발자 C++는 링크에서 두려워하지 않습니다 . ILMerge는 VB NET에서도 매우 쉽게 작동합니다. https://github.com/dotnet/ILMerge를 참조하십시오 . @ Shog9 감사합니다
Ivan Ferrer Villa

26

예. .NET 실행 파일을 라이브러리와 병합 할 수 있습니다. 작업을 수행하는 데 사용할 수있는 여러 도구가 있습니다.

  • ILMerge 는 여러 .NET 어셈블리를 단일 어셈블리로 병합하는 데 사용할 수있는 유틸리티입니다.
  • Mono mkbundle은 libmono가 포함 된 exe 및 모든 어셈블리를 단일 바이너리 패키지로 패키지합니다.
  • IL-Repack 은 ILMerge를 대체하는 FLOSS이며 몇 가지 추가 기능이 있습니다.

또한 이것은 사용하지 않는 코드를 제거하고 결과 어셈블리를 더 작게 만드는 Mono Linker 와 결합 될 수 있습니다 .

또 다른 가능성은 어셈블리 압축을 허용 할뿐만 아니라 dll을 exe로 직접 압축 할 수있는 .NETZ 를 사용 하는 것입니다. 위에서 언급 한 솔루션과의 차이점은 .NETZ는 솔루션을 병합하지 않고 별도의 어셈블리를 유지하지만 하나의 패키지로 압축된다는 것입니다.

.NETZ는 Microsoft .NET Framework 실행 파일 (EXE, DLL) 파일을 압축하여 압축하여 압축하는 오픈 소스 도구입니다.


NETZ는 사라진 것 같습니다
Rbjz

와우-나는 마침내 그것을 발견했다고 생각한 다음이 의견을 읽었습니다. 완전히 사라진 것 같습니다. 포크가 있습니까?
Mafii

글쎄, 그것은 단지 GitHub로 옮겨졌고 더 이상 웹 사이트에 연결되어 있지 않습니다. 대부분 더 이상 지원되지 않지만 여전히 있습니다. 링크를 업데이트했습니다.
Bobby

20

어셈블리에 관리 코드 만있는 경우 ILMerge 는 어셈블리를 하나의 단일 어셈블리로 결합 할 수 있습니다. 명령 줄 앱을 사용하거나 exe에 대한 참조를 추가하고 프로그래밍 방식으로 병합 할 수 있습니다. GUI 버전의 경우 Eazfuscator.Netz가 모두 무료입니다. 유료 앱에는 BoxedAppSmartAssembly가 포함됩니다. .

관리되지 않는 코드로 어셈블리를 병합해야하는 경우 SmartAssembly를 제안 합니다. 나는 SmartAssembly 와 다른 문제 가 없었습니다 . 여기에서 필요한 종속성을 기본 exe에 리소스로 포함시킬 수 있습니다.

dll을 리소스에 포함시킨 다음 AppDomain의 Assembly에 의존하여 어셈블리가 관리되거나 혼합 모드 인 경우 걱정할 필요없이이 모든 작업을 수동으로 수행 할 수 있습니다 ResolveHandler. 관리되지 않는 코드가있는 어셈블리와 같은 최악의 경우를 채택함으로써 원 스톱 솔루션입니다.

static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
    {
        string assemblyName = new AssemblyName(args.Name).Name;
        if (assemblyName.EndsWith(".resources"))
            return null;

        string dllName = assemblyName + ".dll";
        string dllFullPath = Path.Combine(GetMyApplicationSpecificPath(), dllName);

        using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
        {
            byte[] data = new byte[stream.Length];
            s.Read(data, 0, data.Length);

            //or just byte[] data = new BinaryReader(s).ReadBytes((int)s.Length);

            File.WriteAllBytes(dllFullPath, data);
        }

        return Assembly.LoadFrom(dllFullPath);
    };
}

여기서 핵심은 바이트를 파일에 쓰고 해당 위치에서로드하는 것입니다. 닭고기와 달걀 문제를 피하려면 어셈블리에 액세스하기 전에 핸들러를 선언하고로드 (어셈블리 해결) 부품 내부에서 어셈블리 멤버에 액세스하거나 어셈블리를 처리해야하는 항목을 인스턴스화하지 않아야합니다. 또한 GetMyApplicationSpecificPath()임시 파일이 다른 프로그램이나 자신에 의해 삭제 될 수 있기 때문에 임시 디렉토리가 아닌지 확인 하십시오 (프로그램이 dll에 액세스하는 동안 삭제되지는 않지만 최소한 성가신 것입니다) 위치). 또한 매번 바이트를 작성해야한다는 것을 주목하십시오 .dll이 이미 존재하는 위치에서로드 할 수 없습니다.

관리되는 dll의 경우 바이트를 쓸 필요는 없지만 dll의 위치에서 직접로드하거나 바이트를 읽고 메모리에서 어셈블리를로드하면됩니다. 이와 같이 :

    using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
    {
        byte[] data = new byte[stream.Length];
        s.Read(data, 0, data.Length);
        return Assembly.Load(data);
    }

    //or just

    return Assembly.LoadFrom(dllFullPath); //if location is known.

어셈블리가 완전히 관리되지 않는 경우 해당 dll을로드하는 방법에 대한이 링크 또는 링크를 볼 수 있습니다 .


리소스의 "빌드 작업"을 "내장 리소스"로 설정해야합니다.
Mavamaarten

@Mavamaarten 반드시 그런 것은 아닙니다. 프로젝트의 Resources.resx에 미리 추가 된 경우에는 그렇게 할 필요가 없습니다.
Nyerguds

2
EAZfuscator는 현재 상용입니다.
Telemat

16

Jeffrey Richter발췌 내용 은 매우 좋습니다. 요컨대, 라이브러리를 임베디드 리소스로 추가하고 다른 것보다 콜백을 추가하십시오. 여기 콘솔 응용 프로그램의 Main 메서드 시작 부분에 넣은 코드 버전 (자신의 페이지 주석에 있음)이 있습니다 (라이브러리를 사용하는 모든 호출이 Main과 다른 방법인지 확인하십시오).

AppDomain.CurrentDomain.AssemblyResolve += (sender, bargs) =>
        {
            String dllName = new AssemblyName(bargs.Name).Name + ".dll";
            var assem = Assembly.GetExecutingAssembly();
            String resourceName = assem.GetManifestResourceNames().FirstOrDefault(rn => rn.EndsWith(dllName));
            if (resourceName == null) return null; // Not found, maybe another handler will find it
            using (var stream = assem.GetManifestResourceStream(resourceName))
            {
                Byte[] assemblyData = new Byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);
                return Assembly.Load(assemblyData);
            }
        };

1
조금 바꿔서 일을 했어요, tnx buddy!
Sean Ed-Man

libz.codeplex.com 프로젝트 는이 프로세스를 사용하지만 이벤트 처리기 관리와 같은 다른 작업도 수행하고 " 관리되는 확장 성 프레임 워크 카탈로그 "(이 프로세스 자체 가 중단됨) 를 위반하지 않는 특수 코드도 있습니다.
Scott Chamberlain

대단해 !! 감사합니다 @ 스티브
Ahmer 아프

14

의 @Bobby의 asnwer 를 확장하십시오 . IL-Repack 을 사용 하여 빌드 할 때 모든 파일을 단일 어셈블리로 자동 패키지 하도록 .csproj를 편집 할 수 있습니다 .

  1. 다음과 같이 너겟 ILRepack.MSBuild.Task 패키지를 설치하십시오 Install-Package ILRepack.MSBuild.Task
  2. .csproj의 AfterBuild 섹션을 편집하십시오.

다음은 ExampleAssemblyToMerge.dll을 프로젝트 출력에 병합하는 간단한 샘플입니다.

<!-- ILRepack -->
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">

   <ItemGroup>
    <InputAssemblies Include="$(OutputPath)\$(AssemblyName).exe" />
    <InputAssemblies Include="$(OutputPath)\ExampleAssemblyToMerge.dll" />
   </ItemGroup>

   <ILRepack 
    Parallel="true"
    Internalize="true"
    InputAssemblies="@(InputAssemblies)"
    TargetKind="Exe"
    OutputFile="$(OutputPath)\$(AssemblyName).exe"
   />
</Target>

1
IL-Repack의 구문이 변경되었습니다. 연결된 github 저장소 ( github.com/peters/ILRepack.MSBuild.Task ) 에있는 README.md를 확인하십시오 . 이 방법은 나를 위해 일한 유일한 방법 이었으므로 와일드 카드를 사용하여 포함하려는 모든 dll과 일치시킬 수있었습니다.
Seabass77

8

DLL을 포함 된 리소스로 추가 한 다음 시작할 때 프로그램이 응용 프로그램 디렉토리에 압축을 풀도록 할 수 있습니다 (이미 있는지 확인한 후).

그러나 설치 파일은 너무 쉽게 만들 수 있으므로 이것이 가치가 있다고 생각하지 않습니다.

편집 :이 기술은 .NET 어셈블리를 사용하면 쉽습니다. .NET이 아닌 DLL을 사용하면 훨씬 더 많은 작업을 수행 할 수 있습니다 (파일의 압축을 풀고 등록하는 위치를 파악해야 함).


: 여기 당신은이 작업을 수행하는 방법을 설명하는 좋은 기사가 codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource
푸른 빛이 도는

8

SmartAssembly.com의이 제품을 우아하게 처리 할 수있는 다른 제품이 SmartAssembly 입니다. 이 제품은 모든 종속성을 단일 DLL에 병합 할뿐만 아니라 (선택적으로) 코드를 난독 처리하고 추가 메타 데이터를 제거하여 결과 파일 크기를 줄이며 실제로 IL을 최적화하여 런타임 성능을 향상시킬 수 있습니다.

또한 소프트웨어에 유용한 일종의 전역 예외 처리 /보고 기능이 있습니다 (원하는 경우). 나는 또한 커맨드 라인 API를 가지고 있다고 생각하므로 빌드 프로세스의 일부로 만들 수 있습니다.


7

ILMerge 접근 방식이나 Lars Holm Jensen의 AssemblyResolve 이벤트 처리는 플러그인 호스트에서 작동하지 않습니다. 실행 파일 H가 어셈블리 P를 동적으로 로드 하고 별도의 어셈블리에 정의 된 인터페이스 IP 를 통해 액세스합니다 . IPH에 포함 시키려면 Lars의 코드를 약간 수정해야합니다.

Dictionary<string, Assembly> loaded = new Dictionary<string,Assembly>();
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{   Assembly resAssembly;
    string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");
    dllName = dllName.Replace(".", "_");
    if ( !loaded.ContainsKey( dllName ) )
    {   if (dllName.EndsWith("_resources")) return null;
        System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
        byte[] bytes = (byte[])rm.GetObject(dllName);
        resAssembly = System.Reflection.Assembly.Load(bytes);
        loaded.Add(dllName, resAssembly);
    }
    else
    {   resAssembly = loaded[dllName];  }
    return resAssembly;
};  

동일한 어셈블리를 해결하고 새 인스턴스를 만드는 대신 기존 어셈블리를 반환하려는 반복 된 시도를 처리하는 트릭입니다.

편집 : .NET의 직렬화를 망칠 수 있도록 포함되지 않은 모든 어셈블리에 대해 null을 반환하여 표준 동작으로 기본 설정하십시오. 다음과 같은 방법으로 이러한 라이브러리 목록을 얻을 수 있습니다.

static HashSet<string> IncludedAssemblies = new HashSet<string>();
string[] resources = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
for(int i = 0; i < resources.Length; i++)
{   IncludedAssemblies.Add(resources[i]);  }

전달 된 어셈블리가에 속하지 않으면 null을 반환합니다 IncludedAssemblies.


댓글이 아닌 답변으로 게시 해 주셔서 죄송합니다. 나는 다른 사람의 답변에 대해 의견을 말할 권리가 없습니다.
Ant_222

5

.NET Core 3.0은 기본적으로 단일 .exe 로의 컴파일을 지원합니다.

이 기능은 프로젝트 파일 (.csproj)에서 다음 속성을 사용하여 활성화됩니다.

    <PropertyGroup>
        <PublishSingleFile>true</PublishSingleFile>
    </PropertyGroup>

이것은 외부 도구없이 수행됩니다.

자세한 내용 은이 질문에 대한 내 대답 참조 하십시오.


3

단순 해 보이지만 WinRar는 여러 파일을 자동 압축 풀기 실행 파일로 압축하는 옵션을 제공합니다.
구성 가능한 옵션은 최종 아이콘, 지정된 경로로 파일 추출, 추출 후 실행할 파일, 추출 중에 표시되는 팝업에 대한 사용자 정의 로고 / 텍스트, 팝업 창이 전혀 없음, 라이센스 계약 텍스트 등입니다.
경우에 따라 유용 할 수 있습니다 . .


Windows 자체에는 iexpress라는 유사한 도구가 있습니다. 튜토리얼은 다음과 같습니다
Ivan Ferrer Villa

2

.vbs 스크립트에서 호출 된 csc.exe 컴파일러를 사용합니다.

xyz.cs 스크립트에서 지시문 뒤에 다음 행을 추가하십시오 (내 예제는 Renci SSH에 대한 것임).

using System;
using Renci;//FOR THE SSH
using System.Net;//FOR THE ADDRESS TRANSLATION
using System.Reflection;//FOR THE Assembly

//+ref>"C:\Program Files (x86)\Microsoft\ILMerge\Renci.SshNet.dll"
//+res>"C:\Program Files (x86)\Microsoft\ILMerge\Renci.SshNet.dll"
//+ico>"C:\Program Files (x86)\Microsoft CAPICOM 2.1.0.2 SDK\Samples\c_sharp\xmldsig\resources\Traffic.ico"

ref, res 및 ico 태그는 csc 명령을 형성하기 위해 아래의 .vbs 스크립트에 의해 선택됩니다.

그런 다음 Main에 어셈블리 확인자 호출자를 추가하십시오.

public static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    .

... 그리고 클래스 어딘가에 리졸버 자체를 추가하십시오.

    정적 어셈블리 CurrentDomain_AssemblyResolve (객체 발신자, ResolveEventArgs 인수)
    {
        String resourceName = new AssemblyName (args.Name) .Name + ".dll";

        (var stream = Assembly.GetExecutingAssembly (). GetManifestResourceStream (resourceName)) 사용
        {
            바이트 [] assemblyData = 새로운 바이트 [stream.Length];
            stream.Read (assemblyData, 0, assemblyData.Length);
            반환 Assembly.Load (assemblyData);
        }

    }

.cs 파일 이름과 일치하도록 vbs 스크립트의 이름을 지정합니다 (예 : ssh.vbs는 ssh.cs를 찾습니다). 이렇게하면 스크립트를 여러 번 쉽게 실행할 수 있지만 나와 같은 바보가 아닌 경우 일반 스크립트는 끌어서 놓기에서 대상 .cs 파일을 선택할 수 있습니다.

    희미한 이름 _, oShell, fso
    oShell = CreateObject ( "Shell.Application") 설정
    fso = CreateObject ( "Scripting.fileSystemObject") 설정

    '대상 파일 이름으로 VBS 스크립트 이름을 가져옵니다.
    '##############################################
    name_ = 분할 (wscript.ScriptName, ".") (0)

    '.CS 파일에서 외부 DLL 및 아이콘 이름 가져 오기
    '############################################## ######
    Const OPEN_FILE_FOR_READING = 1
    objInputFile = fso.OpenTextFile (name_ & ".cs", 1) 설정

    '배열로 모든 것을 읽으십시오
    '#############################
    inputData = 분할 (objInputFile.ReadAll, vbNewline)

    입력 데이터의 각 strData에 대해

        left (strData, 7) = "// + ref>"이면 
            csc_references = csc_references & "/ reference :"& trim (replace (strData, "// + ref>", "")) & ""
        경우 종료

        left (strData, 7) = "// + res>"이면 
            csc_resources = csc_resources & "/ resource :"& trim (replace (strData, "// + res>", "")) & ""
        경우 종료

        left (strData, 7) = "// + ico>"이면 
            csc_icon = "/ win32icon :"& trim (replace (strData, "// + ico>", "")) & ""
        경우 종료
    다음

    objInputFile.Close


    '파일을 합치다
    '################
    oShell.ShellExecute "c : \ windows \ microsoft.net \ framework \ v3.5 \ csc.exe", "/ warn : 1 / target : exe"& csc_references & csc_resources & csc_icon & ""& name_ & ".cs" , "", "runas", 2


    WScript. 종료 (0)

0

C #에서 하이브리드 네이티브 / 관리 어셈블리를 만드는 것은 가능하지만 쉽지는 않습니다. Visual C ++ 컴파일러는 다른 것만 큼 쉽게 하이브리드 어셈블리를 만들 수 있으므로 C ++을 사용하는 것이 훨씬 쉬웠습니다.

하이브리드 어셈블리를 생성하기 위해 엄격한 요구 사항이 없으면 C #과 관련하여 실제로 문제가되지 않는다는 MusiGenesis에 동의합니다. 필요한 경우 대신 C ++ / CLI로 이동하십시오.


0

일반적으로 설명하는 것처럼 어셈블리 병합을 수행하려면 빌드 후 형태의 도구가 필요합니다. Eazfuscator (eazfuscator.blogspot.com/)라는 무료 도구는 어셈블리 병합을 처리하는 바이트 코드 맹 글링을 위해 설계되었습니다. Visual Studio를 사용하여 빌드 후 명령 줄에 이것을 추가하여 어셈블리를 병합 할 수 있지만, 마일리지는 트라이 벌이 아닌 어셈블리 병합 시나리오에서 발생할 수있는 문제로 인해 달라질 수 있습니다.

NANT가 빌드 후 어셈블리를 병합 할 수있는 능력을 가지고 있는지 확인할 수도 있지만 기능이 내장되어 있는지 여부를 말할 수는 없습니다.

응용 프로그램 빌드의 일부로 어셈블리 병합을 수행하는 많은 Visual Studio 플러그인도 있습니다.

또는 자동으로 수행 할 필요가없는 경우 .net 어셈블리를 단일 파일로 병합하는 ILMerge와 같은 여러 도구가 있습니다.

어셈블리를 병합 할 때 가장 큰 문제는 비슷한 네임 스페이스를 사용하는 것입니다. 또는 더 나쁜 것은 동일한 dll의 다른 버전을 참조하십시오 (내 문제는 일반적으로 NUnit dll 파일과 관련이 있습니다).


1
Eazfuscator는 IlMerge, AFAIK에 전화 할 것입니다.
Bobby

바비 +1 나는 그것을 기억해야했다. Eazfucator가 수행하는 모든 작업은 일반적인 구성 파일을 사용하여 ILMerge에 대한 실제 호출을 추상화합니다.
wllmsaccnt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.