Actualmente estoy tratando de obtener un COM libre de registro que trabaje con Excel como cliente y un .NET dll como servidor. Actualmente estoy tratando de hacer funcionar una prueba de concepto pero estoy teniendo problemas.RegFree COM trabajando desde C#, NO trabajando desde VBA
Obviamente, como estoy usando Excel, no puedo simplemente usar la vida manifiesta cliente junto con el ejecutable, por lo que estoy usando Microsoft.Windows.ActCtx
(link)
hago que el cliente manifiesta, manifiesto del ensamblado, y DLL todos en el mismo lugar
Desafortunadamente, lo que funciona en C# no parece funcionar en Excel/VBA y no estoy seguro del motivo. Mientras que el cliente de prueba C# funciona perfectamente, VBA da un error , con el mensaje El método 'CreateObject' del objeto 'IActCtx' falló.
Tengo una DLL .NET (COMTestService.dll) la exposición de una sola clase/interfaz de COM (COMTestObject
/ICOMTestObject
), como en este 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);
}
}
El cliente manifiesta (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>
El manifiesto de ensamblado (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>
El código de cliente 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
El código C# cliente:
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);
EDITAR
La trama se complica ... Sólo por diversión, me escribió una rápida COM-visible, Clase de ayudante REGISTRADO para hacer la creación de objetos en C#, luego pasarla de nuevo, usando un método como public object CreateObject(string manifestPath, string typeName)
Ahora, llamar a esto desde un C# exe funciona bien, pero llamarlo desde VBA falla (80070002 otra vez, mensaje: El sistema no puede encontrar el archivo especificado.). Ahora estoy aún más confundido ...
Gracias de antemano por cualquier ayuda, y si necesito proporcionar más información solo házmelo saber y estaré encantado de complacerlo!
La ruta de manifiesto que pasa no es válida, no puede usar tres puntos. Y definitivamente necesita una ruta completa, no puede predecir cuál será el directorio de trabajo actual. –
Perdón por confundir, eso era solo un marcador de posición. El camino está ahí completo, y es correcto. –