2010-10-05 9 views
14

मेरे पास सी # रैपर कोड है जो मूल (सी ++) डीएलएल से कार्यों को कॉल करता है। वर्तमान में, मैं सी # डीएल में एक संदर्भ जोड़ सकता हूं और 'कॉपी स्थानीय' विकल्प को सत्य पर सेट कर सकता हूं। हालांकि देशी डीएल, जो एक निर्भरता है, को संदर्भ के रूप में जोड़ा नहीं जा सकता है - इसलिए कोई 'कॉपी स्थानीय' विकल्प नहीं है।क्या बिन फ़ोल्डर में मूल डीएलएल कॉपी करने के कोई बेहतर तरीके हैं?

मैं निम्नलिखित की कोशिश की है दृष्टिकोण

  1. $(TargetFolder)

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

  2. को Libs फ़ोल्डर से देशी dll कॉपी करने के लिए देशी dll के रूप में शामिल एक के बाद निर्माण की घटनाओं का उपयोग करना परियोजना में एक मौजूदा आइटम (जोड़ें -> मौजूदा आइटम -> डीएल शामिल करें)। यह विकल्प मुझे 'कॉपी स्थानीय' विकल्प का उपयोग करने की अनुमति देता है। इस दृष्टिकोण का नकारात्मक पक्ष यह है कि डीएल हमेशा एक परियोजना आइटम के रूप में दिखाता है।

मैंने "सभी फ़ाइलें दिखाएं" की कोशिश की जिसने मुझे लिब्स फ़ोल्डर देखने की अनुमति दी। इसके बाद मैं प्रोजेक्ट में NQuantLibc.dll फ़ाइल शामिल करता हूं जिसने मुझे 'कॉपी स्थानीय' विकल्प सेट करने की अनुमति दी। हालांकि, इसने मुझे एक अप्रत्याशित परिणाम दिया। इसने एक लिब्स उपफोल्डर बनाया जिसमें बिन फ़ोल्डर (जैसे bin/debug/Libs/NQuantLibc.dll) के भीतर डीएल शामिल है। आदर्श नहीं है क्योंकि सी # डीएल देशी डीएल को सही ढंग से कॉल करने में सक्षम नहीं था क्योंकि यह वहां नहीं था।

उपरोक्त दोनों उपरोक्त विकल्प काम करते हैं। क्या बिन फ़ोल्डर में मूल डीएलएल की प्रतिलिपि बनाने के कोई बेहतर तरीके हैं जैसे कि निर्भरता हमेशा हल हो जाएगी? वैकल्पिक रूप से, क्या इस प्रकार के परिदृश्य के लिए एक अलग दृष्टिकोण है?

+0

संबंधित प्रश्न: http://stackoverflow.com/questions/126331/specifying-a-non-net- निर्भरता-in-visual-studio – Ahmad

उत्तर

20

प्रोजेक्ट का उपयोग करें + मौजूदा आइटम जोड़ें और डीएलएल का चयन करें। समाधान एक्सप्लोरर विंडो में जोड़ा गया फ़ाइल का चयन करें। प्रॉपर्टी विंडो में, कॉपी टू आउटपुट निर्देशिका सेटिंग को "नया अगर कॉपी करें" में बदलें।

+0

+1 आसान और दर्द रहित समाधान – Christian

+2

मैंने इसे एक संभव के रूप में किया है विकल्प - बिंदु 2 – Ahmad

+0

मुझे समस्या नहीं मिलती है, यह * एक प्रोजेक्ट आइटम है। यह इसके बिना नहीं चलेगा, जैसे कि कोई स्रोत कोड फ़ाइल गुम होने पर नहीं चलती है। –

1

प्रोजेक्ट में फ़ाइल के रूप में डीएल जोड़ें ("लिंक के रूप में" शायद अगर आप अभी भी किसी अन्य निर्देशिका में रहना चाहते हैं)। फिर बिल्ड एक्शन को सामग्री पर सेट करें और आउटपुट निर्देशिका में कॉपी को सही पर सेट करें।

+0

क्या यह वीएस 2010 एक्सप्रेस पर लागू होता है? मुझे 'लिंक जोड़ें' विकल्प नहीं मिल रहा है। उत्तर का शेष बिंदु 2 में वर्णित वर्णन के समान ही लगता है। क्या मैं गलत हूं? – Ahmad

+0

@ अहमद आप "जोड़ें" बटन (जोड़ें → मौजूदा आइटम ...) पर छोटे नीचे वाले तीर पर दबाकर लिंक के रूप में फ़ाइल जोड़ सकते हैं, और 'लिंक के रूप में जोड़ें' –

+0

@hmemcpy - काम नहीं कर रहे हैं । डीएलएल को बिन फ़ोल्डर में कॉपी नहीं किया जा रहा है और एक इसी अपवाद को फेंक दिया जा रहा है। – Ahmad

1

आपके द्वारा बनाए गए "Libs" फ़ोल्डर के साथ ठीक कर रहे हैं, तो आप, आपके आवेदन के लिए probing path में जोड़ने app.config फ़ाइल में निम्न जोड़कर कोशिश कर सकते हैं:

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

इस क्रम का कारण होगा DLL के लिए सभी निर्दिष्ट निर्देशिकाओं को देखने के लिए।

संपादित करें दुर्भाग्य से, यह does not impact the unmanaged DLL loading by DllImport

+0

पर मैं एसओ पर व्यस्त था कि यह पता लगाने की कोशिश क्यों कर रही थी कि अपवाद क्यों फेंका जा रहा है :(धन्यवाद। – Ahmad

3

एक बेहतर तरीका मिला। Nuget .targets फ़ाइलों को जोड़ सकता है, चुड़ैल पैकेज के निर्माण फ़ोल्डर में आपके प्रोजेक्ट में संग्रहीत किया जाता है। इस तरह से आप जहां चाहें अपने पैकेज की कुछ फाइलों को प्रत्येक पर कॉपी कर सकते हैं। निम्नलिखित उदाहरण में, मैंने कुछ गैर डॉटनेट डीएलएल को "बाइनरी" फ़ोल्डर में संग्रहीत किया है। प्रत्येक बिल्ड पर, यह जांचता है कि आउटपुट फ़ोल्डर ($ आउटपुटपाथ चर) में डीएलएल पहले ही कॉपी हो चुके हैं और यदि आवश्यक हो तो उन्हें कॉपी करें।

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> 

उदाहरण।लक्ष्य सामग्री:

<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> 
13

आपको लिंक किए गए आइटम के रूप में देशी dll जोड़ सकते हैं, और प्रयोग "कॉपी नए अगर"।
देशी डीएलएस के साथ समस्या यह है कि कभी-कभी आप प्रोजेक्ट की कॉन्फ़िगरेशन (डीबग/रिलीज या प्लेटफॉर्म) के अनुसार विभिन्न डीएलएस का उपयोग करना चाहेंगे।

आप परियोजना की .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> 

नोट प्रतिलिपि विकल्प PreserveNewest जो "कॉपी करता है, तो नए" का अर्थ है पर सेट है।

+2

यह आश्चर्यजनक है कि मुख्य लाइन विकास पैटर्न क्या होता था अब यह अजीब-गेंद है जिसे आपको मैन्युअल रूप से .csproj फ़ाइल को संपादित करना है। – zumalifeguard