Obecnie staram się uzyskać wolny od rejestracji COM pracujący z programem Excel jako klientem i biblioteką .NET dll jako serwerem. Obecnie staram się po prostu uruchomić proof-of-concept, ale mam problem.RegFree COM działające z C#, NIE działające z VBA
Oczywiście, jak używam Excela, nie mogę po prostu użyć klienta oczywistego życia obok pliku wykonywalnego, więc używam Microsoft.Windows.ActCtx
(link)
Mam klienta manifest, montaż oczywisty i dll wszystko w tej samej lokalizacji.
Niestety, to, co działa w języku C#, nie działa w programie Excel/VBA i nie jestem pewien co do przyczyny. Podczas gdy klient testowy C# działa idealnie, VBA daje błąd z komunikatem Metoda "CreateObject" obiektu "IActCtx" nie powiodła się.
Mam dll .NET (COMTestService.dll) wystawienie jednej klasy/interfejsu COM (COMTestObject
/ICOMTestObject
), jak tutaj:
[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);
}
}
Klient manifest (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>
manifestu zespół (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>
VBA kod klienta:
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
C# Kod klienta:
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
Fabuła się zagęszcza ... Po prostu dla zabawy, napisałem krótki COM-widzialne, ZAREJESTROWANA klasa pomocnika, aby utworzyć obiekt w języku C#, a następnie przekazać go z powrotem, przy użyciu metody wzdłuż linii public object CreateObject(string manifestPath, string typeName)
Teraz wywoływanie tego z C# exe działa poprawnie, ale wywoływanie go z VBA nie działa (80070002 ponownie, wiadomość: System nie może odnaleźć określonego pliku.). Teraz jestem jeszcze bardziej zdezorientowany ...
Z góry dziękuję za wszelką pomoc, a jeśli potrzebuję dostarczyć więcej informacji, daj mi znać, a ja z przyjemnością Cię zobowiązam!
Przekazana ścieżka jest niepoprawna, nie można użyć trzech kropek. I zdecydowanie potrzebujesz pełnej ścieżki, nie możesz przewidzieć, jaki będzie bieżący katalog roboczy. –
Przepraszam za pomylenie, to był tylko symbol zastępczy. Ścieżka jest tam w całości i jest poprawna. –