DLL'leri derlenmiş bir yürütülebilir dosyaya katıştırma


618

Önceden var olan bir DLL'yi derlenmiş bir C # yürütülebilir dosyasına gömmek mümkün mü (böylece dağıtacak yalnızca bir dosyanız var)? Mümkünse, bunu nasıl yapabilirim?

Normalde, DLL'leri dışarıda bırakarak ve kurulum programını her şeyi halletmekten hoşlanıyorum, ama işte bana bunu soran birkaç insan var ve dürüstçe bilmiyorum.


Montajı da seçtiğiniz bir şema ile sıkıştıran .NETZ yardımcı programını kontrol etmenizi öneririm: http://madebits.com/netz/help.php#single
Nathan Baulch 9:08

2
Mümkün, ancak büyük yürütülebilir ile sonuçlanacak (Base64 dll kodlamak için kullanılacak).
Paweł Dyda

ILMerge'in yanı sıra , komut satırı anahtarlarıyla uğraşmak istemiyorsanız, gerçekten ILMerge-Gui'yi tavsiye ederim . Bu açık kaynaklı bir proje, gerçekten çok iyi!
tyron

2
@ PawełDyda: Ham ikili verileri PE görüntüsüne gömebilirsiniz (bkz. RCDATA ). Dönüşüm gerekmez (veya önerilir).
Şubat'ta

Yanıtlar:


761

Costura.Fody'yi kullanmanızı kesinlikle tavsiye ederim - kaynakları montajınıza dahil etmenin en iyi ve en kolay yolu. NuGet paketi olarak mevcuttur.

Install-Package Costura.Fody

Projeye ekledikten sonra, çıkış dizinine kopyalanan tüm başvuruları otomatik olarak ana derlemenize gömer . Projenize bir hedef ekleyerek katıştırılmış dosyaları temizlemek isteyebilirsiniz:

Install-CleanReferencesTarget

Ayrıca, pdb'leri dahil edip etmeyeceğinizi, belirli derlemeleri hariç tutabileceğinizi veya derlemeleri derhal çıkarabileceğinizi de belirtebilirsiniz. Bildiğim kadarıyla, yönetilmeyen meclisler de destekleniyor.

Güncelleme

Şu anda, bazı insanlar DNX için destek eklemeye çalışıyor .

Güncelleme 2

En son Fody sürümü için MSBuild 16 (Visual Studio 2019) gereklidir. Fody sürüm 4.2.1, MSBuild 15 yapacak. (Başvuru: Fody, yalnızca MSBuild 16 ve üstü sürümlerde desteklenir. Geçerli sürüm: 15 )


79
Bu harika öneri için teşekkür ederim. Paketi yükleyin ve işiniz bitti. Hatta montajları varsayılan olarak sıkıştırır.
Daniel

9
'Ben de' olmaktan nefret ediyorum, ama ben de - bu beni çok fazla baş ağrısından kurtardı! Tavsiye için teşekkürler! Bu, tek bir exe'ye yeniden dağıtmak için ihtiyacım olan her şeyi paketlememi sağladı ve şimdi orijinal exe ve dll'lerin birleştirildiğinden daha küçük ... Bunu sadece birkaç gündür kullanıyorum, bu yüzden diyemem ' adım adım koydum, ancak kötü bir şey ortaya çıkardığında, bunun araç kutumda düzenli bir araç olduğunu görebiliyorum. Sadece çalışıyor!
mattezell

19
Serin. Ancak bir dezavantaj var: Windows'da oluşturulan derleme artık mono Linux ile ikili olarak uyumlu değil. Bu, derlemeyi doğrudan Linux mono üzerine dağıtamayacağınız anlamına gelir.
Tyler Long

7
Bu çok hoş! Vs2018 kullanıyorsanız, projenizin kök dizininde bulunan FodyWeavers.xml dosyasını unutmayın.
Alan Deep

4
Son yoruma ek olarak: projenize aşağıdaki içeriğe sahip FodyWeavers.xml dosyasını ekleyin: <? Xml version = "1.0" encoding = "utf-8"?> <Weavers VerifyAssembly = "true"> <Costura /> </Weavers>
HHenn

88

Visual Studio'da projenizi sağ tıklatın, Proje Özellikleri -> Kaynaklar -> Kaynak Ekle -> Mevcut Dosya Ekle… 'yi seçin ve aşağıdaki kodu App.xaml.cs veya eşdeğerinize ekleyin.

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);
}

İşte orijinal blog yazım: http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/


6
Bu davranışı kutudan çıkarabilirsiniz. Cevabımı kontrol et stackoverflow.com/a/20306095/568266
Matthias

4
Ayrıca, AshRowe'dan blogunuzda İNANILMAZ yararlı bir notu not etmek de önemlidir: Yüklü özel bir temanız varsa, çöküp yanan ve yakan PresentationFramework.Theme montajını çözmeye çalışacaktır! AshRowe'nin önerisine göre, dllName öğesinin böyle PresentationFramework içerip içermediğini kontrol edebilirsiniz: if (dllName.ToLower (). Contains ("Presentationframework")) null döndürür;
YasharBahman

4
Bu konuda iki yorum. Bir: bytesboş olup olmadığını kontrol etmelisiniz ve eğer öyleyse, orada boş döndürün. Sonuçta, dll kaynaklarda değil mümkündür . İki: Bu sadece o sınıfın kendisinde bu derlemeden herhangi bir şey için "kullanma" yoksa çalışır. Komut satırı araçları için, gerçek program kodumu yeni bir dosyaya taşımak ve bunu yapan ve daha sonra eski sınıftaki orijinal ana kodu çağıran küçük bir yeni ana program yapmak zorunda kaldım.
Nyerguds

2
Bu yaklaşımın tersi, istenen işlevselliği elde etmek için herhangi bir harici libs kurmaya dayanmamasıdır. Bu yaklaşımın dezavantajı, yalnızca yönetilen dll'ler söz konusu olduğunda yararlı olmasıdır - birlikte çalışma dll'leri (en azından benim testim kadarıyla) assemblyresolve olayını başlatmazlar ve Assembly.Load (<bazı bazı birlikte çalışmaların baytları) .dll>) yolda istenen etkiyi elde edemez. stackoverflow.com/questions/13113131/… Bu konuda sadece 2c
XDS

3
Herkes benim sorunumla karşılaşırsa: .dlladı herhangi bir tire (yani twenty-two.dll) içeriyorsa , bunlar da bir alt çizgi (yani twenty_two.dll) ile değiştirilecektir . Bu kod satırını şu şekilde değiştirebilirsiniz:dllName = dllName.Replace(".", "_").Replace("-", "_");
Micah Vertal

87

Gerçekten yönetilen derlemeler varsa, ILMerge'yi kullanabilirsiniz . Yerel DLL'ler için, yapmak için biraz daha işiniz olacak.

Ayrıca bkz: Nasıl bir C ++ windows dll bir C # uygulama exe birleştirilebilir?


Yerel DLL birleştirme ile ilgileniyorum, herhangi bir malzeme var mı?
Baiyan Huang


En @BaiyanHuang göz github.com/boxedapp/bxilmerge , fikri yerli Dll'lerin için "ILMerge" yapmaktır.
Artem Razin

Benim gibi VB NET geliştiricileri C++bu bağlantıdan korkmuyorlar . ILMerge, VB NET için de çok kolay çalışıyor. Bkz . Https://github.com/dotnet/ILMerge . Shog9
Ivan Ferrer Villa

26

Evet, .NET yürütülebilir dosyalarını kitaplıklarla birleştirmek mümkündür. İşi yapmak için birden fazla araç vardır:

  • ILMerge , birden çok .NET derlemesini tek bir derlemede birleştirmek için kullanılabilen bir yardımcı programdır.
  • Mono mkbundle , bir exe ve libmono ile tüm montajları tek bir ikili pakete paketler.
  • IL-Repack , bazı ek özelliklere sahip ILMerge'ye alternatif bir FLOSS'tur.

Ek olarak , kullanılmayan kodu kaldıran Mono Linker ile birleştirilebilir ve bunun sonucunda oluşan montaj daha küçük olur.

Başka bir olasılık, sadece bir montajın sıkıştırılmasına izin vermekle kalmaz, aynı zamanda dll'leri doğrudan exe'ye paketleyebilen .NETZ'yi kullanmaktır . Yukarıda belirtilen çözümlerin farkı, .NETZ'nin bunları birleştirmemesi, ayrı montajlar halinde kalmaları ancak tek bir pakette paketlenmesidir.

.NETZ, Microsoft .NET Framework yürütülebilir (EXE, DLL) dosyalarını daha küçük yapmak için sıkıştırıp paketleyen açık kaynaklı bir araçtır.


NETZ gitmiş gibi görünüyor
Rbjz

Vay canına - sonunda bulduğumu sanıyordum, sonra bu yorumu okudum. Tamamen gitmiş gibi görünüyor. Çatal var mı?
Mafii

Sadece GitHub'a taşındı ve artık web sitesine bağlı değil ... bu yüzden "tamamen gitti" abartılı bir şey. Büyük olasılıkla artık desteklenmiyor, ancak hala orada. Bağlantıyı güncelledim.
Bobby

20

ILMerge , montajın yalnızca yönetilen kodu olması koşuluyla, montajları tek bir montajda birleştirebilir. Komut satırı uygulamasını kullanabilir veya exe'ye başvuru ekleyebilir ve programlı olarak birleştirebilirsiniz. Bir GUI sürümü için orada Eazfuscator zamanda ve .Netz ikisi de serbesttir. Ücretli uygulamalar BoxedApp ve SmartAssembly içerir .

Derlemeleri yönetilmeyen kodla birleştirmeniz gerekiyorsa, SmartAssembly öneririm . SmartAssembly ile hiç bir zaman hıçkırık yapmadım ama diğerleriyle. Burada, gerekli bağımlılıkları ana exe'nize kaynak olarak yerleştirebilir.

Tüm bu manuel olarak derleme yönetilen veya karışık modda dll kaynaklarınıza gömmek ve sonra AppDomain's Assembly güvenerek endişelenmenize gerek yok elle yapabilirsiniz ResolveHandler. Bu, en kötü durumun, yani yönetilmeyen koda sahip montajların benimsenmesiyle tek durak bir çözümdür.

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);
    };
}

Buradaki anahtar, baytları bir dosyaya yazmak ve konumundan yüklemek. Tavuk ve yumurta probleminden kaçınmak için, montaja erişmeden önce işleyiciyi bildirdiğinizden ve yükleme (montaj çözme) parçasının içindeki montaj elemanlarına erişmediğinizden (veya montajla ilgilenmesi gereken herhangi bir şeyi başlattığınızdan) emin olmalısınız. Ayrıca GetMyApplicationSpecificPath()geçici dosyalar diğer programlar veya kendiniz tarafından silinmeye çalışılacağı için herhangi bir geçici dizin olmadığından emin olun (programınız dll'ye erişirken silinecektir, ancak en azından bir sıkıntı. AppData iyidir yer). Ayrıca her seferinde bayt yazmak zorunda olduğunuzu, dll zaten orada bulunduğu için konumdan yükleyemeyeceğinizi unutmayın.

Yönetilen dll için, bayt yazmanız gerekmez, ancak doğrudan dll'nin konumundan yükleyin veya sadece baytları okuyun ve derlemeyi bellekten yükleyin. Bunun gibi:

    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.

Derleme tamamen yönetilmezse, bu bağlantıyı veya bu tür dll'lerin nasıl yükleneceği ile ilgili olarak görebilirsiniz .


Kaynağın "Derleme Eylemi" nin "Katıştırılmış Kaynak" olarak ayarlanması gerektiğini unutmayın.
Mavamaarten

@Mavamaarten Mutlaka değil. Önceden projenin Resources.resx dosyasına eklenmişse, bunu yapmanız gerekmez.
Nyerguds

2
EAZfuscator artık ticari.
Telemat

16

Jeffrey Richter alıntı çok iyidir. Kısacası, kütüphanenin gömülü kaynakları olarak ekleyin ve her şeyden önce bir geri arama ekleyin. İşte bir konsol uygulaması için Main yönteminin başına koyduğum kodun (sayfasının yorumlarında bulunan) bir sürümü (sadece kütüphaneyi kullanan tüm çağrıların Main için farklı bir yöntemde olduğundan emin olun).

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
Biraz değişti, iş yaptı, tnx dostum!
Sean Ed-Man

Libz.codeplex.com projesi bu işlemi kullanıyor ancak sizin için olay işleyiciyi yönetme gibi bazı başka şeyler yapacak ve " Yönetilebilir Genişletilebilirlik Çerçevesi Katalogları" " (bu işlemin kendi kendine kırılacağı)
Scott Chamberlain

Bu harika!! @Steve
Ahmer Afzal

14

Yukarıdaki @ Bobby'nin asnwer'ını genişletmek . Oluşturduğunuzda tüm dosyaları otomatik olarak tek bir derleme halinde paketlemek üzere IL-Repack'i kullanmak için .csproj dosyanızı düzenleyebilirsiniz .

  1. Nuget ILRepack.MSBuild.Task paketini Install-Package ILRepack.MSBuild.Task
  2. .Csproj dosyanızın AfterBuild bölümünü düzenleyin

SampleAssemblyToMerge.dll dosyasını proje çıktısında birleştiren basit bir örnek.

<!-- 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 sözdizimi değişti, bağlantılı github deposunda bulunan README.md dosyasını kontrol edin ( github.com/peters/ILRepack.MSBuild.Task ). Bu şekilde benim için çalışan sadece biriydi ve ben dahil etmek istediğim tüm dlls maç için bir joker kullanabilirsiniz.
Seabass77

8

DLL'leri katıştırılmış kaynaklar olarak ekleyebilir ve programınızın başlangıçta uygulama dizinine açmasını sağlayabilirsiniz (zaten orada olup olmadıklarını kontrol ettikten sonra).

Kurulum dosyalarını yapmak o kadar kolay ki, buna değeceğini sanmıyorum.

EDIT: Bu teknik .NET derlemeleri ile kolay olurdu. Non..NET DLL'leri ile çok daha fazla iş olacaktır (dosyaları nerede açacağınızı ve kaydedeceğinizi bulmanız gerekir).


Burada bunun nasıl yapılacağını açıklayan harika bir makaleniz var: codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource
mavimsi

8

Bunu zarif bir şekilde ele alabilecek bir diğer ürün SmartAssembly.com'da SmartAssembly . Bu ürün, tüm bağımlılıkları tek bir DLL'de birleştirmenin yanı sıra, (isteğe bağlı olarak) kodunuzu gizler, ortaya çıkan dosya boyutunu azaltmak için fazladan meta verileri kaldırır ve ayrıca IL'yi çalışma zamanı performansını artırmak için optimize edebilir.

Ayrıca, yazılımınıza (istenirse) faydalı olabilecek bir tür küresel istisna işleme / raporlama özelliği de vardır. Ayrıca, oluşturma işleminizin bir parçası haline getirebilmeniz için bir komut satırı API'sı olduğuna inanıyorum.


7

Ne ILMerge yaklaşımı ne de Lars Holm Jensen, AssemblyResolve etkinliğini ele alması bir eklenti sunucusu için işe yaramayacaktır. Yürütülebilir H'nin derleme P'yi dinamik olarak yüklediğini ve ayrı bir derlemede tanımlanan arabirim IP'si üzerinden eriştiğini varsayalım. To gömmek IP içine H biri Lars koduyla biraz değişiklik yapmak gerekebilir zorundadır:

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;
};  

Aynı montajı çözme ve yeni bir örnek oluşturmak yerine mevcut olanı döndürme girişimlerini tekrarlama hilesi.

DÜZENLEME: .NET'in serileştirmesini bozmasın, kendinize gömülmemiş tüm derlemeler için null döndürdüğünüzden emin olun, böylece standart davranışa varsayılan olarak getirin. Bu kütüphanelerin bir listesini şu şekilde alabilirsiniz:

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

ve eğer geçen montaj ait değilse, null değerini döndürün IncludedAssemblies.


Yorum yapmak yerine cevap olarak gönderdiğim için üzgünüm. Başkalarının cevaplarına yorum yapma hakkım yok.
Ant_222

5

.NET Core 3.0 yerel olarak tek bir .exe dosyasına derlemeyi destekler

Bu özellik, proje dosyanızda (.csproj) aşağıdaki özelliğin kullanılmasıyla etkinleştirilir:

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

Bu herhangi bir harici araç olmadan yapılır.

Daha fazla ayrıntı için bu soruya verdiğim cevaba bakınız.


3

Basit gelebilir, ancak WinRar bir grup dosyayı kendi kendine ayıklanan bir yürütülebilir dosyaya sıkıştırma seçeneği sunar.
Yapılandırılabilir birçok seçenek vardır: son simge, verilen yola dosyaları çıkart, çıkarıldıktan sonra çalıştırılacak dosya, ayıklama sırasında gösterilen açılır pencere için özel logo / metinler, hiç açılır pencere yok, lisans sözleşmesi metni, vb
. .


Windows'un kendisi iexpress adlı benzer bir araca sahiptir. İşte bir öğretici
Ivan Ferrer Villa

2

Bir .vbs komut dosyasından çağrılan csc.exe derleyicisi kullanın.

Xyz.cs betiğinize, yönergelerden sonra aşağıdaki satırları ekleyin (örneğim Renci SSH içindir):

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 ve ico etiketleri, csc komutunu oluşturmak için aşağıdaki .vbs komut dosyası tarafından alınır.

Ardından, Montaj çözücü arayanını Ana Ekrana ekleyin:

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

... ve çözümleyicinin kendisini sınıfın herhangi bir yerine ekleyin:

    static Assembly CurrentDomain_AssemblyResolve (nesne göndericisi, ResolveEventArgs argümanları)
    {
        String resourceName = new AssemblyName (args.Name) .Name + ".dll";

        using (var stream = Assembly.GetExecutingAssembly (). GetManifestResourceStream (resourceName))
        {
            Byte [] assemblyData = yeni Bayt [stream.Length];
            stream.Read (assemblyData, 0, assemblyData.Length);
            Assembly.Load (assemblyData) öğesini döndürür;
        }

    }

Vs betiği .cs dosya adıyla eşleşecek şekilde adlandırıyorum (örneğin, ssh.vbs ssh.cs dosyasını arar); bu, betiği birçok kez çalıştırmayı çok daha kolay hale getirir, ancak benim gibi bir aptal değilseniz, genel bir komut dosyası hedef .cs dosyasını sürükle ve bırak yönteminden alabilir:

    Dim adı_, oShell, fso
    Set oShell = CreateObject ("Shell.Application")
    Set fso = CreateObject ("Scripting.fileSystemObject")

    'HEDEF DOSYA ADI OLARAK VBS SCRIPT ADINI ALIN
    '################################################
    name_ = Böl (wscript.ScriptName, ".") (0)

    'EXCAL DLL'leri VE SİMGESİ İSİMLERİNİ .CS DOSYASINDAN ALIN
    '################################################# ######
    Sabit OPEN_FILE_FOR_READING = 1
    ObjInputFile = fso.OpenTextFile (name_ & ".cs", 1) olarak ayarlayın

    'HER ŞEYİ BİR DÜZEYE OKUYUN
    '#############################
    inputData = Böl (objInputFile.ReadAll, vbNewline)

    Her strData In inputData için

        bırakılırsa (strData, 7) = "// + ref>" 
            csc_references = csc_references & "/ reference:" & kırpma (değiştir (strData, "// + ref>", "")) & ""
        eğer biterse

        bırakılırsa (strData, 7) = "// + res>" 
            csc_resources = csc_resources & "/ resource:" & kırpma (değiştir (strData, "// + res>", "")) & ""
        eğer biterse

        bırakılırsa (strData, 7) = "// + ico>" 
            csc_icon = "/ win32icon:" & trim (değiştir (strData, "// + ico>", "")) & ""
        eğer biterse
    Sonraki

    objInputFile.Close


    'DOSYAYI DERLEYİN
    '################
    oShell.ShellExecute "c: \ windows \ microsoft.net \ framework \ v3.5 \ csc.exe", "/ warn: 1 / target: exe" & csc_references & csc_resources & csc_icon & "" ve ad_ & ".cs" , "", "runas", 2


    WScript.Quit (0)

0

C # 'da karma yerel / yönetilen bir montaj oluşturmak mümkün ama o kadar kolay değil. Visual C ++ derleyicisi başka bir şey kadar kolay bir şekilde karma derlemeler oluşturabileceğinden, bunun yerine C ++ kullanıyor olsaydınız çok daha kolay olurdu.

Hibrit bir montaj üretmek için katı bir gereksiniminiz olmadıkça, MusiGenesis ile bu C # ile gerçekten uğraşmaya değmez. Bunu yapmanız gerekiyorsa, bunun yerine C ++ / CLI'ye geçmeye bakın.


0

Genelde, açıkladığınız gibi bir birleştirme birleştirmesi gerçekleştirmek için bir tür post derleme aracının olması gerekir. Montaj birleştirmeyi de işleyen bayt kodu yönetimi için tasarlanmış Eazfuscator (eazfuscator.blogspot.com/) adlı ücretsiz bir araç var. Bunu derlemelerinizi birleştirmek için Visual Studio ile bir derleme sonrası komut satırına ekleyebilirsiniz, ancak herhangi bir trival olmayan birleştirme senaryolarında ortaya çıkacak sorunlardan dolayı kilometreniz değişecektir.

Ayrıca, yapı NANT'ı yapmak için yapı olup olmadığını kontrol edebilirsin NANT, binadan sonra montajları birleştirme yeteneğine sahiptir, ancak işlevselliğin yerleşik olup olmadığını söylemek için kendime NANT hakkında yeterince bilgim yok.

Ayrıca uygulama oluşturmanın bir parçası olarak birleştirme birleştirmesi gerçekleştirecek birçok Visual Studio eklentisi de vardır.

Alternatif olarak, bunun otomatik olarak yapılması gerekmiyorsa, ILMerge gibi .net derlemelerini tek bir dosyada birleştirecek bir dizi araç vardır.

Birleştirme derlemelerinde yaşadığım en büyük sorun, benzer ad alanları kullanmalarıdır. Ya da daha kötüsü, aynı dll farklı sürümleri referans (benim sorunları genellikle NUnit dll dosyaları ile vardı).


1
Eazfuscator sadece AFAIK IlMerge'yi arayacak.
Bobby

+1 Bobby. Bunu hatırlamalıydım. Eazfucator sizin için yaptığı tüm hakkında daha genel bir yapılandırma dosyası ile ILMerge gerçek çağrıları soyut olduğunu.
wllmsaccnt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.