2009-12-14 8 views
6

के साथ साइड-बाय-साइड COM इंटरऑप मैं सी # से वीबीए COM को कॉल करने के बारे में बात नहीं कर रहा हूं ... दूसरी तरफ!सी # और वीबीए

मैं जो करना चाहता हूं वह डीएलएल पंजीकृत किए बिना एमएस एक्सेस में वीबीए का उपयोग कर सी # लाइब्रेरी को कॉल करना है। मैं सफलता के बिना थोड़ी देर के लिए साइड-बाय-साइड इंटरऑप के साथ खेल रहा हूं और अंततः यह मेरे लिए हुआ है कि एक mdb.manifest शायद exe.manifest के लिए एक स्वीकार्य प्रतिस्थापन नहीं है (शायद स्पष्ट है, मुझे पता है, लेकिन मैं आशावादी होने की कोशिश कर रहा था)।

मेरा प्रश्न: क्या वीबीए को साइड-बाय-साइड COM घटक लोड करना संभव है?

या, एक्सेस में एक अनियंत्रित सी # लाइब्रेरी का उपयोग करने का कोई और तरीका है?

(इससे पहले कि आप पूछें, मेरे कारण हैं: मुझे बिल्कुल नहीं है कि मुझे अपने क्लाइंट की विंडोज रजिस्ट्री तक पहुंच प्रदान की जाएगी - यही कारण है कि इसे पहली जगह एक्सेस में लिखा गया था। और, मुझे इसे लागू करने की आवश्यकता होगी एक सी # आवेदन में एक ही कार्यक्षमता जल्द ही और दो बार ऐसा नहीं करते हैं)।

उत्तर

3

आपको एसएक्सएस का उपयोग करने के लिए एक्सई का स्वामित्व नहीं है, एसएक्सएस Activation Context के लिए एक और शब्द है। यदि आप vba (और आप कर सकते हैं) में प्रासंगिक Win32 कॉल आयात कर सकते हैं, तो आप अपनी मेनिफेस्ट फ़ाइल लोड करने के लिए activation context api का उपयोग कर सकते हैं।

विषय पर अधिक और कुछ उदाहरण here मिल सकते हैं।

+0

मैंने उस एपीआई का उपयोग करने में देखा। विडंबना यह है कि, माइक्रोसॉफ्ट ने पंजीकरण से बचने के लिए एक पैकेज बनाया है जिसके लिए पंजीकरण की आवश्यकता है और मेरे पास पहले से ही वही प्रश्न छोड़ दिया गया है - इसे अपने ग्राहक की मशीन पर कैसे प्राप्त करें? हालांकि माइक्रोसॉफ्ट.Windows.Actctx विंडोज 2 के 3 के लिए उपलब्ध है + यह केवल सर्वर इंस्टॉल में शामिल है। यहां एक और एसओ सवाल है जिसके बारे में शिकायत है: http://stackoverflow.com/questions/979567/microsoft-windows-actctx-on-windows-xp। और एमएसडीएन इसे यहां बैक करता है: http://msdn.microsoft.com/en-us/library/aa375644(VS.85).aspx। – Jelly

+0

मुझे पता है कि सक्रियण संदर्भ API कर्नेल 32 का हिस्सा हैं।lib, जिसका अर्थ है कि आपके पास कोई भी चीज़ स्थापित नहीं है, और यह किसी भी ऑपरेटिंग सिस्टम में शामिल है जिसमें एसएक्सएस के लिए समर्थन है जो WinXP SP2 और उच्चतर है। मैंने इसे WinXP SP3 पर अपना स्वयं किया है और यह किसी विशेष इंस्टॉल के साथ काम नहीं करता है। मुझे माइक्रोसॉफ्ट.Windows.Actctx के बारे में पता नहीं है, लेकिन मुझे 100% यकीन है कि आप कर्नेल 32.लिब से प्रासंगिक कार्यों को आयात करके सीधे उन्हें एपीआई का आह्वान कर सकते हैं और उन्हें सीधे इनकार कर सकते हैं। जैसा कि यह इस नमूना कोड पर प्रस्तुत किया गया है http://www.mazecomputer.com/sxs/help/sxsapi3.htm –

+0

ओह मैं देखता हूं। वेब पर किए गए सभी उदाहरणों में मैंने वीबीए में ऐसा करने के बारे में देखा था, एपीआई के बजाए एक्टक्टक्स ऑब्जेक्ट का उपयोग करता है, जो कि मूल रूप से निष्कर्ष निकाला गया है कि यह कोड में नहीं किया जा सका। जाहिर है, यह मुझे भ्रमित करने के लिए दोनों तरीकों (और एक ही बात कहा जाता है) लागू किया गया है। मुझे इसे ऊपर उठाने और चलाने में बहुत परेशानी नहीं होनी चाहिए - और यह आईएल हैकिंग की तुलना में एक और अधिक स्थिर समाधान होना चाहिए - इसलिए जब मैं वहां जाता हूं तो स्वीकार्य समाधान ध्वज ले जाऊंगा। सहायता के लिए धन्यवाद! – Jelly

0

सी # पुस्तकालय नियमित डीएलएल नहीं हैं। वे COM पुस्तकालयों के समान हैं जो उपयोग किए जाने से पहले पंजीकृत होने की आवश्यकता है (जैसे ActiveX नियंत्रणों की तरह); खासकर जब गैर- एनईटी कोड से बुलाया जाता है।

(, जब तक जाहिर है, चीजें बदल गई ...)

+0

मेरी धारणा कि सी # डीएलएल का उपयोग अनियंत्रित किया जा सकता है यहां से आया: http://msdn.microsoft.com/en-us/library/ms973915.aspx जहां सी # .NET सर्वर और गैर- .NET क्लाइंट है। मेरा मानना ​​है कि मूल रूप से मैं इस तथ्य के अलावा क्या करना चाहता हूं कि क्लाइंट वीबीए आवेदन के बजाय वीबी 6 निष्पादन योग्य है। क्या कुछ और है जो मुझे याद आ रहा है? धन्यवाद! – Jelly

+0

आप उस हिस्से पर फंस सकते हैं जहां आपको क्लाइंट के लिए एक मेनिफेस्ट फ़ाइल बनाने की आवश्यकता है, क्योंकि वीबीए एक स्टैंडअलोन प्रोग्राम नहीं है जिसके लिए आप एक उत्पन्न कर सकते हैं। मेनिफेस्ट काफी सरल दिखता है, लेकिन मैं यह सुनिश्चित करने के लिए नहीं कह सकता कि इसे सही तरीके से कैसे जोड़ना है। हो सकता है कि आप एक स्टैंडअलोन क्लाइंट निष्पादित करने के लिए वीबीए प्राप्त कर सकें जो आपको चाहिए? – Ioan

1

समस्या SxS उपयोग करने के लिए है कि है, तो आप exe खुद के SxS विधानसभा लोड करने के लिए config स्थापित करने के लिए की जरूरत है। आपके पास "स्वामित्व" नहीं है, और जब आप अपने .NET COM सामान संस पंजीकरण को लोड करने के लिए सही कॉन्फ़िगरेशन ड्रॉप कर सकते हैं, तो यह "अच्छा नागरिक" कदम नहीं होगा।

यदि आप शर्मनाक के साथ मुश्किल हो जाते हैं, तो आप एक अप्रबंधित DLL (या एक हैक्लेड सी # क्लास लाइब्रेरी को एक ड्लेक्सपोर्ट के साथ सेट कर सकते हैं, उदाहरण के लिए this देखें), एक निर्यात के साथ जो .NET ढांचे को लोड करेगा, का एक उदाहरण बनाएं एक COMVisible DispInterface प्रबंधित प्रकार और इसे वापस करें (विधि IDISpatch वापस करना चाहिए)। फिर अपने डीएलएल निर्यात समारोह में एक वीबीए घोषित करें (ऑब्जेक्ट लौटने के रूप में घोषित)। यदि यह समझ में नहीं आता है, तो शायद आपको यह कोशिश नहीं करनी चाहिए ... :) मैंने इसे पहले इसी तरह की स्थिति में किया है, और यह काम करता है, लेकिन मेरे पास आपको इंगित करने के लिए नमूना नहीं है।

+0

यह बहुत चालाक है और यह वास्तव में समझ में आता है। जब मैं एक विधि निर्यात करने के लिए सी # को मजबूर करने के लिए आईएल को हैक करने के बारे में पहले खोज रहा था तो मुझे कुछ भी नहीं मिला था। मुझे वह हिस्सा काम करने के लिए मिला है और मुझे नहीं लगता कि इसे किसी ऑब्जेक्ट को वापस करने के लिए प्रवेश बिंदु बनाने के लिए बहुत कठिन होना चाहिए। सलाह के लिये धन्यवाद! – Jelly

8

पहले से ही विद्यमान उत्तर देने के लिए जोड़ने के लिए: साथ .NET 4.0 , यह COM पंजीकरण के बिना अपने VBA प्रोजेक्ट में एक सी # dll उपभोग करने के लिए वास्तव में काफी आसान है।

संपादित: मैं बस mscorlib.tlb और mscoree.tlb कि C:\windows\Microsoft.NET\Framework\v2.0.50727 में हैं के साथ इस कोशिश की - एक विधानसभा 3.5-- में संकलित लोड हो रहा है और यह ठीक काम किया। तो जाहिर है आपको .NET 4.0 की आवश्यकता नहीं है।

नीचे आपके वीबीए प्रोजेक्ट में सी # डीएल का उपयोग करने का एक उदाहरण है। यह this उत्तर से थोड़ा संशोधित है।आप 64-बिट कार्यालय)

2) में चल रहे हैं

C:\windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb 
C:\windows\Microsoft.NET\Framework\v4.0.30319\mscoree.tlb 

(Framework64 फ़ोल्डर का उपयोग:

1) निम्न प्रकार libs के लिए संदर्भ जोड़ें अपने VBA प्रोजेक्ट (उपकरण> संदर्भ)

using System.Windows.Forms; 
using System.Runtime.InteropServices; 
namespace VB6FuncLib 
{ 
    [ComVisible(true)] 
    public class VB6FuncLib 
    { 
     public VB6FuncLib() 
     { } 
     public void test() 
     { 
      MessageBox.Show("Test Successful"); 
     } 
    } 
} 

आप chec की जरूरत नहीं कर : अपनी सी # परियोजना, सुनिश्चित करें कि आप अपनी कक्षा में [ComVisible(true)] विशेषता जोड़ कर के विकल्प "COM इंटरऑप के लिए रजिस्टर करें"। यह केवल मानक COM ऑब्जेक्ट बनाने के लिए है। जब तक आप पूरी असेंबली को दिखाना नहीं चाहते हैं, तब तक आपको "असेंबली COM दृश्यमान बनाएं" की जांच करने की आवश्यकता नहीं है (जो COMVisible विशेषता की आवश्यकता को भी समाप्त कर देगा)। अपने कार्यालय परियोजना के रूप में

Sub Test() 
    Dim Host As mscoree.CorRuntimeHost 
    Set Host = New CorRuntimeHost 
    Host.Start 
    Dim Unk As IUnknown 
    Host.GetDefaultDomain Unk 
    Dim AppDomain As AppDomain 
    Set AppDomain = Unk 
    Dim ObjHandle As ObjectHandle 
    Set FS = CreateObject("Scripting.FileSystemObject") 
    Path = FS.GetParentFolderName(CurrentDb().Name) 
    Set ObjHandle = AppDomain.CreateInstanceFrom(Path & "\VB6 Function Library.dll", "VB6FuncLib.VB6FuncLib") 
    Dim ObjInstance As Object 
    Set ObjInstance = ObjHandle.Unwrap 
    ObjInstance.test 
    Host.Stop 
End Sub 

4) एक ही फ़ोल्डर में DLL की प्रतिलिपि बनाएँ और टेस्ट() VBA में उप चलाएँ:

3) अपने VBA कोड में, इस कोड के साथ एक नया मॉड्यूल जोड़ें।

नोट्स:

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

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