Sto cercando di ottenere la COM senza registrazione che funziona con Excel come client e una DLL .NET come server. Attualmente sto semplicemente cercando di ottenere un proof-of-concept funzionante ma sto avendo problemi.COM RegFree che funziona da C#, NON funziona da VBA
Ovviamente, come sto usando Excel, non posso semplicemente utilizzare un soggiorno manifesta cliente a fianco l'eseguibile, quindi sto usando Microsoft.Windows.ActCtx
(link)
ho il cliente manifesta, assemblaggio manifesti, e dll tutto nella stessa posizione.
Sfortunatamente, ciò che funziona in C# non sembra funzionare in Excel/VBA e sono perplesso sul motivo. Mentre il client di test C# funziona perfettamente, VBA fornisce un errore , con il messaggio Metodo 'CreateObject' dell'oggetto "IActCtx" non riuscito.
ho una dll .NET (COMTestService.dll) esponendo una singola classe/interfaccia COM (COMTestObject
/ICOMTestObject
), come in questo caso:
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("EEE50CDF-D8EC-4F38-B986-C231EC45171E")]
public interface ICOMTestObject
{
[ComVisible(true)]
string GetString(int number);
}
[ComVisible(true), ClassInterfaceAttribute(ClassInterfaceType.None), ComDefaultInterface(typeof(ICOMTestObject))]
[Guid("6E54611B-8B56-49E0-9415-E59B0774A4BE")]
public class COMTestObject : ICOMTestObject
{
public COMTestObject()
{
}
public string GetString(int number)
{
return string.Format("The number is: {0}", number);
}
}
Il cliente manifesta (COMTestService_Client.manifest):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
manifestVersion="1.0"
xmlns="urn:schemas-microsoft-com:asm.v1" >
<assemblyIdentity
name="client"
version="1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity
name="COMTestService"
version="1.0.0.0"
processorArchitecture="msil" />
</dependentAssembly>
</dependency>
</assembly>
Il manifesto di montaggio (COMTestService.manifest):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
manifestVersion="1.0"
xmlns="urn:schemas-microsoft-com:asm.v1" >
<assemblyIdentity
name="COMTestService"
version="1.0.0.0"
processorArchitecture="msil" />
<clrClass
clsid="{6E54611B-8B56-49E0-9415-E59B0774A4BE}"
progid="COMTestService.COMTestObject"
threadingModel="Both"
name="COMTestService.COMTestObject"
runtimeVersion="v4.0.30319">
</clrClass>
<file
name="COMTestService.dll"
hashalg="SHA1">
</file>
</assembly>
Il codice client VBA:
Dim actCtx As Object
Set actCtx = CreateObject("Microsoft.Windows.ActCtx")
actCtx.Manifest = "...\COMTestService_Client.manifest"
Dim testObject As Object
Set testObject = actCtx.CreateObject("COMTestService.COMTestObject") 'This line throws...
Dim text As String
text = thing.GetString(42)
Debug.Print text
Il codice C# client:
var actCtxType = System.Type.GetTypeFromProgID("Microsoft.Windows.ActCtx");
dynamic actCtx = System.Activator.CreateInstance(actCtxType);
actCtx.Manifest = @"...\COMTestService_Client.manifest";
var type = System.Type.GetTypeFromProgID("COMTestService.COMTestObject");
dynamic obj = System.Activator.CreateInstance(type);
dynamic s = obj.GetString(42);
EDIT
La trama si infittisce ... Solo per divertimento, ho scritto un rapido COM-visibile, Classe helper registrata per eseguire la creazione dell'oggetto in C#, quindi passarla indietro, utilizzando un metodo lungo le righe di public object CreateObject(string manifestPath, string typeName)
Ora, chiamare questo da un exe C# funziona correttamente, ma la chiamata da VBA non riesce (80070002 di nuovo, messaggio: Il sistema non riesce a trovare il file specificato.). Ora sono ancora più confuso ...
Grazie in anticipo per qualsiasi aiuto, e se ho bisogno di fornire ulteriori informazioni fammelo sapere e sarò lieto di rendere omaggio!
Il percorso Manifesto che si supera non è valido, non è possibile utilizzare tre punti. E hai sicuramente bisogno di un percorso completo, non puoi prevedere quale sarà la directory di lavoro corrente. –
Mi dispiace confondere, era solo un segnaposto. Il percorso è lì per intero, ed è corretto. –