2016-09-02 8 views
12

में स्थानीय रूप से देशी निर्भरताओं की प्रतिलिपि बनाएँ मेरे पास एक मिश्रित मोड सी ++ प्रोजेक्ट है जो कुछ प्रबंधित सीएलआर वर्गों को निर्यात करने वाले प्रबंधित डीएल असेंबली का उत्पादन करता है (इसे Managed.dll पर कॉल करें)। यह प्रोजेक्ट देशी डीएलएल का उपयोग कर रहा है, (इसे Native.dll पर कॉल करें)।विजुअल स्टूडियो प्रोजेक्ट

जब मैं Client.exe का उत्पादन करने वाली किसी अन्य प्रोजेक्ट से Managed.dll का संदर्भ देता हूं, तो सब कुछ अपेक्षित कार्य करता है, सिवाय इसके कि मुझे क्लाइंट.एक्सई के समान फ़ोल्डर में Native.dll मैन्युअल रूप से कॉपी करने की आवश्यकता है।

यदि स्थानीय रूप से कॉपी करने के लिए वीएस को मनाने के लिए कोई तरीका है (क्लाइंट.एक्सई के बिन फ़ोल्डर में) न केवल Managed.dll बल्कि Native.dll भी?

मैंने मैनेजर में निर्भरता असेंबली के रूप में Native.dll को शामिल करने का प्रयास किया है, लेकिन इससे मदद नहीं मिली।

संपादित

Managed.dll एक पुनर्वितरण विधानसभा होने जा रहा है। इसे "सी: \ प्रोग्राम फ़ाइलें ....." में एक फ़ोल्डर में स्थापित किया जाएगा। जब विजुअल स्टूडियो का उपयोग करने वाला कोई डेवलपर Managed.dll का संदर्भ जोड़ता है, तो Native.dll को उसकी प्रोजेक्ट के \ bin फ़ोल्डर में भी कॉपी किया जाना चाहिए।

1.Add परियोजना का एक संसाधन के रूप में dll:

+0

शायद यह एसओ पोस्ट शीर्षक [विजुअल स्टूडियो में डीएलएल की निर्भरताओं की प्रतिलिपि बनाना] (http://stackoverflow.com/questions/1043913/copying-a-dlls- निर्भरता-in-visual-studio) मदद की जा सकती है? –

+0

मुझे डर है कि यह मेरी जरूरत नहीं है। मैं Managed.dll और Native.dll वितरित करना चाहता हूं। जब लाइब्रेरी का कोई उपयोगकर्ता Managed.dll संदर्भित करता है तो मुझे अपनी प्रोजेक्ट के बिन फ़ोल्डर में स्थानीय रूप से कॉपी की गई Native.dll की आवश्यकता होती है। – Trifon

उत्तर

8

वहाँ वी.एस. बताने के लिए गंतव्य फ़ोल्डर में DLLs कॉपी करने के लिए कई तरीके हैं। और वीएस को प्रतिलिपि बनाने के लिए बताएं यदि डीएल नया है

2. डीएलएल प्रोजेक्ट के संदर्भ में एक नई परियोजना जोड़ें, और आउटडोर को इच्छित फ़ोल्डर में सेट करें। यह प्रोजेक्ट कुछ भी नहीं करता है लेकिन डीएलएल की प्रतिलिपि बनाता है।

vcxproj फ़ाइल

5.Use vcxproj फ़ाइल

<ItemGroup> 
<CustomBuild Include="..\..\xxx.dll"> 
    <FileType>Document</FileType> 
    <Command> 
    call mkdir &quot;$(OutDir)&quot; 2&gt;nul &amp; 
    copy /Y &quot;..\..\xxx.dll&quot; &quot;$(OutDir)xxx.dll&quot; 
    </Command> 
    <Message>Copying xxx.dll to $(OutDir)\xxx.dll</Message> 
    <Outputs>$(OutDir)\xxx.dll</Outputs> 
</CustomBuild> 
</ItemGroup> 

में CustomBuild एक makefile 6.Use में vcxproj फ़ाइल

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 
    <ClCompile> 
    </ClCompile> 
    <Link> 
    </Link> 
    <PostBuildEvent> 
    <Command> 
     echo off 
     mkdir "$(ProjectDir)..\..\bin\$(Configuration)\" 
     copy "$(OutDir)xxx.dll" "$(ProjectDir)..\..\lib\$(Configuration)\" 
     echo on 
    </Command> 
    </PostBuildEvent> 
</ItemDefinitionGroup> 

में एक PostBuildEvent एक PreBuildEvent 4.Use 3.Use

और मेकफ़ाइल में डीएल कॉपी करें। और nmake का उपयोग

7.Write एक बल्ला फ़ाइल है कि प्रति काम करने का निर्माण, और के रूप में बल्लेबाजी फ़ाइल आह्वान करने के लिए 3-6

जैसे कि अजगर के रूप में

8. स्क्रिप्ट है, जो भी से dll डाउनलोड कर सकते हैं इंटरनेट। और पीई फ़ाइल को 3-6 में डालें।

ऐसे Gradle के रूप में निर्माण 9.Other उपकरण भी मदद कर सकते हैं,

10.Make यह एक NuGet प्लगइन

11.Sometimes मैं सिर्फ एक बल्ला लिखते हैं, और मैन्युअल रूप से बल्ले पर अमल।

अपडेट 01 (स्व निकालने dll उदाहरण):

1.Add आप देशी dll कामयाब dll के संसाधन

2.Add इस init() विधि के रूप में

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Reflection; 
using System.Security.Cryptography; 
using System.Text; 
using System.Threading.Tasks; 

namespace DllSelfExtract 
{ 
    public class SelfExtract 
    { 
     public static void Init() 
     { 
      String managedDllPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; 
      String nativeDllPath = managedDllPath.Replace("file:///", "").Replace("DllSelfExtract.DLL", "TestDll.dll"); 
      if(!File.Exists(nativeDllPath)) 
      { 
       Stream dllIn = Assembly.GetExecutingAssembly().GetManifestResourceStream("DllSelfExtract.TestDll.dll"); 
       if (dllIn == null) return; 

       using (Stream outFile = File.Create(nativeDllPath)) 
       { 
        const int sz = 4096; 
        byte[] buf = new byte[sz]; 
        while (true) 
        { 
         int nRead = dllIn.Read(buf, 0, sz); 
         if (nRead < 1) 
          break; 
         outFile.Write(buf, 0, nRead); 
        } 
       } 
      } 

      //LoadLibrary Here 
     } 
    } 
} 

3 ।परियोजना है कि आपके प्रबंधित dll का उपयोग में, आह्वान init() विधि पहले

SelfExtract.Init(); 

अपडेट 02 (NuGet उदाहरण):

1. बनाएँ एक नया NuGet परियोजना

2.Place कामयाब/lib निर्देशिका

3.Place गैर-प्रबंधित सभी गैर-प्रबंधित * * .dl_

को .dll/निर्माण उपनिर्देशिका में साझा पुस्तकालयों और संबंधित फ़ाइलें और नाम बदलने में विधानसभाओं 10

4.Add निम्नलिखित सामग्री कुछ इस तरह के साथ/निर्माण उपनिर्देशिका में एक कस्टम .targets फ़ाइल:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <ItemGroup> 
    <AvailableItemName Include="NativeBinary" /> 
    </ItemGroup> 
    <ItemGroup> 
    <NativeBinary Include="$(MSBuildThisFileDirectory)*"> 
     <TargetPath></TargetPath> 
    </NativeBinary> 
    </ItemGroup> 
    <PropertyGroup> 
    <PrepareForRunDependsOn> 
     $(PrepareForRunDependsOn); 
     CopyNativeBinaries 
    </PrepareForRunDependsOn> 
    </PropertyGroup> 
    <Target Name="CopyNativeBinaries" DependsOnTargets="CopyFilesToOutputDirectory"> 
    <Copy SourceFiles="@(NativeBinary)" 
      DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).dll')" 
      Condition="'%(Extension)'=='.dl_'"> 
     <Output TaskParameter="DestinationFiles" ItemName="FileWrites" /> 
    </Copy> 
    <Copy SourceFiles="@(NativeBinary)" 
      DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).%(Extension)')" 
      Condition="'%(Extension)'!='.dl_'"> 
     <Output TaskParameter="DestinationFiles" ItemName="FileWrites" /> 
    </Copy> 
    </Target> 
</Project> 

5.Add Package.nuspec में

<files> 
    <file src="lib\" target="lib" /> 
    <file src="tools\" target="tools" /> 
    <file src="content\" target="content" /> 
    <file src="build\" target="build" /> 
</files> 

6 निर्माण फ़ोल्डर के लिए नियम बनाएं पैकेज

7. अपने अन्य सी # प्रोजेक्ट में बस इस NuGet पैकेज को जोड़ें।

+0

आपके उत्तर के लिए धन्यवाद। ये सभी विधियां वैध और उपयोगी हैं और मैं उन्हें अपनी परियोजना में उपयोग कर सकता हूं। समस्या यह है कि मैं एक बहु-फ़ाइल असेंबली (Managed.dll और Native.dll से युक्त) वितरित करना चाहता हूं, न कि विजुअल स्टूडियो प्रोजेक्ट। – Trifon

+0

@Trifon Managed.dll में संसाधन के रूप में Native.dll को जोड़ने के बारे में क्या। Managed.dll में, Native.dll लोड करने से पहले, पता लगाएं कि Native.dll सही जगह पर है, यदि Managed.dll से मूल निकालें नहीं है? लेकिन मुझे लगता है कि इसे इंटरनेट से डाउनलोड करना बेहतर होगा। – neohope

+0

हां यह एक ऐसा समाधान है जो मुझे कुछ भी सफल नहीं होने पर ध्यान में रखता है, जैसे कि [लिंक] (http://stackoverflow.com/a/768429/3260013) – Trifon

5

लिंकर गुणों में /ASSEMBLYLINKRESOURCE विकल्प का उपयोग करना सबसे आसान समाधान प्रतीत होता है। यह दृश्य स्टूडियो को देशी डीएल को असेंबली के हिस्से के रूप में मानता है।

  • अधिकार परियोजना के नाम पर क्लिक करें और चुनें: इसके अलावा, Microsoft द्वारा प्रदान प्रलेखन के अनुसार, देशी dll कैश

    वैश्विक विधानसभा में स्थापित होने के लिए एक विजुअल C++ प्रोजेक्ट में इस लिंकर विकल्प सेट करने के लिए अनुमति देता है गुण

  • लिंकर का चयन करें फ़ोल्डर
  • इनपुट संपत्ति पेज विधानसभा लिंक resourc लगता है ई विकल्प
  • देशी असेंबली का फ़ाइल नाम लिखें उदा। MyNative.dll

आप एक पोस्ट का निर्माण घटना आउटपुट फ़ोल्डर के मूल निवासी dll कॉपी करने के लिए की आवश्यकता होगी।

किसी भी अन्य विजुअल प्रोजेक्ट से प्रबंधित असेंबली का संदर्भ, देशी डीएल को/bin फ़ोल्डर में प्रबंधित असेंबली के साथ एक साथ कॉपी करने के लिए मजबूर करता है।

+0

कृपया इसे पढ़ें, आप nuget पैकेज को आजमा सकते हैं। http://stackoverflow.com/questions/19478775/add-native-files-from-nuget-package-to-project-output-directory – neohope

संबंधित मुद्दे