2014-04-03 21 views
1

在我們的頭文件中,我們有類定義,其中GroupInitEditInitprotected。我希望能夠通過從C#的解決方案增加了生成GrpSvr.tlb文件的引用,所以我改變了這些公共訪問這些方法...如何編輯COM庫來提供方法來訪問

#if !defined(AFX_GRPCALL_H__FFB54BC3_B15E_11D1_99BC_0000E803C444__INCLUDED_) 
#define AFX_GRPCALL_H__FFB54BC3_B15E_11D1_99BC_0000E803C444__INCLUDED_ 
#if _MSC_VER >= 1000 
#pragma once 
#endif 
class CGrpCall : public CCmdTarget 
{ 
    DECLARE_DYNCREATE(CGrpCall) 
    CGrpCall(); // protected constructor used by dynamic creation 
// Attributes 
public: 
// Operations 
public: 
    public: 
    virtual void OnFinalRelease(); 
    DECLARE_MESSAGE_MAP() 
    DECLARE_OLECREATE(CGrpCall) 
    afx_msg BSTR GroupInit(LPCTSTR bstrIniFile, BOOL bDiagErr, BOOL bProcErr); 
    afx_msg BSTR EditInit(LPCTSTR bstrIniFile); 
    DECLARE_DISPATCH_MAP() 
    DECLARE_INTERFACE_MAP() 
    // Implementation 
protected: 
    virtual ~CGrpCall(); 
}; 
#endif // !defined(AFX_GRPCALL_H__FFB54BC3_B15E_11D1_99BC_0000E803C444__INCLUDED_) 

的GrpSvr.cpp代碼

IMPLEMENT_DYNCREATE(CGrpCall, CCmdTarget) 
CGrpCall::CGrpCall() { 
    EnableAutomation(); 
    AfxOleLockApp(); 
    Initialize(FALSE); 
} 

CGrpCall::~CGrpCall() { 
    AfxOleUnlockApp(); 
    GroupTerm(); 
} 

void CGrpCall::OnFinalRelease() { 
    CCmdTarget::OnFinalRelease(); 
} 

BEGIN_MESSAGE_MAP(CGrpCall, CCmdTarget) 
END_MESSAGE_MAP() 

BEGIN_DISPATCH_MAP(CGrpCall, CCmdTarget) 
    DISP_FUNCTION(CGrpCall, "GroupInit", GroupInit, VT_BSTR, VTS_BSTR VTS_BOOL VTS_BOOL) 
    DISP_FUNCTION(CGrpCall, "EditInit", EditInit, VT_BSTR, VTS_BSTR) 
END_DISPATCH_MAP() 

static const IID IID_IGrpCall = 
{ 0xffb54bc2, 0xb15e, 0x11d1, { 0x99, 0xbc, 0x0, 0x0, 0xe8, 0x3, 0xc4, 0x44 } }; 

BEGIN_INTERFACE_MAP(CGrpCall, CCmdTarget) 
    INTERFACE_PART(CGrpCall, IID_IGrpCall, Dispatch) 
END_INTERFACE_MAP() 

IMPLEMENT_OLECREATE(CGrpCall, "GrpSvr.GrpCall", 0xffb54bc2, 0xb15e, 0x11d1, 
    0x99, 0xbc, 0x0, 0x0, 0xe8, 0x3, 0xc4, 0x44) 

BSTR CGrpCall::GroupInit(LPCTSTR bstrIniFile, BOOL bDiagErr, BOOL bProcErr) { /* Some Code */ } 
BSTR CGrpCall::EditInit(LPCTSTR bstrIniFile) { /* Some Code */ } 

我現在可以通過添加在C#中的引用,並做

GrpSvr.GrpCall g = new GrpSvr.GrpCall(); 
g.GroupInit(this.strCommandFilePath, true, true); 

但是看到這些方法,這是給

在mscorlib.dll中發生未處理的「System.Runtime.InteropServices.COMException」類型異常。 ...類沒有註冊...

爲了能夠直接調用方法,我該怎麼做這段代碼?

謝謝你的時間。


編輯。下面的評論我在​​打開了.tlb文件,我得到下面的輸出

// Generated .IDL file (by the OLE/COM Object Viewer) 
// 
// typelib filename: GrpSvr.tlb 

[ 
    uuid(FFB54BB5-B15E-11D1-99BC-0000E803C444), 
    version(1.0), 
    custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 134218331), 
    custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1396349854), 
    custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, "Created by MIDL version 8.00.0603 at Tue Apr 01 11:57:34 2014 
") 

] 
library GrpSvr 
{ 
    // TLib :  // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046} 
    importlib("stdole2.tlb"); 

    // Forward declare all types defined in this typelib 
    dispinterface IGrpCall; 

    [ 
     uuid(FFB54BC2-B15E-11D1-99BC-0000E803C444) 
    ] 
    dispinterface IGrpCall { 
     properties: 
     methods: 
      [id(0x00000001)] 
      BSTR GroupInit(
          BSTR bstrIniFile, 
          VARIANT_BOOL bDiagErr, 
          VARIANT_BOOL bProcErr); 
      [id(0x00000002)] 
      BSTR EditInit(BSTR bstrIniFile); 
      [id(0x00000003)] 
      BSTR GroupTerm(); 
      [id(0x00000004)] 
      BSTR GetVars(
          short* sNumInp, 
          short* sLastOP, 
          short* sLenDiag, 
          short* sLenProc, 
          short* sNumDiag, 
          short* sNumProc, 
          BSTR* bstrInpFile, 
          BSTR* bstrOutFile, 
          BSTR* bstrDbFile); 
      [id(0x00000005)] 
      BSTR GetFldDets(
          short sIndex, 
          BSTR* bstrFldName, 
          short* sNumFld, 
          short* sFldNum, 
          short* sFldLen, 
          short* sFldType, 
          short* sFldPos); 
      [id(0x00000006)] 
      long SetVersionDate(BSTR bstrDate); 
      [id(0x00000007)] 
      BSTR GetLabel(
          short sFldNum, 
          BSTR bstrCode); 
      [id(0x00000008)] 
      BSTR BatchProcess(long* lNRecs); 
      [id(0x00000009)] 
      BSTR FldEdit(
          short sFld, 
          BSTR bstrVal); 
      [id(0x0000000a)] 
      BSTR GroupRecord(BSTR bstrRec); 
      [id(0x0000000b)] 
      BSTR GetReport(); 
      [id(0x0000000c)] 
      BSTR GetFldVal(
          short sFld, 
          long sOcc, 
          BSTR* bstrVal); 
      [id(0x0000000d)] 
      BSTR EditRec(BSTR bstrRec); 
      [id(0x0000000e)] 
      BSTR MakeRec(
          short sFld, 
          short sOcc, 
          BSTR bstrVal); 
      [id(0x0000000f)] 
      BSTR GetRecord(); 
      [id(0x00000010)] 
      BSTR GetCount(long* lRecs); 
      [id(0x00000011)] 
      BSTR WriteReport(); 
      [id(0x00000012)] 
      BSTR Test(VARIANT_BOOL bTest); 
      [id(0x00000013)] 
      BSTR GetFldVal2(
          short sFld, 
          short sOcc); 
    }; 

    [ 
     uuid(FFB54BC4-B15E-11D1-99BC-0000E803C444) 
    ] 
    coclass GrpCall { 
     [default] dispinterface IGrpCall; 
    }; 
}; 
+0

您必須註冊服務器。從提升的命令提示符運行Regsvr32.exe。這通常在ATL項目中自動完成。但是,如果需要運行Visual Studio,因此它可以寫入註冊表。右鍵單擊VS快捷方式,然後單擊「以管理員身份運行」。 –

+0

我已經完成了這項工作,我的帳戶是'管理員',因此它始終運行提升。我已經使用regsvr32註冊了GrpSvr.dll,並使用regtlibv12註冊了GrpSvr.tlb(這樣我可以在C#中添加對它的引用)。這些方法都通過intellisense顯示,但發生錯誤。我想知道是否需要向'BEGIN_INTERFACE_MAP(CGrpCall,CCmdTarget)'東西添加任何東西。我試圖在網上找到關於如何做到這一點的材料,但實際上沒有什麼......謝謝你的時間。 – MoonKnight

+0

完全太多的貨物崇拜,我不買。不*使用regtlib,這是不必要的。 *不*假設你運行提升。在您的問題中發佈項目的.rgs文件的內容。使用SysInternals的Process Monitor來查看實際發生的情況。查看運行Regsvr32.exe時看到的跟蹤,以查看寫入的註冊表項。看看你運行客戶端時看到的蹤跡,看看它在看什麼鍵。 –

回答

1

由於這是一個MFC工程,​​/IMPLEMENT_OLETYPELIB已經存在於類聲明/實現。正常註冊類型庫需要其他一些額外的步驟:

TN065: Dual-Interface Support for OLE Automation Servers

我建議使用OLEVIEW工具進行故障排除。在樹中找到您的"GrpSvr.GrpCall"對象,右鍵單擊它並嘗試從那裏創建。檢查相應的註冊表項是否指向正確的.DLL(和.TLB,如果單獨註冊)。