2012-03-21 17 views
10

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!

+0

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. –

+0

Przepraszam za pomylenie, to był tylko symbol zastępczy. Ścieżka jest tam w całości i jest poprawna. –

Odpowiedz

0

Nie mogę powiedzieć, że kiedykolwiek próbowałem użyć tej techniki i zrobiłem wiele instalacji na przestrzeni lat. Zastanawiam się, dlaczego nie zarejestrować swojego serwera .NET COM Visible? Regasm ma tendencję do tworzenia bardzo czystej i lekkiej rejestracji COM w rejestrze. Znacznie czystszy niż stary niezarządzany program DllRegisterServer().

+0

Niestety jest to wdrażane bez możliwości uprawnień administratora, więc regresja jest niedostępna w oknie ... –

+0

Projekty InstallShield MSI mają atrybut ".NET COM Visible", który wywołuje RegAsm w czasie kompilacji, aby wyodrębnić dane meta COM. W przypadku instalacji na użytkownika klucze COM są zapisywane w HKCU \ Software \ Classes zamiast w HKLM \ Software \ Classes. Nie widzę, jak rejestracja w stylu RegAsm w stylu COM nie wchodzi w rachubę. –

2

Za pomocą Monitora procesu odkryłem, że biblioteka dll była poszukiwana w C:/Program Files/Microsoft Office/Office11 /. Przeniosłem wszystkie moje biblioteki DLL tam i błąd zniknął.

W sidenote, jeśli ktoś wie, jak powiedzieć programowi Excel, aby nie szukał tam plików, ale zamiast tego, gdzie został znaleziony plik .tlb, jestem zainteresowany. (Próbowałem już dodać ścieżkę do zmiennej środowiskowej PATH)

Powiązane problemy