2012-02-09 11 views
5

In uno dei miei progetti, ho un'applicazione C# che sta utilizzando C++ DLL. Attualmente sul PC client stiamo registrando DLL C++ sui componenti COM nel registro in modo che li useremo in C#.Come utilizzare Dll COM di registrazione gratuita in dot net

imparo su NET che ci sia una soluzione Reg gratuita disponibile da Microsoft al link http://msdn.microsoft.com/en-us/library/ms973913.aspx

Ma dopo aver letto non ho avuto molto indizio perché la mia architettura dell'applicazione è diverso in quanto a seguito

  1. I Sto avendo 2 dll C++ LET SAY CPForms.dll e Rules.dll.
  2. Rule.dll è includere all'interno CPForms.dll
  3. ho 1 C# dll diciamo ConsumeForm.dll che sta usando CPForms.DLL
  4. Ho un altro C# Exe che sta usando ConsumeForm.dll

Il mio client sta aprendo solo C# Exe che a sua volta chiama ConsumeForm.dll che chiama ulteriormente CPForms.dll che mostra il modulo C++ (UI), c'è il pulsante di convalida, quando l'utente fa clic sul pulsante internamente utilizzando C++ Rules.dll. Attualmente sto registrando entrambe le DLL C++ nel registro.

Ora il client desidera solo eseguire il riferimento a Rule.dll come installazione RegFree, in quanto Rule.dll cambia frequentemente e il client non desidera annullare la registrazione e registrarsi nuovamente utilizzando l'account Admin.

Altro che quel client è OK con la registrazione di CPForms.dll.

La mia domanda è come possiamo generare file manifest? E come funzionerà nel mio scenario?

+0

L'articolo fornisce molti dettagli, che altro avete bisogno? Che cosa hai provato? Quali errori stai ottenendo? – Polyfun

+0

Suppongo che tu debba sapere se il manifest è collegato all'exe o a una delle DLL - immagino l'exe perché imposta il processo. A parte questo, la sintassi XML non è chiara? – Rup

+1

In realtà, è necessaria la registrazione gratuita? Finché rules.dll viene installato nello stesso posto (che richiederebbe comunque i diritti di amministratore, correggere?) E implementa gli stessi oggetti e le stesse interfacce con cui è costruito CPForms.dll, perché è necessario che non sia registrato e registrato nuovamente ogni tempo? (La domanda senza registrazione è di per sé interessante, però.) – Rup

risposta

8

Nota: Considerare l'utilizzo di un manifestarsi come nella risposta qui per una soluzione migliore:

Come farlo senza una manifesta

Il COM registro è un servizio che è opti onal per un server inproc.

Ancora: Non è necessario registrare un oggetto per crearlo. Se non è registrato, (e non in un manifest) non è possibile crearlo con CoCreateInstance, perché il registro (o manifest) è ciò che dice a CoCreateInstance quale DLL caricare.

Tuttavia è possibile crearlo con LoadLibrary, GetProcAddress, DllGetClassObject e IClassFactory::CreateInstance.

(Nota che non si otterranno servizi COM + e non è possibile creare oggetti out-of-process in questo modo o oggetti il ​​cui modello di threading non è compatibile con il thread di creazione. fallo per te queste cose diventano il tuo problema).

Il servizio fornito da CoCreateInstance consiste nel trovare la DLL corretta per la chiamata a LoadLibrary e chiamare semplicemente le altre funzioni. (E controllando i modelli di threading sono compatibili, creando sul thread appropriato e usando CoMarshalInterthreadInterfaceInStream/CoUnmarshalInterfaceAndReleaseStream per eseguire il marshalling dell'interfaccia se non lo sono. Sembra un sacco di lavoro ma se hai solo uno STA therad puoi praticamente ignorare tutto le questioni.)

Qualcosa del genere dovrebbe fare il trucco:

// Really you should break this up int GetClassFactoryFromDLL, then reuse the class factory. 
// But this is all from memory... 
// Load CLSID_MyID, from DLL pszMyDllPath 
typedef HRESULT __stdcall (*_PFNDLLGETCLASSOBJECT)(
    __in REFCLSID rclsid, 
    __in REFIID riid, 
    __out LPVOID *ppv 
) PFNDLLGETCLASSOBJECT; 

HRESULT CreateInstanceFromDll(LPCTSTR pszMyDllPath, CLSID clsidMyClass, IUknown** ppunkRet) 
{ 
    // Handle bad callers 
    *ppunkRet = NULL; 
    HANDLE hDLL = LoadLibrary(pszMyDllPath); 
    if(hDLL == NULL) 
    { 
     // Failed to load 
     return HRESULT_FROM_NTSTATUS(GetLastError()); 
    } 
    PFNDLLGETCLASSOBJECT pfnDllGetClassObject = GetProcAddress(hDLL); 
    if(pfnDllGetClassObject == NULL) 
    { 
     // Not a COM dll 
     HRESULT hrRet = HRESULT_FROM_NTSTATUS(GetLastError()); 
     FreeLibrary(hDLL);hDLL = NULL; 
     return hrRet; 
    } 
    IClassFactory* pClassFactory = NULL; 
    HRESULT hr = pfnDllGetClassObject(clsidMyClass, IID_IClassFactory, &pClassFactory); 
    if(FAILED(hr)){ 
     FreeLibrary(hDLL);hDLL = NULL; 
     return hr; 
    } 
    hr = pClassFactory->CreateInstance(NULL, IID_IUnknown, &ppunkRet); 
    pClassFactory->Release(); 
    if(FAILED(hr)) 
    { 
     *ppunkRet = NULL; 
     FreeLibrary(hDLL); 
     return hr; 
    } 
    return hr; 
} 

Nota: questo vi permetterà di creare l'oggetto. Tuttavia, se l'oggetto che chiami è di per sé affidabile, esso non funzionerà correttamente.

In particolare, molte implementazioni IDispatch si basano sulla libreria dei tipi. Se questo è il caso per un oggetto particolare, allora GetIDsOfNames e GetTypeInfo non riusciranno e non sarai in grado di utilizzare metodi con limite di lunghezza dell'oggetto. Ciò include l'uso di dynamic in C# e lingue dinamiche come Python.

Altri metodi come i metodi di interfaccia doppia e le interfacce che non ereditano da IDispatch potrebbero funzionare anche se i metodi IDispatch non funzionano.

Bottom line: per la COM senza registrazione per il lavoro, l'oggetto da istanziare non deve fare affidamento sulla propria registrazione.

+0

L'ho seguito per il mio caso (AutoItX.dll). L'oggetto infatti è stato creato. Ma non posso invocarlo non tramite interop Lib non tramite la riflessione. Quando registro C++ lib, tutto inizia a funzionare. –

+0

@DzmitryLahoda, non è possibile registrare un file C++ * .lib. Immagino tu voglia dire che hai registrato la DLL COM? Come l'hai registrato? – Ben

+0

Ci scusiamo per la fuorviante lib. Parlo di dll. Quando eseguo 'regsvr32 AutoItX3.dll/u ', quindi non posso richiamare alcun metodo sull'oggetto creato. È inutilizzabile Quando eseguo 'regsvr32 AutoItX3.dll' tutto funziona. Ma in questo caso non ho bisogno del codice fornito nel senso che il codice non è la risposta "Come usare la DLL COM di registrazione gratuita in dot net" per l'oggetto COM completamente valido. –

2

Per coloro che passeranno a questa domanda nella ricerca di Registration free COM dll in dot net, sono stato in grado di utilizzare AutoItX oggetto COM in modalità Reg Free da C# in questa risposta https://stackoverflow.com/a/19996424/173073. La creazione e l'utilizzo di altri oggetti Reg Free sarebbe simile.