it-swarm-tr.com

Bir C++ pencereleri nasıl bir C # uygulaması exe ile birleştirilebilir?

Veri g/Ç için bir C++ dll kullanan bir Windows C # program var. Amacım, uygulamayı tek bir EXE olarak dağıtmak.

Böyle bir yürütülebilir dosyayı oluşturma adımları nelerdir?

32
Noah

Yönetilen ve Yönetilmeyen Kodun Tek Meclis Dağıtımı 4 Şubat 2007 Pazar

.NET geliştiricileri XCOPY dağıtımına bayılır. Ve onlar tek Meclis bileşenlerini severler. En azından her zaman kendimi biraz tedirgin hissediyorum, eğer bir bileşen kullanmam gerekiyorsa ve o bileşenin ana Meclisine dahil edilecek bir dosya listesini hatırlamam gerekiyorsa. Bu yüzden yakın zamanda bir yönetilen kod bileşeni geliştirmek zorunda kaldığımda ve bunu bir C DLL 'den yönetilmeyen bir kodla arttırmak zorunda kaldığımda (bu konuda bana yardımcı oldukları için Marcus Heege' e teşekkür ederim!), Nasıl daha kolay hale getirebileceğimi düşündüm. iki DLL dağıtın. Bu sadece iki derleme olsaydı, onları bir dosyaya koymak için ILmerge kullanabilirdim. Ancak bu, yönetilen ve yönetilmeyen DLL'lerle karışık kod bileşenleri için çalışmaz.

İşte size bir çözüm için geldiğim şey:

Bileşenimin ana Meclisi ile gömülü kaynaklar olarak dağıtmak istediğim DLL'leri dahil ediyorum. Sonra aşağıdaki DLL'leri çıkarmak için bir sınıf kurucusu kurdum. Sınıf kurucusu her AppDomain içinde sadece bir kez çağrılıyor, bu yüzden ihmal edilebilir bir ek yük, sanırım.

namespace MyLib
{
    public class MyClass
    {
        static MyClass()
        {
            ResourceExtractor.ExtractResourceToFile("MyLib.ManagedService.dll", "managedservice.dll");
            ResourceExtractor.ExtractResourceToFile("MyLib.UnmanagedService.dll", "unmanagedservice.dll");
        }

        ...

Bu örnekte, biri yönetilmeyen kod DLL'si, biri yönetilen kod DLL (yalnızca tanıtım amaçlı) olan ve bu tekniğin her iki tür kod için de nasıl çalıştığını göstermek için kaynak olarak iki DLL dahil ettim.

DLL dosyaları kendi dosyalarına ayıklamak için kod basit:

public static class ResourceExtractor
{
    public static void ExtractResourceToFile(string resourceName, string filename)
    {
        if (!System.IO.File.Exists(filename))
            using (System.IO.Stream s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
                {
                    byte[] b = new byte[s.Length];
                    s.Read(b, 0, b.Length);
                    fs.Write(b, 0, b.Length);
                }
    }
}

Yönetilen bir kodla çalışmak Böyle bir derleme, her zamanki gibi aynı - neredeyse. Başvurana (burada: ManagedService.dll) bileşeninizin ana projesinde (burada: MyLib) var, ancak Yerel Kopyala özelliğini false olarak ayarlayın. Ek olarak, Mecliste Mevcut Bir Öğe olarak bağlantı kurar ve Eylem Oluşturmayı Gömülü Kaynağa ayarlarsınız.

Yönetilmeyen kod için (burada: UnmanagedService.dll), DLL içinde bir Mevcut Öğe olarak bağlamanız ve Oluşturma Eylemini Gömülü Kaynağa ayarlamanız yeterlidir. İşlevlerine erişmek için, her zamanki gibi DllImport özelliğini kullanın, örn.

[DllImport("unmanagedservice.dll")] public extern static int Add(int a, int b);

Bu kadar! Statik ctor ile sınıfın ilk örneğini oluşturduğunuz anda gömülü DLL'ler kendi dosyalarına alınır ve ayrı dosyalar olarak dağıtmışsınız gibi kullanıma hazırdır. Yürütme dizini için yazma izniniz olduğu sürece, bu sizin için iyi sonuç vermelidir. En azından prototipik kod için bu tek Derleme dağıtımının bu şekilde oldukça uygun olduğunu düşünüyorum.

Keyfini çıkarın!

http://weblogs.asp.net/ralfw/archive/2007/02/04/single-Assembly-deployment-of-managed-and-unmanaged-code.aspx

16
Nick

Deneyin boxedapp ; tüm DLL'leri bellekten yüklemeye izin verir. Ayrıca, .net çalışma zamanını bile gömebilirsiniz. Gerçekten bağımsız uygulamalar oluşturmak için iyi ...

3
Art

Projenizi Visual Studio'da sağ tıklayın, Proje Özellikleri -> Kaynaklar -> Kaynak Ekle -> Mevcut Dosya Ekle… Öğelerini seçin ve aşağıdaki kodu Uygulama.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 benim orijinal blog yazısı: http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-Assembly/

1
Lars Holm Jensen

Fody.Costura nuget kullanın.

  1. Çözümünüzü açın -> Proje -> Nuget Paketlerini Yönetin
  2. Fody.Costura 'yı ara
  3. Derle sizin proje

Bu kadar !

Kaynak: http://www.manuelmeyer.net/2016/01/net-power-tip-10-merging-assemblies/

1
automan

ILMerge'i denediniz mi? http://research.Microsoft.com/~mbarnett/ILMerge.aspx

ILMerge, birden çok .NET derlemesini tek bir derlemede birleştirmek için kullanılabilecek bir yardımcı programdır. Microsoft .NET Framework Geliştirici Merkezi'ndeki Araçlar ve Yardımcı Programlar sayfasından serbestçe kullanılabilir. 

C++ DLL /clr bayrağıyla (kısmen veya tamamen C++/CLI) oluşturuyorsanız, çalışması gerekir:

ilmerge /out:Composite.exe MyMainApp.exe Utility.dll

Ancak, sıradan (yerel) bir Windows DLL ile çalışmaz. 

1
Raithlin

Akıllı Montaj bunu ve daha fazlasını yapabilir. Eğer dll'iniz yönetilmeyen bir kod içeriyorsa, borçları tek bir Meclis ile birleştirmenize izin vermez, bunun yerine gerekli bağımlılıkları ana exe'nize kaynak olarak gömebilirsiniz. Flip-side, özgür değil.

Bunu dll'yi kaynaklarınıza katıştırarak ve ardından AppDomain's Assembly ResolveHandler işlevine dayanarak elle yapabilirsiniz. Karışık mod ödevleri söz konusu olduğunda, benim için çalışmayan ResolveHandler yaklaşımının çeşitlerini ve lezzetlerini buldum (hepsi dll byte'ını belleğe okur ve ondan okur). Hepsi yönetilen işler için çalıştı. İşte benim için çalıştı ne:

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 bulunduğu yerden yüklemek. Tavuk ve Yumurta probleminden kaçınmak için, Montaj'a erişmeden önce işleyiciyi ilan ettiğinizden ve Montaj (Montajın çözülmesi) bölümünün içinde Montaj üyelerine (veya Montaj ile ilgilenmesi gereken herhangi bir şeyi başlatmayacağınız) bildirdiğinizden emin olmalısınız. Ayrıca, GetMyApplicationSpecificPath() dosyasının herhangi bir geçici dizin olmadığından emin olun; çünkü geçici dosyalar diğer programlar veya kendiniz tarafından silinmeye çalışılabilir (programınız dll'ye erişirken silinmeyecek, ancak en azından bir sıkıntısı silinecek. iyi konum). Ayrıca, her seferinde baytları yazmanız gerektiğine dikkat edin, konumdan yükleme yapamazsınız çünkü dll zaten oradadır.

Meclis tamamen yönetilmemişse, bu link veya this 'yi bu tür yüklerin nasıl yükleneceğini görebilirsiniz.

0
nawfal

Thinstall bir çözümdür. Yerel bir windows uygulaması için DLL öğesini ikili kaynak nesnesi olarak gömmenizi, ardından çalışma zamanına ihtiyaç duymadan çıkarmanızı öneririm.

0
titanae