سؤال

لدي رمز التفاف C# الذي يستدعي وظائف من DLL (C ++) DLL. حاليًا ، يمكنني إضافة مرجع إلى C# DLL وقضاء خيار "نسخة محلية" على TRUE. ومع ذلك ، لا يمكن إضافة DLL الأصلي ، وهو التبعية ، كمرجع - لذلك لا يوجد خيار "نسخة محلية".

لقد جربت النهج التالية

  1. باستخدام أحداث ما بعد البناء لنسخ DLL الأصلي من مجلد LIBS إلى $(TargetFolder)

    copy "$(ProjectDir)Libs\NQuantLibc.dll" "$(TargetDir)NQuantLibc.dll"

  2. تضمين DLL الأصلي كعنصر موجود في المشروع (إضافة -> العنصر الحالي -> تضمين DLL). يتيح لي هذا الخيار استخدام الخيار "نسخ محلي". الجانب السلبي لهذا النهج هو أن DLL يظهر دائمًا كعنصر مشروع.

لقد حاولت أيضًا "إظهار جميع الملفات" التي سمحت لي برؤية مجلد LIBS. أقوم بعد ذلك بتضمين ملف nquantlibc.dll في المشروع الذي سمح لي بتعيين خيار "نسخة محلية". ومع ذلك ، هذا أعطاني نتيجة غير متوقعة. قام بإنشاء مقلع LIBS الفرعي يحتوي على DLL داخل مجلد BIN (على سبيل المثال bin/debug/Libs/NQuantLibc.dll). ليست مثالية لأن C# DLL لم يتمكن من استدعاء DLL الأصلي بشكل صحيح لأنه لم يكن هناك.

كل من الخيارين أعلاه أعلاه العمل. هل هناك أي طرق أفضل لنسخ DLL الأصلي إلى مجلد BIN بحيث يتم دائمًا حل التبعية؟ بدلاً من ذلك ، هل هناك نهج مختلف لهذا النوع من السيناريو؟

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

المحلول

استخدم Project + إضافة العنصر الموجود وحدد DLL. حدد الملف المضافة في نافذة Solution Explorer. في نافذة الخصائص ، قم بتغيير النسخ إلى إعداد دليل الإخراج إلى "نسخ إذا أحدث".

نصائح أخرى

يمكنك إضافة DLL الأصلي كعنصر مرتبط ، واستخدام "انسخ إذا أحدث".
المشكلة مع DLLs الأصلية ، هي أنه في بعض الأحيان سترغب في استخدام DLLs مختلفة وفقًا لتكوين المشروع (تصحيح/إصدار أو منصة).

يمكنك تعديل .CSPROJ للمشروع وربط DLL الأصلي بشكل مشروط:

 <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
    <Content Include="..\..\bin\Win32\Release\NQuantLibc.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
 </ItemGroup>   
 <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
    <Content Include="..\..\bin\Win32\Debug\NQuantLibc_d.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
    <Content Include="..\..\bin\x64\Debug\NQuantLibc_d.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
    <Content Include="..\..\bin\x64\Release\NQuantLibc.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

ملاحظة يتم تعيين خيار النسخ على الحفظ وهو ما يعني "نسخ إذا أحدث".

وجدت طريقة أفضل. يمكن لـ Nuget إضافة ملفات .targets ، يتم تخزين الساحرة في مجلد الإنشاء للحزمة ، إلى مشروعك. بهذه الطريقة ، يمكنك نسخها في كل إنشاء بعض ملفات الحزمة الخاصة بك أينما تريد. في المثال التالي ، قمت بتخزين بعض DOTNET DLL في مجلد "الثنائيات". في كل بناء ، يتحقق مما إذا كانت DLLs قد تم نسخها بالفعل في مجلد الإخراج (متغير $ OutputPath) ونسخها إذا لزم الأمر.

محتوى Nuspec:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
        <id>Example</id>
        <version>1.0.0</version>
        <authors>Example</authors>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Example</description>
    </metadata>
    <files>
        <file src="Non-DotNet.dll" target="binaries\Non-DotNet.dll" />
        <file src="DotNet.dll" target="lib\net40\DotNet.dll" />
        <file src="Example.targets" target="build\Example.targets" />
    </files>
</package>

example.targets المحتوى:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="CopyBinaries" BeforeTargets="BeforeBuild">
        <CreateItem Include="$(MSBuildThisFileDirectory)..\binaries\**\*.*">
            <Output TaskParameter="Include" ItemName="PackageBinaries" /> 
        </CreateItem>

        <Copy SourceFiles="@(PackageBinaries)"
              DestinationFolder="$(OutputPath)"
              SkipUnchangedFiles="true"
              OverwriteReadOnlyFiles="true"
        />
    </Target>
</Project>

أضف DLL كملف في المشروع ("كرابط" ربما إذا كنت لا تزال تريد أن تتواجد في دليل آخر). ثم قم بتعيين إجراء الإنشاء على المحتوى ونسخه لإخراج الدليل إلى True.

إذا كنت موافقًا على مجلد "libs" الذي تم إنشاؤه ، فيمكنك محاولة إضافته إلى مسار التحقيق لتطبيقك ، عن طريق إضافة ما يلي في app.config ملف:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="Libs;Bin2"/>
      </assemblyBinding>
   </runtime>
</configuration>

سيؤدي ذلك إلى البحث عن وقت التشغيل في جميع الدلائل المحددة لـ DLL.

تعديل لسوء الحظ ، هذا لا يؤثر على تحميل DLL غير المدير بواسطة Dllimport.

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

xcopy /y "$(ProjectDir)\lib_$(Platform)\*.dll" "$(ProjectDir)$(OutDir)"

فقط تأكد من أن لديك مجلد لكل منصة استهداف مطلوبة ، على سبيل المثال: lib_x86, lib_x64 و ربما lib_AnyCPU

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