2010-05-13 9 views
6

हमारे पास एक .NET असेंबली (Aspose.Words वास्तव में) है और हम चाहते हैं कि क्लाइंट इसे बिना किसी परेशानी के COM क्लाइंट से उपयोग करें।एक कमांड लाइन में .NET असेंबली (या टीएलबी को आईडीएल में कैसे परिवर्तित करें) से आईडीएल कैसे प्राप्त करें?

  1. तो हम विधानसभा के साथ एक .tlb जहाज तो ग्राहक इस तरह के सी ++ या डेल्फी के रूप में भाषाओं से उपयोग कर सकते हैं और .tlb खुद को निकालने के लिए परेशान नहीं है।

  2. हम असेंबली के साथ एक .IDL भी भेजते हैं ताकि यदि वे एएसपी में प्रोग्रामिंग कर रहे हैं तो वे गणना मूल्यों को देखना चाहते हैं तो ग्राहक इसे देख सकते हैं।

  3. मैं चाहता हूं कि एक बिल्ड स्क्रिप्ट द्वारा टीएलबी और .IDL उत्पन्न किया जाए। मैं उत्पन्न कर सकता हूं। टीएलबी कोई समस्या नहीं है। लेकिन मैं एक कमांड लाइन में .IDL उत्पन्न नहीं कर सकता (या वैकल्पिक रूप से परिवर्तित करें .एलएलबी से .IDL)। मैं मैन्युअल रूप से OLEVIEW.EXE का उपयोग कर ऐसा करता हूं जो अच्छा नहीं है।

डेल्फी के TLIBIMP.EXE के बारे में सुना लगता है जैसे कि यह है कि कर सकता है, लेकिन यह अलग से उपलब्ध होने की नहीं लगती।

तो प्रश्न हैं:

  1. ऊपर से कुछ भी बेवकूफ लग रहा है?

  2. कमांड लाइन का उपयोग कर .NET असेंबली से .IDL कैसे प्राप्त करें।

धन्यवाद।

+0

आपके ग्राहक OleView.exe के साथ TLB फ़ाइलों को ब्राउज़ करने में सक्षम हो सकते हैं। यह एक टीएलबी फ़ाइल दिया गया (जेनरेट) आईडीएल दिखाता है। –

+0

संभावित डुप्लिकेट [आईडीएल (टीएलबी के लिए) प्राप्त करने पर COM + dll से प्राप्त होने पर] (http://stackoverflow.com/questions/18385780/getting-idl-for-tlb-from-a-com-dll- जब-यह-प्रदान नहीं किया गया है) – DaveInCaz

उत्तर

0

टाइप लाइब्रेरी किसी भी भाषा के लिए आपके सर्वर का उपयोग करने के लिए पर्याप्त है। आईडीएल केवल एक प्रकार की लाइब्रेरी उत्पन्न करने के लिए उपयोगी होगा, जिसे आप पहले ही आपूर्ति करते हैं, या सी ++ हेडर फ़ाइल उत्पन्न करने के लिए, जो #import directive के साथ उत्पन्न करना बहुत आसान है।

यदि आप वास्तव में ऐसा करना चाहते हैं तो एक ऐसा तरीका होगा, एक छोटा सी ++ प्रोग्राम बनाएं जो #import का उपयोग करता है, जेनरेट की गई .tlh फ़ाइल प्रदान करें।

+0

धन्यवाद और मैं गंभीरता से आईडीएल की आपूर्ति नहीं करने पर विचार करूंगा। यदि आप प्रोग्रामिंग कर रहे हैं तो वीबीस्क्रिप्ट/पर्ल/PHP/पायथन में और टीएलबी ऑब्जेक्ट ब्राउज़र के साथ आईडीई का उपयोग नहीं करते हैं, तो .IDL यह देखने की अनुमति देता है कि कैसे।नेट खुलासा विधि हस्ताक्षर, उदाहरण के लिए परिणाम सहेजें_2 ([में] BSTR फ़ाइल नाम); और enum enum को महत्व देता { HeightRule_AtLeast = 0, HeightRule_Exactly = 1, } HeightRule; लेकिन मुझे लगता है कि वहां ऐसा करने वाले कई डेवलपर्स नहीं हैं और यदि वे पहले से ही अपना जीवन इतना कठिन बना रहे हैं, तो वे ठीक से पढ़ लेंगे यदि आवश्यक हो तो टीएलबी को आईडीएल में कैसे परिवर्तित करें। – romeok

2

मैंने टीएलबी से आईडीएल निकालने के लिए यह त्वरित और गंदा हैक लिखा है। यह वही उपयोग करता है (मेरे सर्वोत्तम ज्ञान के लिए) COM ऑब्जेक्ट जो OLEVIEW.EXE उपयोग करता है।

/* 
    Extract the IDL from a tlb file and print it to stdout. 

    The tlb file is analysed by a COM object of type CLSID_ITypeLibViewer and 
    the extracted IDL is shown in a window created by the same object. 

    This program extracts the IDL from that window. 

    Usually Microsoft's OLEViewer (a.k.a. OLE/COM Object Viewer) registers a 
    COM object of that CLSID_ITypeLibViewer (for example inside a dll called 
    IViewers.Dll), I've tested it with: 
    IVIEWERS.DLL "OLE/COM Object Interface Viewer" Version 6.0.6000.16384 

    This software is provided "as-is," without any express or implied warranty. 
*/ 

#define _CRT_SECURE_NO_WARNINGS 

#include <Windows.h> 
#include <atlbase.h> 
#include <comdef.h> 

#include <iostream> 
#include <string> 
#include <ctime> 

const char IDL_window_name[] = "ITypeLib Viewer"; 

const IID IID_IInterfaceViewer = { 0xfc37e5ba, 0x4a8e, 0x11ce, { 0x87, 0x0b, 
            0x08, 0x00, 0x36, 0x8d, 0x23, 0x02 } }; 

const CLSID CLSID_ITypeLibViewer = { 0x57efbf49, 0x4a8b, 0x11ce, { 0x87, 0x0b, 
            0x08, 0x00, 0x36, 0x8d, 0x23, 0x02 } }; 

#define RICHEDIT_CONTROL_ID 0xE901 // found by Spy++ 
#define RICHEDIT_PARENT_ID 0xE900 // found by Spy++ 

#define CHECK(hr) if (FAILED(hr)) { std::wcerr << L"COM error: " << stringify_hr(hr) << L"\n"; return __LINE__; } 

std::string myself; 
std::string tlb; 

// My installation of Microsoft Visual Studio 2010 has a sample folder where 
// I can find the source of OleView: 
// C:\Program Files (x86)\Microsoft Visual Studio 10.0\Samples\1033\VC2010Samples.zip 
// 
// Unzipping the file gives me the solution for Visual Studio 2010 
// C++\MFC\ole\oleview\oleview.sln 
// 
// The following declaration comes from that sample. 
// The sample has also the source for the CLSID_ITypeLibViewer object but 
// unfortunately the method View is not implemented (the code in my sample says 
// "Implement interface viewer UI here."). 
DECLARE_INTERFACE_(IInterfaceViewer, IUnknown) 
{ 
    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE; 
    STDMETHOD_(ULONG,AddRef) (THIS) PURE; 
    STDMETHOD_(ULONG,Release) (THIS) PURE; 

    STDMETHOD(View) (HWND hwndParent, REFIID riid, LPUNKNOWN punk) PURE; 
}; 

std::string replace_all(const char* txt, const std::string& old_s, const std::string& new_s); 
std::string adapt(const char* txt); 
std::string now(); 
std::wstring stringify_hr(HRESULT hr); 

DWORD WINAPI scrape(LPVOID) 
{ 
    HWND hwnd = 0; 
    int guard = 100; 

    while(guard-- > 0 && (hwnd = ::FindWindowA(0,IDL_window_name)) == 0) { 
     ::Sleep(100); 
    } 

    if (guard <= 0) { 
     std::cerr << "No window found with name '" << IDL_window_name << "'\n"; 
     return __LINE__; 
    } 

    guard = 100; 
    const size_t sz = 100*1024; 
    char text[sz]; 
    do { 
     HWND parent_hwnd = ::GetDlgItem(hwnd,RICHEDIT_PARENT_ID); 
     if (parent_hwnd == 0) { 
     ::SendMessage(hwnd,WM_CLOSE,0,0); 
     std::cerr << "No parent with ID " << std::hex << "0x" 
        << RICHEDIT_PARENT_ID << " found in window with name '" 
        << IDL_window_name << "'\n"; 
     return __LINE__; 
     } 
     HWND richedit_hwnd = ::GetDlgItem(parent_hwnd,RICHEDIT_CONTROL_ID); 
     if (richedit_hwnd == 0) { 
     ::SendMessage(hwnd,WM_CLOSE,0,0); 
     std::cerr << "No richedit with ID " << std::hex << "0x" 
        << RICHEDIT_CONTROL_ID << " found in window with name '" 
        << IDL_window_name << "'\n"; 
     return __LINE__; 
     } 
     ::GetWindowTextA(richedit_hwnd,text,sz); 
     ::Sleep(100); 
    } while (guard-- > 0 && strlen(text) == 0); 

    if (guard <= 0) { 
     ::SendMessage(hwnd,WM_CLOSE,0,0); 
     std::cerr << "No IDL found in window with name '" 
       << IDL_window_name << "'\n"; 
     return __LINE__; 
    } 

    std::cout << "// IDL extracted from " << tlb << " by tlb2idl (" 
      << myself << ") on " << now() << "\n" << adapt(text); 

    ::SendMessage(hwnd,WM_CLOSE,0,0); 
    return 0; 
} 

int main(int argc, char* argv[]) 
{ 
    myself = argv[0]; 
    if (argc <= 1) { 
     std::cerr << "\nPrint to stdout the IDL extracted from file.tlb\n\nUsage:\n" 
       << myself << " file.tlb\n"; 
     return __LINE__; 
    } 

    DWORD exit_code = 0; 
    CHECK(::CoInitialize(0)); 
    { 
    CComPtr<ITypeLib> ptl; 
    tlb = argv[1]; 
    CHECK(::LoadTypeLib(std::wstring(tlb.begin(),tlb.end()).c_str(), &ptl)); 

    CComPtr<IInterfaceViewer> piv; 
    CHECK(::CoCreateInstance(CLSID_ITypeLibViewer, NULL, CLSCTX_SERVER, 
           IID_IInterfaceViewer, (void**)&piv)); 

    HANDLE th = ::CreateThread(0, 0, scrape, 0, 0, 0); 
    CHECK(piv->View(0,IID_ITypeLib,ptl)); 
    ::WaitForSingleObject(th,1000); 
    ::GetExitCodeThread(th,&exit_code); 
    } 
    ::CoUninitialize(); 
    return exit_code; 
} 

std::string replace_all(const char* txt, const std::string& old_s, const std::string& new_s) 
{ 
    std::string str(txt); 
    size_t start_pos = 0; 
    while((start_pos = str.find(old_s, start_pos)) != std::string::npos) { 
     str.replace(start_pos, old_s.length(), new_s); 
     start_pos += new_s.length(); 
    } 
    return str; 
} 

std::string adapt(const char* txt) 
{ 
    std::string str(replace_all(txt,"\r\n","\n")); 
    return replace_all(str.c_str(),"\r","\n"); 
} 

std::string now() 
{ 
    time_t szClock; 
    time(&szClock); 
    struct tm *newTime = localtime(&szClock); 
    return asctime(newTime); 
} 

std::wstring stringify_hr(HRESULT hr) 
{ 
    return _com_error(hr).ErrorMessage(); 
} 
2

यह ठीक है, बनाम 2012 तक केवल now समारोह को ठीक:

std::string now() 
{ 
    char buffer[32]; 
    errno_t errNum; 
    _time32(&aclock); 
    _localtime32_s(&newtime, &aclock); 

    errNum = asctime_s(buffer, 32, &newtime); 

    return buffer; 
} 

यह सुनिश्चित करना चाहिए कि आप नहीं खुला OLEVIEW है।

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