بناء ونشر dll على النوافذ:SxS، والبيانات وكل موسيقى الجاز

StackOverflow https://stackoverflow.com/questions/110249

  •  02-07-2019
  •  | 
  •  

سؤال

منذ VS 2005، أرى أنه ليس من الممكن ببساطة إنشاء ملف dll مقابل وقت تشغيل MS ونشرهما معًا (http://www.ddj.com/windows/184406482).أنا في حيرة شديدة من البيان، SxS وشركاه:وثائق MSDN سيئة للغاية، مع مراجع دائرية؛خاصة وأنني من محبي يونكس أكثر، أجد كل تلك المعلومات غير مفيدة.مشكلتي الأساسية هي ربط ملف dll بـ msvc9 أو msvc8:نظرًا لأن أوقات التشغيل هذه غير قابلة لإعادة التوزيع، ما هي الخطوات اللازمة لربط ونشر مثل هذا الملف؟على وجه الخصوص، كيف يتم إنشاء البيان (لا أريد mt.exe، أريد شيئًا يمكن حمله عبر المترجمين)، وكيف يتم تضمينه واستخدامه؟ماذا يعني التجميع جنبًا إلى جنب؟

في الأساس، أين يمكنني العثور على أي نوع من المواصفات بدلاً من مصطلحات MS؟

شكرًا لكل من أجاب، لقد كان هذا مفيدًا حقًا،

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

المحلول

نحن نستخدم ملف تضمين بسيط في جميع تطبيقاتنا وملفات DLL، vcmanifest.h، ثم نقوم بتعيين كافة المشاريع لتضمين ملف البيان.

vcmanifest.h

/*----------------------------------------------------------------------------*/

#if _MSC_VER >= 1400

/*----------------------------------------------------------------------------*/

#pragma message ( "Setting up manifest..." )

/*----------------------------------------------------------------------------*/

#ifndef _CRT_ASSEMBLY_VERSION
#include <crtassem.h>
#endif 

/*----------------------------------------------------------------------------*/

#ifdef WIN64
    #pragma message ( "processorArchitecture=amd64" )
    #define MF_PROCESSORARCHITECTURE "amd64"
#else
    #pragma message ( "processorArchitecture=x86" )
    #define MF_PROCESSORARCHITECTURE "x86"
#endif 

/*----------------------------------------------------------------------------*/

#pragma message ( "Microsoft.Windows.Common-Controls=6.0.0.0") 
#pragma comment ( linker,"/manifestdependency:\"type='win32' " \
                  "name='Microsoft.Windows.Common-Controls' " \
                  "version='6.0.0.0' " \
                  "processorArchitecture='" MF_PROCESSORARCHITECTURE "' " \
                  "publicKeyToken='6595b64144ccf1df'\"" )

/*----------------------------------------------------------------------------*/

#ifdef _DEBUG
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT' "         \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#else
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "              \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif

/*----------------------------------------------------------------------------*/

#ifdef _MFC_ASSEMBLY_VERSION
    #ifdef _DEBUG
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #else
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #endif
#endif /* _MFC_ASSEMBLY_VERSION */

/*----------------------------------------------------------------------------*/

#endif /* _MSC_VER */

/*----------------------------------------------------------------------------*/

نصائح أخرى

أبسط شيء تفعله:بافتراض التثبيت الافتراضي لـ VS2005، سيكون لديك مسار مثل:

C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT

اذهب، واحصل على الملفات الموجودة في مجلد redist هذا، ثم ضع الملف .manifest وmsvcr80.dll (على الأقل) في مجلد .exe الخاص بالتطبيقات.هذه الملفات، الموجودة في جذر التثبيت الخاص بك، يجب أن تمكن ملف exe الخاص بك وجميع ملفات dll المرتبطة بها، من العمل بشكل لا تشوبه شائبة دون اللجوء إلى دمج الوحدات، أو MSIs أو في الواقع أي نوع من الكشف في الوقت المناسب عن عدم تثبيت وقت التشغيل.

هنا هو دخول بلوق شرح السبب المنطقي وراء قرار SxS crt لـ VC++.ويتضمن شرحًا لمدى سوء ربط crt بشكل ثابت، ولماذا لا ينبغي عليك القيام بذلك.

هنا هو وثائق حول كيفية ربط CRT بشكل ثابت.

حسنًا، لقد واجهت بعضًا من هذه المشكلات، لذا ربما تكون بعض تعليقاتي مفيدة.

  1. البيان هو ملف XML.بينما يمكن لـ VS إنشاء واحد لك عند الترجمة، فإن الحل الآخر هو إنتاج ملف مورد (.rc) وتجميعه في ملف مورد مترجم (.res) باستخدام مترجم الموارد (rc.exe) المضمن في VS .ستحتاج إلى تشغيل سطر أوامر VS من قائمة الأدوات، مما سيؤدي إلى وجود rc في المسار، بالإضافة إلى ضبط المتغيرات البيئية المختلفة بشكل صحيح.ثم قم بتجميع الموارد الخاصة بك.يمكن استخدام الملف .res الناتج من قبل المترجمين الآخرين.
  2. تأكد من أن حجم ملف البيان xml الخاص بك قابل للقسمة على 4.أضف مسافة بيضاء في منتصفها لتحقيق ذلك إذا لزم الأمر.حاول تجنب وجود أي أحرف قبل علامة xml المفتوحة أو بعد علامة xml الختامية.لقد واجهت مشاكل في بعض الأحيان مع هذا.إذا قمت بالخطوة 2 بشكل غير صحيح، فتوقع حدوث أخطاء في التكوين جنبًا إلى جنب.يمكنك التحقق مما إذا كان هذا هو خطأك عن طريق فتح ملف exe في محرر الموارد (على سبيل المثال.devenv.exe) وفحص مورد البيان.يمكنك أيضًا رؤية مثال للبيان الصحيح بمجرد فتح ملف مدمج، مع ملاحظة أن ملفات dlls والملفات exes لها اختلافات بسيطة في المعرف الذي يجب أن يُعطى للمورد.

قد ترغب على الأرجح في إجراء اختبار على نظام التشغيل Vista للتأكد من أن هذا يعمل بشكل صحيح.

إنها قابلة لإعادة التوزيع ولديك حزم قابلة لإعادة التوزيع داخل دليل msvs.

قم بالإنشاء باستخدام وقت التشغيل الذي تختاره، وأضف الحزمة المقابلة إلى برنامج التثبيت الخاص بك ولا تهتم - فسوف يعمل.الفرق هو أنهم كذلك المثبتة في مكان مختلف الآن (ولكن هذا هو المكان الذي سيبحث فيه تطبيقك أيضًا عن المكتبات).

بخلاف ذلك، MSDN أو أي كتاب غير قديم عن برمجة Windows C++.

شكرا على الاجابة.بالنسبة للنشر في حد ذاته، يمكنني رؤية 3 خيارات، ثم:

  • باستخدام توجيه الدمج .msi.
  • استخدام حزمة VS القابلة لإعادة التوزيع وتشغيلها قبل برنامج التثبيت الخاص بي
  • نسخ القابلة لإعادة التوزيع ملفات على طول طلبي الخاص.لكن في هذه الحالة، كيف يمكنني الإشارة إليه في التسلسل الهرمي لنظام الملفات (على سبيل المثال، يشير bar/foo1/foo1.dll وbar/foo2/foo2.dll إلى msvcr90.dll في bar/)؟أعني إلى جانب ما هو واضح وقبيح "نسخ ملف dll في كل دليل يوجد به ملف dll والذي يعتمد عليه).

لا يمكنك استخدام VC++8 SP1/9 CRT كوحدة دمج على نظامي التشغيل Vista وWindows Server 2008 إذا كانت لديك خدمات تريد تشغيلها أو برامج تريد تشغيلها قبل إجراء "InstallFinalize" في MSI.

وذلك لأنه تم تثبيت ملفات dll في WinSXS في الإجراء "InstallFinalize".

لكن إجراء MSI "ServiceStart" يأتي قبل ذلك.

لذلك استخدم إما bootstrapper "http://www.davidguyer.us/bmg/publish.htm"

أو فكر في استخدام تسلسل المثبت في المثبت 4.5.ولكن هذا يعني أنك بحاجة إلى برنامج تمهيد لتثبيت الإصدار 4.5، لذا يبدو الأمر غير مجدٍ بعض الشيء.

إذا كنت تنوي نشر ملفات Microsoft DLLs/.manifest وتستخدم Java JNI، فستحتاج إلى وضعها في دليل bin الخاص بـ JDK/JRE.

إذا كنت تقوم بتشغيل التطبيق في JBoss، فستحتاج إلى وضعه في دليل JBoss/bin.

يمكنك وضع JNI DLL الخاص بك في المكان المناسب لتطبيقك.

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