سؤال

لدي ويندوز C# برنامج يستخدم C++ dll على البيانات i/o.هدفي هو نشر التطبيق واحد EXE.

ما هي الخطوات لإنشاء مثل هذه للتنفيذ ؟

هل كانت مفيدة؟

المحلول

واحد الجمعية نشر التعليمات البرمجية المدارة وغير المدارة الأحد, فبراير 4, 2007

.صافي الحب المطورين نشر XCOPY.وأنهم يحبون واحد الجمعية المكونات.على الأقل أنا دائما أشعر نوعا ما غير مستقر ، إذا لا بد لي من استخدام بعض المكونات تحتاج إلى تذكر قائمة من الملفات أيضا مع التجميع الرئيسي من هذا العنصر.حتى عندما كنت مؤخرا قد وضع التعليمات البرمجية المدارة مكون كان لزيادة مع بعض التعليمات البرمجية غير المدارة من DLL C (thx إلى ماركوس Heege لمساعدتي مع هذا!) ، فكرت كيف يمكن أن تجعل من الأسهل لنشر اثنين DLLs.إذا كانت هذه هي اثنين فقط من الجمعيات كان يمكن أن تستخدم ILmerge أن حزمة لهم في ملف واحد فقط.ولكن هذا لا يعمل من أجل خلط المكونات البرمجية المدارة وكذلك DLLs غير مدار.

حتى هنا ما جئت حتى مع الحل:

أنا وتشمل مهما دلس كنت ترغب في نشر مع المكونات الرئيسية الجمعية باعتبارها جزءا لا يتجزأ من الموارد.ثم أقوم بإعداد منشئ فئة لاستخراج تلك Dll مثل أدناه.الطبقة المنشئ يسمى مرة واحدة فقط في كل مجال حتى في neglible النفقات العامة ، على ما أعتقد.

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

        ...

في هذا المثال لقد شملت اثنين من DLLs الموارد واحد كونه التعليمات البرمجية غير المدارة DLL واحدة يجري التعليمات البرمجية المدارة DLL (فقط لأغراض العرض التوضيحي) ، لإظهار كيف تعمل هذه التقنية على حد سواء أنواع من التعليمات البرمجية.

رمز لاستخراج DLLs إلى الملفات الخاصة بهم بسيطة:

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

العمل مع التعليمات البرمجية المدارة الجمعية مثل هذا هو نفسه كالعادة - تقريبا.هل مرجع ذلك (هنا:ManagedService.dll) في مكونات المشروع الرئيسي (هنا:MyLib) ، ولكن ضبط نسخ المحلية الخاصية إلى false.بالإضافة إلى ذلك يمكنك ربط في الجمعية عنصر القائمة وتعيين بناء العمل إلى الموارد المضمنة.

للحصول على التعليمات البرمجية غير المدارة (هنا:UnmanagedService.dll) فقط الرابط في DLL مثل عنصر القائمة وتعيين بناء العمل إلى الموارد المضمنة.للوصول إلى وظائف استخدام DllImport السمة كالعادة ، على سبيل المثال

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

هذا كل شيء!بمجرد إنشاء المثيل الأول من الفصل ثابت المنشئ جزءا لا يتجزأ من دلس على استخراجها إلى الملفات الخاصة بهم و هي جاهزة للاستخدام كما لو أنك نشرت لهم كملفات منفصلة.طالما لديك أذونات الكتابة لتنفيذ هذا الدليل يجب أن تعمل بشكل جيد بالنسبة لك.على الأقل من أجل تنميط رمز أعتقد أن هذا وسيلة واحدة الجمعية نشر مريحة جدا.

استمتع!

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

نصائح أخرى

محاولة boxedapp;فإنه يسمح لتحميل جميع ملفات Dll من الذاكرة.أيضا, يبدو أن يمكنك تضمين حتى .net runtime.جيدة لخلق حقا التطبيقات المستقلة...

استخدام Fody.Costura nuget

  1. فتح الحل الخاص بك -> مشروع> إدارة الحزم Nuget
  2. البحث عن Fody.Costura
  3. تجميع الخاص بك المشروع.

هذا هو !

المصدر: http://www.manuelmeyer.net/2016/01/net-power-tip-10-merging-assemblies/

هل حاولت ILMerge? http://research.microsoft.com/~mbarnett/ILMerge.aspx

ILMerge هو الأداة التي يمكن استخدامها لدمج عدة .صافي الجمعيات في اجتماع واحد.وهي متاحة للاستخدام من الأدوات والمرافق الصفحة في Microsoft .NET Framework مركز المطور.

إذا كنت بناء C++ DLL مع /clr العلم (كليا أو جزئيا C++/CLI) ، ومن ثم ينبغي العمل:

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

فهو لن يعمل مع العاديين (الأم) Windows DLL ذلك.

فقط انقر بزر الماوس الأيمن فوق المشروع في Visual Studio ، اختر خصائص المشروع -> موارد> إضافة الموارد -> إضافة ملف موجود... وتشمل التعليمات البرمجية التالية إلى التطبيق الخاص بك.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/

Thinstall هو حل واحد.الأصلي تطبيق ويندوز أود أن أقترح تضمين DLL الثنائية الموارد كائن ، ثم استخراج ذلك في وقت التشغيل قبل كنت في حاجة إليها.

الذكية الجمعية يمكن أن تفعل هذا وأكثر.إذا كان dll الخاص بك لديه التعليمات البرمجية غير المدارة, لن تمكنك من دمج ملفات dll واحد الجمعية, بدلا من ذلك فإنه يمكن تضمين التبعيات الموارد الرئيسية exe.لها الجانب الآخر, وليس مجانا.

يمكنك القيام بذلك يدويا عن طريق دمج dll إلى الموارد الخاصة بك ومن ثم الاعتماد على AppDomain الجمعية ResolveHandler.عندما يتعلق الأمر إلى "وضع مختلطة" dlls وجدت العديد من المتغيرات و النكهات ResolveHandler نهج لا تعمل بالنسبة لي (كل قراءة dll بايت ذاكرة قراءة منه).أنهم جميعا يعملون من أجل تمكنت dlls.هنا هو ما عملت بالنسبة لي:

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() ليس أي دليل temp منذ الملفات المؤقتة يمكن أن يكون محاولة للحصول على محوها من قبل برامج أخرى أو من قبل نفسك (لا أنه سيتم حذفها أثناء البرنامج هو الوصول إلى dll, ولكن على الأقل مصدر إزعاج.AppData هو موقع جيد).نلاحظ أيضا أن لديك لكتابة بايت في كل مرة ، لا يمكنك التحميل من الموقع فقط لأن dll بالفعل يقيم هناك.

إذا كان التجمع هو تماما غير المدارة, يمكنك أن ترى هذا الرابط أو هذا كيفية تحميل هذه dlls.

PostBuild من Xenocode يمكن أن حزمة كل إدارة unmanged في واحد exe.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top