Jak zdobyć serwer COM dla Excela napisany w VB.NET zainstalowane i zarejestrowane na liście serwerów automatyki?

Wersje

Excel 2007, Windows Vista, VB.NET, Visual Studio 2008 z. NET 3.5 sp2, pakiet instalacyjny MSI.

What I am trying to do

Mam UDF Excela, który jest napisany w VB.NET. jest wyświetlany jako serwer COM, ponieważ nie można tworzyć Excel UDFs bezpośrednio w językach. NET. Instalacja to prawdziwy ból, ponieważ żadne z ustawień instalacji nie wydaje się być całkiem poprawne; żadne z nich nie daje pakietu instalacyjnego, który umieszcza serwer COM na kliencie maszyna z zarejestrowanym serwerem, zarejestrowaną biblioteką typów i komponentem widocznym na liście serwerów automatyzacji programu Excel 2007.

What I ' ve tried

Oto ustawienia instalacji bibliotek typów, z ich wadami widocznymi w czasie kompilacji i instalacji:

VsdrfComSelfReg

  • brak ostrzeżenia podczas kompilacji projektu setup
  • moduł xxx. tlb nie został zarejestrowany. HRESULT -2147024703
  • składowe i GUID są ustawiane w rejestrze, ale komponent nie pojawia się na liście serwerów automatyzacji

VsdrfDoNotregister

  • brak ostrzeżenia podczas kompilacji
  • instalacja działa, ale oczywiście TLB nie jest zarejestrowany

VsdrfCOM

  • ostrzeżenie o czasie kompilacji: ostrzeżenie: nie można utworzyć informacji rejestracyjnych dla pliku o nazwie 'xxx. tlb'
  • biblioteka typu nie jest rejestrowana podczas instalacji

Prawidłowe ustawienie powinno być vsdrfCOM, jak wyjaśniono tutaj :

Q. Czy ktoś może powiedzieć, co robi vsdrfcom mean w projekcie instalacji Visual Studio? Jest on dostępny, gdy I sprawdź nieruchomość "rejestr" wśród właściwości dodanych plików w konfiguracji projekt.

A. Oznacza to, że Visual Studio będzie wyodrębnij dane rejestracyjne COM w build czas i umieścić go w pliku MSI (głównie tabela rejestru plików MSI, ale także tabelę klasową). Więc kiedy ty zainstaluj go twój kod nie musi samodzielnej rejestracji, ponieważ plik dostaje skopiowane na dysk i rejestr wpisy są tworzone. Będzie również create type library registration by dodawanie wpisu do TypeLib MSI stolik.

Wiele trudności wydaje się być specyficznych dla Visty. W szczególności, za pomocą narzędzia REGCAP do produkcji.Plik REG z a .Plik TLB nie działa w Vista. Gdyby nie to, być może ta rada byłaby przydatna . Zamiast tego produkuje puste .Pliki REG, gdy w ogóle działa. Próbowałem wszystkich porad w ten post StackOverflow . Ten post ma całkiem dobry opis problemu technicznego:

Wpisy w oknie dialogowym odnośniki pudełko pochodzi z HKCR\TypeLib klucz rejestru, nie z HKCR \ CLSID. Jeśli Twój montaż nie pojawia się w Okno dialogowe referencji, ale skompilowane biblioteki DLL może nadal korzystać z montażu COM, to oznacza, że klasy i interfejsy były prawidłowo zarejestrowany dla Twojego assembly, ale że biblioteka typu sama nie była.

Pytanie

Ktoś ma pomysł jak zrobić aby instalacja zarejestrowała komponent i bibliotekę typów? Nie mam dostępu do komputera z systemem Windows XP.


Opracowanie dlaczego to jest do bani

The .TLB nie jest konieczne, aby jakikolwiek skompilowany kod mógł go wywołać. Nie próbowałem wdrożyć dodatku do automatyzacji Excela, tak jak to robisz, ale domyślam się, że UDFs powinien ładować się i działać poprawnie.

Nie jest tak w Excelu.
  • użytkownik otwiera arkusz roboczy i próbuje odwołać się do UDF. Nie został znaleziony, ponieważ DLL nie jest ładowany. FAIL
  • użytkownik przechodzi do Home|Excel Options|Add-Ins / Excel Add-Ins+Go, a serwer COM nie jest wymieniony w oknie dialogowym Add-Ins. FAIL
  • użytkownik naciska Automation Servers, aby uzyskać listę dostępnych serwerów automatyzacji. DLL nie jest tam. FAIL
  • użytkownik wraca do okna dialogowego Dodatki i wybiera Przeglądaj, przechodzi do katalogu instalacyjnego i wybiera bibliotekę DLL ("XXX nie jest prawidłowym dodatkiem") lub bibliotekę typu ("wybrany plik nie zawiera nowego serwera automatyzacji lub nie masz wystarczających praw..."). FAIL

Z tego co wiem, użytkownik musi uruchomić regasm.exe z linii poleceń, aby udostępnić serwer Excel UDF/COM. Jak byś się czuł o mówieniu ludziom, aby uruchamiali regasm z linii poleceń, aby zainstalować dodatek do Excela?


Edycja 2009-10-04

Komentarze i wskazówki Mike ' a są niesamowite. Kluczową rzeczą, której nie wiedziałem, było to, że program instalacyjny ma wbudowany edytor rejestru do dodawania kluczy rejestru . AHA, i że funkcja instalacyjna z atrybutem ComRegisterFunctionAttribute nie była wywoływana przez Instalator Microsoft. Miałem już wskazówki dotyczące pisanie funkcji instalatora z cytowanych przez niego źródeł.

Author: Community, 2009-10-02

1 answers

Spróbowałem wdrożyć dodatek automatyzacji w weekend. Okazuje się, że jest to ogromnie skomplikowane (nie jest to dla Ciebie zaskoczeniem!) i nie mogłem znaleźć w Internecie absolutnie żadnych źródeł na temat tego, jak to zrobić prawidłowo. Brak

Istnieją źródła, które opisują, jak używać RegAsm, ale żadne, jak poprawnie użyć projektu instalacyjnego do zarejestrowania dodatku automatyzacji, który nieco różni się od standardowego dodatku COM.

Na szczęście udało mi się to rozwiązać. Oto czego się dowiedziałem:

Jeśli przeczytasz kilka artykułów na temat tworzenia i rejestracji dodatku C # automation, zobaczysz, że musisz dodać klucz rejestru o nazwie Programmable w HKEY\_CLASSES\_ROOT\CLSID\\{GUID}, Gdzie {GUID} jest identyfikatorem GUID twojej klasy COM-visible.

Jest to zazwyczaj wykonywane przez dodanie pary metod oznaczonych przezComRegisterFunctionAttribute iComUnregisterFunctionAttribute . Dobrym przykładem tego jest Artykuł pisanie niestandardowego arkusza Excel Funkcje w C# by Gabhan Berry:

// C#:

[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type type) {
  Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type));
}

[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type type) {
  Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type), false);
}

private static string GetSubKeyName(Type type) {
  string s = @"CLSID\{" + type.GUID.ToString().ToUpper() + @"}\Programmable";
  return s;
}

Przetłumaczone na VB.NET, działa to na:

'VB.NET:

<ComRegisterFunctionAttribute()> _
Public Shared Sub RegisterFunction(ByVal type As Type)
    Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type))
End Sub

<ComUnregisterFunctionAttribute()> _
Public Shared Sub UnregisterFunction(ByVal type As Type)
    Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type), false)
End Sub

Private Shared Function GetSubKeyName(ByVal type As Type) As String
    Dim s As String = ("CLSID\{" _
                + (type.GUID.ToString.ToUpper + "}\Programmable"))
    Return s
End Function

Metoda oznaczona {[8] } jest automatycznie wywoływana przez RegAsm, gdy zgromadzenie dla tej klasy jest zarejestrowane. Metoda oznaczona {[10] } jest automatycznie wywoływana przez RegAsm, gdy zgromadzenie dla tej klasy jest niezarejestrowane za pomocą przełącznika /u.

Problem polega na tym, że ComRegisterFunctionAttribute i ComUnregisterFunctionAttributecałkowicie ignorowane podczas instalacji przez Visual Studio Projekt Instalacji.

Na początku wydaje się to zaskakujące, ponieważ projekt instalacji Visual Studio uruchamia RegAsm za pomocą przełącznika /regfile w celu wygenerowania .Plik REG zawierający wszystkie wymagane klucze rejestru. To jest to .Plik REG, który jest następnie używany, a następnie.Pakiet MSI jest uruchamiany na stronie klienta. [49]}Z zbudować i wdrożyć. NET COM Assembly Phil Wilson:

Jak działa Visual Studio Zapisy na zajęcia COM? Dobrze., jeśli skonfigurowałeś Dziennik Fusion Viewer (Fuslogvw.exe w. NET 2.0 SDK) aby nagrać załadowanie zestawu, Uruchom to po zbudowaniu konfiguracji i zauważysz ten Regazm.exe faktycznie działa podczas tworzenia konfiguracji projekt. Jednak nie spełnia każda rejestracja. Dzieje się tak, że Visual Studio prowadzi Regasm z /regfile opcja tworzenia .plik reg zawierające wpisy rejestru wymagane do uzyskania informacji o Krok 1 i to .plik reg jest importowane wewnętrznie do konfiguracji projekt. Więc jeśli chcesz zobaczyć co wpisy w tematyce Rejestracja klas Studio stworzy w konfiguracji MSI, możesz uruchomić Regasm samodzielnie z /regfile opcja

Po uruchomieniu Regasma za pomocą przełącznika /regfile zauważyłem jednak, że przełącznik Programmable był włączony , a nie. Następnie umieściłem logowanie w moich metodach oznaczonych przez ComRegisterFunctionAttribute i ComUnregisterFunctionAttribute i odkryłem, że oba są wywoływane podczas uruchamiania RegAsm Bez /regfile switch, ale są Nie wywoływane podczas uruchamiania za pomocą przełącznika /regfile, ani nie są wywoływane podczas uruchamiania za pomocą.Pakiet MSI stworzony przez Visual Studio Setup Project.

Pliki pomocy dla Regasm.exe potwierdź to (podkreślenie dodane):

Możesz użyć opcji /regfile, aby wygenerować a .plik reg zawierający wpisy w rejestrze zamiast dokonywania zmiany bezpośrednio w rejestrze. Ty możliwość aktualizacji rejestru na komputerze importując .plik reg z Narzędzie edytora rejestru (Regedit.exe). zauważ, że ... plik reg nie zawiera żadnych aktualizacji rejestru, które mogą być dokonywane przez rejestr zdefiniowany przez użytkownika funkcje.

Rozwiązaniem jest zatem dodanie klucza Programmable. Można to zrobić w następujący sposób:

  1. W ramach projektu instalacyjnego Otwórz Edytor rejestru. Utwórz nowy klucz o nazwie CLSID pod HKEY_CLASSES_ROOT, klikając prawym przyciskiem myszy na folderze HKEY_CLASSES_ROOT, a następnie wybierając "Nowy", a następnie "Klucz".
  2. pod kluczem CLSID Dodaj nowy klucz o nazwie GUID, w tym nawiasy klamrowe.
  3. pod dodanym nowym kluczem GUID Dodaj klucz o nazwie Programmable. Nie musisz umieszczać żadnej wartości w tym kluczu; jednak musimy wymusić jego utworzenie. Dlatego kliknij prawym przyciskiem myszy na klawiszu Programmable i wybierz "okno Właściwości". Następnie zmień właściwość AlwaysCreate na True.

Gdy już to zrobisz, nie potrzebujesz już metod oznaczonych ComRegisterFunctionAttribute i ComUnregisterFunctionAttribute, ale i tak zostawiłbym je na te okazje, gdy intall przez RegAsm, a nie przez projekt Setup.

W tym momencie jesteście gotowi do startu. Zbuduj swoje rozwiązanie, a następnie kliknij prawym przyciskiem myszy projekt konfiguracji i wybierz "Build". Następnie możesz użyć utworzonej konfiguracji.exe i .Pliki MSI do wdrożenia na komputerze klienckim.

Należy jednak wziąć pod uwagę również to, że podczas dodawania dodatku automatyzacji za pomocą programu Excel okno dialogowe add-ins, zostanie wyświetlony komunikat o błędzie z informacją, że " Mscoree.dll nie można znaleźć, chcesz usunąć dodatek?"lub coś bardzo podobnego. Ten Komunikat o błędzie może zostać zignorowany, a twój dodatek będzie działał bez względu na to, na co odpowiesz, ale może być alarmujący dla klienta instalującego twój dodatek.

[49]}ta sytuacja i Wyjaśnienie, jak ją rozwiązać, jest dobrze opisane w artykule pisanie funkcji zdefiniowanych przez użytkownika dla programu Excel w. NET przez Erica Carter.

Problem polega na tym, że domyślną wartością klucza InprocServer32 jest po prostu mscorree.dll, co jest wystarczające dla. NET, aby go znaleźć, ale powoduje, że Excel skarży się. Rozwiązaniem jest upewnienie się, że domyślna wartość klucza InprocServer32 zawiera pełną ścieżkę do katalogu systemowego. Na przykład w 32-bitowych oknach powinno być to C:\Windows\system32\mscoree.dll. Ścieżka ta musi się jednak różnić w zależności od systemu, na którym jest zainstalowana. Więc ta ścieżka nie powinna być mocno zakodowana.

Eric Carter obsługuje to poprzez modyfikację metod oznaczonych przez ComRegisterFunctionAttribute i ComUnregisterFunctionAttribute, aby były następujące:
// C#: 

[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type type)
{

  Registry.ClassesRoot.CreateSubKey(
    GetSubKeyName(type, "Programmable"));
  RegistryKey key = Registry.ClassesRoot.OpenSubKey(
    GetSubKeyName(type, "InprocServer32"), true);
  key.SetValue("",
    System.Environment.SystemDirectory + @"\mscoree.dll",
    RegistryValueKind.String);
}

[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type type)
{

  Registry.ClassesRoot.DeleteSubKey(
    GetSubKeyName(type, "Programmable"), false);
}

private static string GetSubKeyName(Type type,
  string subKeyName)
{
  System.Text.StringBuilder s =
    new System.Text.StringBuilder();
  s.Append(@"CLSID\{");
  s.Append(type.GUID.ToString().ToUpper());
  s.Append(@"}\");
  s.Append(subKeyName);
  return s.ToString();
}  

Przetłumaczone na VB.NET, jest to równoważne:

'VB.NET:

<ComRegisterFunctionAttribute()> _
Public Shared Sub RegisterFunction(ByVal type As Type)
    Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable"))
    Dim key As RegistryKey = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true)
    key.SetValue("", (System.Environment.SystemDirectory + "\mscoree.dll"), RegistryValueKind.String)
End Sub

<ComUnregisterFunctionAttribute()> _
Public Shared Sub UnregisterFunction(ByVal type As Type)
    Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false)
End Sub

Private Shared Function GetSubKeyName(ByVal type As Type, ByVal subKeyName As String) As String
    Dim s As System.Text.StringBuilder = New System.Text.StringBuilder
    s.Append ("CLSID\{")
    s.Append(type.GUID.ToString.ToUpper)
    s.Append ("}\")
    s.Append (subKeyName)
    Return s.ToString
End Function

To działa, ale ma dokładnie ten sam problem, gdy zespół jest prawidłowo zarejestrowany podczas uruchamiania RegAsm na komputerze lokalnym, ale nie udaje się podczas próby użycia tego w projekcie instalacyjnym Visual Studio.

Rozwiązaniem jest dodanie własnych kluczy rejestru. Tym razem jednak będziemy musieli utworzyć domyślną wartość, która wykorzystuje Właściwość [SystemFolder], która jest równoważna wywołaniu System.Environment.SystemDirectory używanemu w kodzie Erica Cartera, powyżej.

Aby to zrobić, dodaj klucz o nazwie InprocServer32 pod swoim CLSID\\{GUID} kluczem, który stworzyliśmy wcześniej. Następnie kliknij prawym przyciskiem myszy na nowy klawisz InprocServer32 i wybierz "New", a następnie "String Value". Wynikiem będzie nowa wartość o nazwie New Value #1, ale będziesz w trybie edycji pozwalającym na jej zmianę nazwy. Co chcesz zrobić tutaj to usuń wszystkie znaki, a następnie naciśnij enter. Usuwając wszystkie znaki z nazwy, tworzysz wartość domyślną, a ikona dla wartości rejestru zostanie automatycznie zmieniona na " (Domyślnie)". Następnie kliknij prawym przyciskiem myszy tę domyślną ikonę wartości i wybierz "okno Właściwości". W oknie właściwości ustaw właściwość Value na "[SystemFolder]mscoree.dll" (bez cudzysłowów).

Możesz następnie kliknąć prawym przyciskiem myszy projekt konfiguracji i wybrać "Build", a następnie jesteś gotowy do wdrożenia.

Jest jeszcze jedna rzecz, o którą trzeba się martwić. Jeśli jesteś instalując program Excel 2007 lub nowszy, powyższe będzie działać w 100%. Jeśli jednak instalujesz w programie Excel 2003 lub poniżej, musisz dołączyć następujące elementy:]}

Poprawka: Dodatki, inteligentne dokumenty lub inteligentne tagi, które tworzysz za pomocą programu Microsoft Visual Studio 2005, nie działają w pakiecie Office

W tym samym czasie, w trakcie rozgrywki, gracz może wybrać jedną z dwóch postaci.

Jeśli nie zastosujesz tej poprawki, wszystko zarejestruje się poprawnie i możesz nawet dodaj swój dodatek automatyzacji pomyślnie-wszystko wydaje się w porządku-ale funkcje arkusza roboczego zawiodą i nadal otrzymasz #NAME? błędy w wyniku. (Ale znowu nie potrzebujesz tego w Excelu 2007 i nowszych.)

Tak więc, w końcu, TLB nie ma znaczenia. We wszystkich moich testach używałem RegAsm bez przełącznika / TLB i nie uwzględniłem żadnego TLB podczas rejestracji za pośrednictwem projektu instalacyjnego. Więc nie miałem problemów z robieniem tego z Visty, który ma problemy przy próbie dodania pliku TLB do Projekt Instalacji .

Mam nadzieję, że to pomoże, Hugh, i mam nadzieję, że każdy, kto może natknąć się na ten wątek w przyszłości...

Mike

 28
Author: Mike Rosenblum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:04