2009-12-28 8 views
8

हमारे पास बहुत सारे उत्पाद हैं और प्रत्येक उत्पाद के आवेदन में कुछ सामान्य डीएलएल हैं। अभी हम प्रत्येक सामान्य डीएलएल को प्रत्येक उत्पाद की बिन निर्देशिका में कॉपी करते हैं और उन्हें निजी असेंबली के रूप में देखते हैं। यह अनावश्यक रूप से प्रत्येक उत्पाद के एमएसआई आकार को बढ़ाता है और जब एक डीएलएल में कोई समस्या होती है तो हमें डीएलएल समेत प्रत्येक उत्पाद की एमएसआई बनाना और इसे तैनात करना होता है।केंद्रीय भंडार से डीएलएल लोड करने का एक तरीका

क्या डीएलएल लोड करने के लिए इस्तेमाल होने वाली सामान्य निजी निर्देशिका का उपयोग करने के लिए उत्पाद एप्लिकेशन को निर्देश देने के लिए वैसे भी है [प्रकट योजना का उपयोग कर ..]? [नोट: पथ env करने के लिए निजी निर्देशिका जोड़ना एक समाधान उपलब्ध नहीं कराएगा के रूप में अगर वहाँ एक ही नाम के साथ एक DLL प्रणाली निर्देशिका में मौजूद हैं, कि हमारे निजी निर्देशिका से अधिक विशेषाधिकार ले जाएगा]

-Kartlee

उत्तर

1

आप नेट के बारे में बात कर रहे हैं, आप कर सकते हैं:

  • Assembly.Load(byte[])
  • का उपयोग करके एक डेटाबेस से सीधे अपने DLL लोड Assembly.TypeResolve घटना
  • का उपयोग करके तक TypeProvider वर्ग
  • का उपयोग कर अपने कॉन्फ़िग फ़ाइल में एक जांच सूची को परिभाषित करने

की तरह द्वारा:

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
      <probing privatePath="bin"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 
+0

आपके उत्तर के लिए धन्यवाद। दुर्भाग्य से मैं सी/सी ++ एप्लिकेशन की तलाश में हूं जो उदाहरण के लिए किसी भी रन टाइम डायनामिक लिंकिंग विधि (जैसे लोडलब्रिरी (..)) का उपयोग नहीं करता है। क्या वैसे भी प्रकट होता है जैसे कि 'जांच' अवधारणा कैसे काम करती है? – Kartlee

+0

@ कार्टली, क्षमा करें मुझे सी/सी ++ के बारे में पता नहीं है; लेकिन मैंने आपके प्रश्न को संपादित करने के लिए संपादित किया कि कीवर्ड –

0

मैं अगर यह आपके लिए क्या देख रहे हैं यकीन नहीं है लेकिन जहां अब मैं काम हम हमारे सभी डीएलएल के लिए एक आम यूएनसी पथ का उपयोग करें।

हम कुछ के लिए समान है ...

\\ server01 \ productionLibrary उत्पादन के लिए DLLs, अपने आप निर्देशिका में प्रत्येक पढ़ें।

और

\\ server01 \ developmentLibrary जो उत्पादन पुस्तकालय दर्पण है और इस डेवलपर्स क्या उपयोग के रूप में वे विकसित है।

जब परीक्षण पूरा होने के बाद हम कोड मर्ज करते हैं तो हम उत्पादन पुस्तकालय में तैनात होते हैं। सभी परियोजनाएं उत्पादन पुस्तकालय को संदर्भित करती हैं जब उन्हें तैनाती के लिए एमएसआई फाइलों में बनाया जाता है। हमारी स्वचालित प्रणाली परियोजनाओं को एमएसआई में बनाती है और यह सत्यापित करती है कि सभी डीएलएल उत्पादन पुस्तकालय को इंगित कर रहे हैं, इसलिए कोई मौका नहीं है कि यह आकस्मिक रूप से विकास प्रति का उपयोग करेगा।

उम्मीद है कि इससे मदद मिलती है।

0

मुझे यकीन है कि मैं सवाल सही ढंग से समझ है, लेकिन नहीं कर रहा हूँ अगर आप नेट में हैं, वहाँ एक वैश्विक असेंबली कैश (GAC) है: http://en.wikipedia.org/wiki/Global_Assembly_Cache

यह विधानसभाओं कैश और अनुप्रयोगों के द्वारा उनमें से पुन: उपयोग की अनुमति देता है (नेट फ्रेमवर्क के साथ)। आपको बस स्थापना पर जीएसी को असेंबली पंजीकृत करने की आवश्यकता होगी, उदाहरण के लिए सभी आम असेंबली के साथ "अपना फ्रेमवर्क इंस्टॉल" प्रदान करें, और इसे केवल एक बार तैनात किया जा सकता है।

+0

आपके उत्तर के लिए धन्यवाद। कृपया 'रुबेंस फ़ारीस' पर मेरी टिप्पणी देखें। – Kartlee

7

आप यह निर्दिष्ट नहीं करते हैं कि आपका पर्यावरण .NET या सीधे Win32 है या नहीं।

मैं अपने Win32 को मान रहा हूं क्योंकि यदि इसकी .NET प्रौद्योगिकियां ग्लोबल असेंबली कैश जैसी चीजों के मामले में हाथ के करीब हैं।

Win32 के संदर्भ में यह दो तरीकों में से एक में एक साझा किए गए स्थान से DLLs लोड करने के लिए संभव है:

  • उपयोग स्पष्ट पूर्ण पथ के साथ LoadLibrary। इसका मतलब है कि आप स्थिर लिंकिंग का उपयोग नहीं कर सकते - सभी उत्पादों में उपयोग किए जाने वाले सभी डीएलएल कार्यों को GetProcAddress के माध्यम से एक्सेस करना होगा। आप लोड लाइब्रेरी के माध्यम से लोड किए गए डीएलएल से सी ++ कक्षाएं आयात नहीं कर सकते हैं - उन्हें स्थिर रूप से काम से जोड़ा जाना चाहिए ताकि यह दृष्टिकोण व्यवहार्य हो या न हो। शिम हेडर फाइलों को लिखना बहुत कठिन नहीं है जो डीएल के इंटरफेस के रूप में मास्कराइड करते हैं और प्रत्येक कॉल के लिए जरूरी समय में डीएलएल लोड और GetProcAddress करते हैं।

  • दूसरा विकल्प डीएल को "साइड बाय साइड असेंबली" कहलाता है और उन्हें WinSxS स्टोर में इंस्टॉल करना है। बड़े नाम से डरो मत। "साइड बाय साइड असेंबली" का अर्थ है "संस्करण जानकारी के साथ एक डीएल फाइल प्लस मेनिफेस्ट फ़ाइल"। विभिन्न अनुप्रयोगों में से प्रत्येक को 'मजबूत नाम' रखा जाएगा - जिसमें संस्करण जानकारी शामिल है - प्रत्येक एप्लिकेशन के उपयोग के लिए अपने एप्लिकेशन मेनिफेस्ट में, और Win32 Dll लोडर WinSxS स्टोर से सामान्य डीएल के सही उदाहरण को चुनने के लिए इसका उपयोग करेगा । बुनियादी प्रक्रिया MSDN आलेख में वर्णित किया गया है Guidelines for Creating Side-by-side Assemblies


Windows संस्करण 6.1 और ऊपर पर (विंडोज सर्वर 2008 और विडंबना यह है कि नामित विंडोज 7) आवेदन विन्यास फाइल अब Application Configuration Files

में जांच तत्व का समर्थन करते हैं

इसका मतलब है कि आप एक डीएलएल असेंबली युक्त फ़ोल्डर में एक पथ (आपके आवेदन के सापेक्ष) प्रदान करने में सक्षम होना चाहिए, जिसे आप लोड करना चाहते हैं।


ठीक है, Ive विंडोज 7 पर कुछ परीक्षण किया है, और यह काम करता है:

मान लें कि आप एक आवेदन app1.exe \ Program Files \ APP1 में स्थापित है, कि कुछ सामान्य dll "thedll पर निर्भर करता है है। dll "

आवेदन फ़ोल्डर में (\ Program Files \ APP1) एक फ़ाइल App1.exe.config बनाने और इसे निम्नलिखित सामग्री दे: -

<configuration> 
    <windows> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="..\AcmeCommon"/> 
    </assemblyBinding> 
    </windows> 
</configuration> 

अब, एक फ़ोल्डर \ Program एफ बनाएं जिसका नाम Iles \ AcmeCommon, और उस में एक फ़ोल्डर acme.thedll, और \ Program Files में thedll.dll कॉपी \ AcmeCommon \ acme.thedll

इसके अलावा acme.thedll.manifest बुलाया AcmeCommon \ acme.thedll में एक फ़ाइल बनाने - यह विधानसभा प्रकट 'acme.thedll' नामक विधानसभा का वर्णन किया जाएगा

acme.thedll.manifest की सामग्री हो जाएगा: -

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
    <assemblyIdentity name="acme.thedll" version="1.2.3.4" processorArchitecture="x86" type="win32"/> 
    <file name="thedll.dll"/> 
</assembly> 

अब हम आम dll, एक आम स्थान में, राशि के रूप में एक देशी एसएक्स असेंबली। हमारे पास ऐप है, एक कॉन्फ़िगरेशन फ़ाइल के साथ जो विंडोज 7 और 2008 सर्वर (और ऊपर) पर सामान्य स्थान पर असेंबली खोजने के लिए कहेंगे। लेकिन ऐप अभी भी एक असेंबली के बजाय डीएल के रूप में एक डीएल के रूप में जोड़ने की कोशिश कर रहा है।

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

#pragma comment(linker,"/manifestdependency:\"type='win32' name='acme.thedll' version='1.2.3.4' processorArchitecture='x86' language='*'\"") 

यदि आप किसी पुराने उपयोग कर रहे हैं: - जो मामले में सबसे आसान तरीका विधानसभा परियोजना में कम से कम एक शीर्ष लेख या ग/सीपीपी फ़ाइल में निम्न कोड जोड़ने के बाद यह पुनर्निर्माण के लिए है के बारे में बताने के लिए एप्लिकेशन

<dependency> 
    <dependentassembly> 
    <assemblyidentity type="win32" name="acme.thedll" version="1.2.3.4" processorArchitecture="x86" language="*"/> 
    </dependentassembly> 
</dependency> 

इस चक्र बंद हो जाना चाहिए: वातावरण जहां प्रकट हाथ बना रहे हैं आप APP1 फ़ोल्डर में app1.exe.manifest साथ निम्नलिखित एक्सएमएल मर्ज करने के लिए की आवश्यकता होगी निर्माण एप्लिकेशन Win32 लोडर लोड होगा लोड करता है एप्लिकेशन मैनिफेस्ट (app1.exe.manifest या RT_MANIFEST संसाधन के रूप में एम्बेड किया गया) और "acme.thedll" असेंबली के बारे में जानें। यह एप्लिकेशन कॉन्फ़िगरेशन फ़ाइल (app1.exe.config) भी लोड करेगा और असेंबली खोजने के लिए निजी पथ के बारे में जानेंगे। और फिर यह "सक्रियण संदर्भ" ऐप्स को "acme.thedll.manifest" लोड और जोड़ देगा। फिर, जब लोडर "thedll.dll" लोड करने का प्रयास करता है तो यह सक्रियण संदर्भ डीबी को खोजेगा, यह पता लगाएं कि यह acme.thedll असेंबली में है, और इसे असेंबली स्थान से लोड करें।

+0

आपकी टिप्पणी के लिए धन्यवाद। मुझे लगता है कि मैंने अपनी पिछली पोस्ट में जवाब दिया था कि रन टाइम डीएलएल लिंकिंग एक ऐसा समाधान नहीं है जिसे मैं ढूंढ रहा हूं। साइड साइड assmebly अवधारणा अच्छा है, लेकिन इसके लिए हमारे कस्टम DLL को WinSXS निर्देशिका में रखना आवश्यक है और व्यवस्थापक विशेषाधिकार की आवश्यकता है। स्थानीय स्थापना में निजी स्टोर को बनाए रखने का कोई तरीका है और स्टोर से इसका उपयोग करने के लिए मेरे सभी उत्पाद एप्लिकेशन से पूछें? क्या मैनिफेस्ट फ़ाइल में इस तरह इस्तेमाल करने के लिए निर्देशिका निर्दिष्ट करने का कोई तरीका है? -कार्टली – Kartlee

+0

दुर्भाग्य से नहीं। साइड असेंबली इंस्टॉलेशन द्वारा निजी पक्ष * केवल * exe के फ़ोल्डर में खोजा गया है। मैंने असेंबली मैनिफेस्ट के फ़ाइल नोड में डीएल के सापेक्ष पथ डालने का प्रयास किया लेकिन फिर यह लोड करने में विफल रहा। विंडोज कॉन्फ़िगरेशन फ़ाइलें .NET शैली कॉन्फ़िगरेशन फ़ाइलों के प्रोबिंग तत्व का समर्थन नहीं करती हैं। –

+0

असल में, जब तक आपका पसंद का ओएस विंडोज 7 या सेवर 2008 है, तो आप कर सकते हैं। मेरे उत्तर में संशोधित अनुभाग देखें। –

0

यह आपकी मदद नहीं कर सकता है, लेकिन ... आप मनमानी निर्देशिकाओं से डीएलएस लोड कर सकते हैं और फिर भी जब तक आप गतिशील लिंकिंग के माध्यम से डीएलएस लोड होते हैं और सुनिश्चित करते हैं कि आप नियंत्रण कर सकते हैं तब तक सामान्य गतिशील लिंकिंग पर भरोसा कर सकते हैं डायनेमिक रूप से लोड होने से पहले पहले से ही पूर्ण पथ का उपयोग करके डीएलएल को लोड कर लिया है।

यह केवल मदद की संभावना है यदि आप एक प्लगइन सिस्टम लिख रहे हैं जहां आपके प्लगइन्स गतिशील रूप से उन डीएलएस से जुड़े होते हैं जिन्हें आप एक गैर मानक निर्देशिका में रखना चाहते हैं। यदि आप उन सभी डीएलएस के बारे में जानते हैं जो वे आपके साथ जुड़े हुए हैं, तो आप डीएलएस (प्लगइन्स) को लोड करने से पहले इन डीएलएस को सीधे अपने पूर्ण पथ का उपयोग करके लोड कर सकते हैं जो गतिशील रूप से उन पर निर्भर करता है। चूंकि आपकी प्लगइन को ढूंढने की आवश्यकता होने पर डीएलएल पहले से ही स्मृति में है, यह स्मृति में संस्करण का उपयोग करेगा। आप प्लगइन लोड करने से पहले किए गए स्पष्ट लोड को अनलोड कर सकते हैं और आप जाने के लिए अच्छे हैं।

दुर्भाग्य से यह काम नहीं करेगा अगर आपके मुख्य exe को मनमानी स्थानों से डीएलएस लोड करने की आवश्यकता है क्योंकि आप सामान्य डीएल लोड प्रक्रिया से पहले नहीं पहुंच सकते हैं।

1

मैं क्रिस के जवाब का पालन कर रहा हूं। सुनिश्चित करें कि मामला प्रकट और कॉन्फ़िगरेशन पर सही है। अन्यथा वे असफल हो जाएंगे। मैं असेंबली को लोड करने में सक्षम था, लेकिन डीएलएल का चयन नहीं किया जाएगा। मेरे मामले में system32 में एक विंडोज डीएलएल को उसी नाम से अपने आप के बजाय चुना जा रहा है। निर्भरता वाकर में, मेरा डीएलएल लोड हो गया है, लेकिन रनटाइम पर, प्रोसेस एक्सप्लोरर के साथ, विंडोज़ की प्रति लोड हो गई है। कोई विचार?

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