Benutzer mit den meisten Antworten
dll, regasm signatur & co

Frage
-
Hallo an Alle,
ok... klingt nach einem ganzen Fragenkatalog... ist es auch... freue mich aber auch über Teilantworten!
Zum Thema: Wollte mir eine dll erstellen, die ich auch woanders (z. Bsp. in Access) verwenden kann, also nicht einfach nur mal schnell ins vorhandene Projekt einbinden. Ich mach mich frisch ans Werk... neues Projekt als Klassenbibliothek.
Der Code ist ja kein Geheimnis. Will einfach nur ein Verzeichnis- oder Dateiarray bekommen:
namespace FoldersAndFiles { public class Verzeichnisstrukturen { public string[] ZeigeAlleUnterOrdnerVon(string startordner) { return (Directory.GetDirectories(startordner)); } public string[] ZeigeAlleDateienVon(string ordner) { return (Directory.GetFiles(ordner)); } } }
So weit, so gut... nun dachte ich, ich muss die dll noch veröffentlichen, gehe, wie gewohnt über Projekt -> Eigenschaften, nur, geht das bei dll's offenbar nicht. Google und Co empfehlen mir regasm.... aber..
1. obwohl ich VS 2012 Prof habe, regasm kennt mein Rechner nicht.
2. wenn er es kennen würde... hab mich mal umgesehen, die einzige dll meiner Wahl liegt im Debug Ordner. Wie würde denn dann die Anweisung für regasm lauten müssen? So:
regasm D:\CS12Projekte\DLL\FoldersAndFiles\FoldersAndFiles\bin\Debug\FoldersAndFiles.dll /codebaseoder muss ich die dll vorher in irgendein bestimmtes Verzeichnis kopieren?
3. Unter Projekt -> Erstellen habe ich (weil die dll ja in Access genutzt werden soll) den Haken bei: Für Com-Interop registrieren gesetzt. Hoffe, das ist ok.
4. Bin dann noch über die Signierung gestolpert. Ist die unbedingt notwendig? Zumal, wenn die dll auch auf fremden Rechnern eingesetzt werden soll? (Und überhaupt.... wie registriere ich die dll auf Fremdrechnern?!)
4a Falls ich die Signatur brauche... (Assembly signieren). Ich hab da jetzt mal auf Neu geklickt, einen Namen und ein Passwort vergeben und eine entsprechende pfx erzeugt, aber.... was fange ich jetzt damit an?
5 Falls alle diese Fragen geklärt wären, reicht es dann, wenn ich in Access einen Verweis auf diese dll setze, um die darin enthaltenen, öffentlichen Prozeduren aufrufen zu können?
Ja.... puh... ich weiß, jede Menge Fragen, aber ich denke, die gehören irgendwie doch zusammen.
Schon mal Danke für Eure Anteilnahme!
Freundliche Grüße
Ralf
Antworten
-
Hi Ralf,
Es wird - wie bereits geschrieben - Administratorzugriff benötigt. Es reicht also nicht aus, als Administrator angemeldet zu sein, man muss alle Befehle mit ungefiltertem Admin-Token ausführen.
Dazu navigierst Du im Start-Menü zu "Developer-Eingabeaufforderung für Visual Studio 2012". Aus dem Kontextmenü wählst Du dann "Als Administrator ausführen". Nun hast Du einen Admin-Prompt.
1. Kopiere die Ausgabedateien ins Installationsverzeichnis, z.B.:
xcopy "[Pfad]\bin\Debug\MySuperLib.*" "%commonprogramfiles%\Ralf A\MySuperLib\"
2. Entferne vorsichtshalber eine evtl. vorherige, mißlungene Registrierung:
regasm /u "%commonprogramfiles%\Ralf A\MySuperLib\MySuperLib.dll"
3. Registriere die Klassenbibliothek erneut:
regasm "%commonprogramfiles%\Ralf A\MySuperLib\MySuperLib.dll" /codebase
4. Überprüfe die Registrierung:
Kannst Du bestätigen, ob die Registrierung bei dir ebenfalls erfolgreich durchgeführt wird? - Die restlichen Fragen können wird anschließend ggf. besprechen.
Gruß
Marcel
- Bearbeitet Marcel RomaModerator Freitag, 13. September 2013 16:10
- Als Antwort markiert Ralf A Freitag, 13. September 2013 21:15
-
Hi Ralf,
zu deinen Fragen:
1. Wie erstelle ich denn ein MSI-Paket für eine dll?
Die Dateieerweiterung .msi steht für Microsoft Software Installation und bezeichnet ebenfalls ein Dateiformat, das von Windows Installer verwendet wird. Ein MSI-Paket ist im Grunde nichts weiter als eine relationale Datenbank mit Tabellen, die Informationen über die zu installierenden Features beinhalten. Man kann deshalb alles Mögliche in ein MSI-Paket packen: Grafiken, Dokumentationsdateien, Registry-Einstellungen usw., es muss also nicht unbedingt eine EXE-Datei involviert sein. Die bekanntesten Windows Installer-Tools sind wohl InstallShield, AdvancedInstaller und WiX, ein vollständigere Auflistung findest Du hier.
AdvancedInstaller z.B. kann COM-fähige .NET-Assemblies automatisch registrieren. Aber im Hintergrund macht es auch nur das, was man auch manuell tun würde. Zuerst führt es diese Zeile aus:
regasm.exe [Assembly] /codebase /regfile
Der Befehl resultiert in eine [Assembly].reg-Datei mit den notwendigen Registrierungsinformationen. Diese extrahiert dann Advanced Installer und fügt sie der Installationsroutine hinzu, ersetzt dabei den Pfad zur Assembly durch eine Variable.
2. Welches ist denn das "gewünschte" Verzeichnis?
Das von dir für die Installation gewählte Verzeichnis.
Hintergrund: Das Debug-Verzeichnis ist nur zur Entwicklungszeit verfügbar, ist somit für eine Verteilung uninteressant. Das System32-Verzeichnis ist vor allem für Bibliotheken interessant, die systemnahe Bibliotheken referenzieren, deshalb würde meine Wahl bei einer einfachen COM-Komponente eher einen anderen Speicherort vorziehen. Vielleicht ein Unterverzeichnis zu %commonprogramfiles%, oder %programfiles% oder gar im %userprofile%. Hängt davon ab, was genau diese Bibliothek tun soll. [Außerdem gibt es noch die Möglichkeit des registrierungsfreien COM, aber das führt hier zu weit.]
3. GAC-Installation
Wenn die .NET-Assembly auch von anderen .NET-Assemblies referenziert werden soll, würde ich sie im GAC installieren. In diesem Fall entfällt der /codebase flag, da während der Bindungsphase die fusion-Engine das GAC als erstes durchsucht.
Deine Befehlszeile von oben verwendet die x64-Version von gacutil. Ich weiss nicht, ob das intendiert ist, hast Du denn ein x64-Build von MySuperLib.dll? Wenn nicht, dann solltest Du die x86-Version von gacutil verwenden. Ab .NET 4.0 gibt es nicht wirklich einen Unterschied zwischen den zwei gacutil-Versionen, aber man sollte schon immer die plattformspezifischen Tools verwenden.
Ein schönes Wochenende auch dir,
Marcel- Als Antwort markiert Ralf A Sonntag, 15. September 2013 11:13
Alle Antworten
-
Hallo Ralf,
Da Du Access erwähnst, gehe ich davon aus, dass Du über COM auf die Klassenbibliothek zugreifen möchtest. Für COM ist es eigtl. egal, in welchem Verzeichnis die Bibliothek liegt (solange die DLL registriert ist). Für .NET-Anwendungen aber nicht. Wenn Du die Klassenbibliothek in mehreren .NET-Projeken verwenden möchtest, dann wäre der beste Speicherort der GAC (über gacutil registrieren). Falls Du nur über COM zugreifen möchtest, dann könntest Du die Klassenbibliothek z.B. konventionsgemäß im Ordner %COMMONPROGRAMFILES%\<Firma>\<Produkt> speichern.
Hast Du deine Klassenbibliothek schon COM-sichtbar gemacht (Projekteigenschaften > Anwendung > Assemblyinformationen)? - Wenn ja, dann schau doch bitte in den Projekteigenschaften nach, ob die COM-Registrierung ebenfalls eingeschaltet ist (Projekteigenschaften > Erstellen > Ausgabe > Für COM-Interop registrieren). Während der Entwicklung ist das alles was Du brauchst.
Für das Deployment würde ich ein MSI-Paket erstellen, das die Registrierung autom. übernimmt.
Solltest Du hingegen manuelles Deployment vorziehen, dann kopiere die Datei ins gewünschte Verzeichnis und verwende regasm.exe um die Klassenbibliothek zu registrieren (C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe).
Wenn Du /codebase bei der Registrierung angibst oder wenn Du die DLL mittels gacutil.exe ins GAC installieren willst, muss die Assembly mit einem starken Namen signiert werden (Projekteigenschaften > Signierung > Assembly signieren > <Neu...>). Verwechsle diese Signatur nicht mit der Authenticode-Signatur (über ein Software-Herausgeberzertifikat).
Für die COM-Registrierung muss Visual Studio als Administrator gestartet werden.
Um zu überprüfen, ob die Registrierung stattgefunden hat, kannst Du in VS auf Verweis hinzufügen klicken und im COM-Reiter überprüfen, ob eine entspr. Bibliothek zu finden ist.Hier der für Interop mit Access adaptierte .NET-Code:
using System; using System.IO; using System.Runtime.InteropServices; namespace MySuperLib { [InterfaceType(ComInterfaceType.InterfaceIsDual)] [Guid("B69A2294-04E4-466B-919F-B4126C20CC64")] // über Tools > GUID erstellen > 5. public interface IVerzeichnisstrukturen { string[] ZeigeAlleUnterOrdnerVon(string startordner); string[] ZeigeAlleDateienVon(string ordner); } [ClassInterface(ClassInterfaceType.None)] [Guid("AE3EBE70-9324-40F0-A37E-557BE5367AD8")] [ProgId("MySuperLib.Verzeichnisstrukturen")] public class Verzeichnisstrukturen : IVerzeichnisstrukturen { public string[] ZeigeAlleUnterOrdnerVon(string startordner) { string[] arrayToReturn = Directory.GetDirectories(startordner); return arrayToReturn; } public string[] ZeigeAlleDateienVon(string ordner) { string[] arrayToReturn = Directory.GetFiles(ordner); return arrayToReturn; } } }
VBA-Testcode:
Option Compare Database Option Explicit ' Extras > Verweise... > MySuperLib als Verweis hinzufügen Public Sub ZeigeAlleUnterordnerVon(verzeichnis As String) Dim vzs As New MySuperLib.Verzeichnisstrukturen Dim res() As String, i As Integer res = vzs.ZeigeAlleUnterordnerVon(verzeichnis) For i = 0 To UBound(res) Debug.Print res(i) Next End Sub
Gruß
Marcel
-
Marcel,
...Du bist der Größte! ;)
Was wäre dieses Forum ohne Dich?
Ich muss das alles zwar noch mal in Ruhe durchgehen, denke aber, Dank Deiner Hilfe kann ich das Problem als gelöst betrachten. Falls nicht, dann melde ich mich diesbezüglich noch einmal.
Nochmals vielen Dank an Dich!
Ralf
- Bearbeitet Ralf A Donnerstag, 12. September 2013 07:37
-
Hi Marcel,
muss doch noch einmal nachfragen, stelle mich offenbar zu blöd an... und hab auch zu wenig Ahnung...:(
Zunächst aber die Antwort auf Deine Frage "Hast Du deine Klassenbibliothek schon COM-sichtbar gemacht ".... ja, hab ich.
"Für das Deployment würde ich ein MSI-Paket erstellen, das die Registrierung autom. übernimmt."
...aber hier geht es schon los. Wie erstelle ich denn ein MSI-Paket für eine dll? oder
"Solltest Du hingegen manuelles Deployment vorziehen, dann kopiere die Datei ins gewünschte Verzeichnis und verwende regasm.exe "
Welches ist denn das "gewünschte" Verzeichnis? Das, wo die meisten dll's liegen, also in der System32? Oder da, wo meine Anwendung liegt? Aber scheinbar ist das egal, solange ich weiß, wo ich die dll abgelegt habe... oder muss ich sie definitiv aus dem bin/Debug Verzeichnis rausnehmen? Was allerdings wenig einleuchtend wäre...
regasm Hab ich auch ausgeführt. Über prompt hab ich folgendes eingegeben:
SET GACUTIL="C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\x64\gacutil.exe"
SET REGASM="C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe"%REGASM% D:\CS12Projekte\DLL\bin\Debug\FoldersAndFiles.dll /tlb: C:\Users\Ralf\FoldersAndFiles.tlb /verbose
%GACUTIL% /i C:\Users\Ralf\FoldersAndFiles.dllHab es statt mir /verbose auch mit /codebase versucht. Oder das Zielverzeichnis C:\UsersRalf\ ganz simpel auf C:\ gesetzt. Das Ergebnis war immer das gleiche. Die Fehlermeldung:
Die D:\CS12Projekte\.....dll-Assembly kann nicht registriert werden - Zugriff verweigert. Stellen Sie sicher, dass Sie die Anwendung als Administrator ausführen. Der Zugriff auf den Registrierungsschlüssel "HKEY_CLASSES_ROOT\FoldersAndFiles.Verzeichnisstrukturen" wurde verweigert
Mit Powershell war es nicht besser...
Ja wie denn das? Ich bin definitiv als Admin angemeldet. Hab extra nochmal in den Konteneinstellungen nachgesehen. Das verwirrt mich jetzt echt. Oder gibt es bei Win7 Prof, 64 bit einen noch geheimeren Zugang?
Langer Rede, kurzer Sinn, ich krieg es nicht gebacken.
Die nächsten Fragen lauten somit:
- War das vorgehen erst einmal soweit in Ordnung?
- Wo liegt der Detailfehler?
Besten Dank schon mal im Voraus!
Ralf
- Bearbeitet Ralf A Freitag, 13. September 2013 13:57
-
Hi Ralf,
Es wird - wie bereits geschrieben - Administratorzugriff benötigt. Es reicht also nicht aus, als Administrator angemeldet zu sein, man muss alle Befehle mit ungefiltertem Admin-Token ausführen.
Dazu navigierst Du im Start-Menü zu "Developer-Eingabeaufforderung für Visual Studio 2012". Aus dem Kontextmenü wählst Du dann "Als Administrator ausführen". Nun hast Du einen Admin-Prompt.
1. Kopiere die Ausgabedateien ins Installationsverzeichnis, z.B.:
xcopy "[Pfad]\bin\Debug\MySuperLib.*" "%commonprogramfiles%\Ralf A\MySuperLib\"
2. Entferne vorsichtshalber eine evtl. vorherige, mißlungene Registrierung:
regasm /u "%commonprogramfiles%\Ralf A\MySuperLib\MySuperLib.dll"
3. Registriere die Klassenbibliothek erneut:
regasm "%commonprogramfiles%\Ralf A\MySuperLib\MySuperLib.dll" /codebase
4. Überprüfe die Registrierung:
Kannst Du bestätigen, ob die Registrierung bei dir ebenfalls erfolgreich durchgeführt wird? - Die restlichen Fragen können wird anschließend ggf. besprechen.
Gruß
Marcel
- Bearbeitet Marcel RomaModerator Freitag, 13. September 2013 16:10
- Als Antwort markiert Ralf A Freitag, 13. September 2013 21:15
-
Hi Marcel,
offen gestanden, ich bin sprachlos. Es gibt nur wenige, die so geduldig, ausführlich und vor allem verständlich auf Fragen antworten wie Du. Dank Deiner Hilfe hab sogar ich das jetzt hinbekommen. Womit Deine Frage beantwortet wäre... ;) Ja, habe sie in der Registry im Verzeichnis Improcserver32 als Assembly gefunden. Hätte ich allein nie hinbekommen. Und hab das, trotz umfangreicher Recherche im Netz, auch nie so verständlich zu sehen bekommen. Großen Dank nochmal an Dich!
Mir war gar nicht klar, dass es ein Admintoken gibt, oder dass ich Attribute hätte setzen müssen (und vor allem nicht welche).
Meine Hauptfragen hast Du beantwortet, das Hauptproblem gelöst und der Thread könnte geschlossen werden, aber ich nehme Dein Angebot, zur Besprechung der restlichen Fragen gern an. Allerdings nur, wenn es Dir nichts ausmacht. Ich bin so schon happy und wirklich zufrieden mit Deinen bisherigen Antworten!. Du solltest mich nicht mit Extrabonbons verwöhnen...:D
So oder so.... noch mal vielen Dank an Dich und ein schönes Wochenende!
Ralf
-
Hi Ralf,
zu deinen Fragen:
1. Wie erstelle ich denn ein MSI-Paket für eine dll?
Die Dateieerweiterung .msi steht für Microsoft Software Installation und bezeichnet ebenfalls ein Dateiformat, das von Windows Installer verwendet wird. Ein MSI-Paket ist im Grunde nichts weiter als eine relationale Datenbank mit Tabellen, die Informationen über die zu installierenden Features beinhalten. Man kann deshalb alles Mögliche in ein MSI-Paket packen: Grafiken, Dokumentationsdateien, Registry-Einstellungen usw., es muss also nicht unbedingt eine EXE-Datei involviert sein. Die bekanntesten Windows Installer-Tools sind wohl InstallShield, AdvancedInstaller und WiX, ein vollständigere Auflistung findest Du hier.
AdvancedInstaller z.B. kann COM-fähige .NET-Assemblies automatisch registrieren. Aber im Hintergrund macht es auch nur das, was man auch manuell tun würde. Zuerst führt es diese Zeile aus:
regasm.exe [Assembly] /codebase /regfile
Der Befehl resultiert in eine [Assembly].reg-Datei mit den notwendigen Registrierungsinformationen. Diese extrahiert dann Advanced Installer und fügt sie der Installationsroutine hinzu, ersetzt dabei den Pfad zur Assembly durch eine Variable.
2. Welches ist denn das "gewünschte" Verzeichnis?
Das von dir für die Installation gewählte Verzeichnis.
Hintergrund: Das Debug-Verzeichnis ist nur zur Entwicklungszeit verfügbar, ist somit für eine Verteilung uninteressant. Das System32-Verzeichnis ist vor allem für Bibliotheken interessant, die systemnahe Bibliotheken referenzieren, deshalb würde meine Wahl bei einer einfachen COM-Komponente eher einen anderen Speicherort vorziehen. Vielleicht ein Unterverzeichnis zu %commonprogramfiles%, oder %programfiles% oder gar im %userprofile%. Hängt davon ab, was genau diese Bibliothek tun soll. [Außerdem gibt es noch die Möglichkeit des registrierungsfreien COM, aber das führt hier zu weit.]
3. GAC-Installation
Wenn die .NET-Assembly auch von anderen .NET-Assemblies referenziert werden soll, würde ich sie im GAC installieren. In diesem Fall entfällt der /codebase flag, da während der Bindungsphase die fusion-Engine das GAC als erstes durchsucht.
Deine Befehlszeile von oben verwendet die x64-Version von gacutil. Ich weiss nicht, ob das intendiert ist, hast Du denn ein x64-Build von MySuperLib.dll? Wenn nicht, dann solltest Du die x86-Version von gacutil verwenden. Ab .NET 4.0 gibt es nicht wirklich einen Unterschied zwischen den zwei gacutil-Versionen, aber man sollte schon immer die plattformspezifischen Tools verwenden.
Ein schönes Wochenende auch dir,
Marcel- Als Antwort markiert Ralf A Sonntag, 15. September 2013 11:13
-
Hi Marcel,
ich ziehe meinen Hut vor Deinem Wissen, Können und vor allem vor Deiner Hilfsbereitschaft sowie der Gründlichkeit und Mühe, die Du Dir dabei machst! [img]http://www.greensmilies.com/smile/smiley_emoticons_seb_hut1.gif[/img]
...falls Du mal ein Fachbuch herausbringst, sag mir Bescheid. Das will ich haben! :)
Zu 3.) Das mit dem x64 Build war (in diesem Fall) schon in Ordnung. Ich habe einen 64 bit Rechner, und auf dem sollte es auch (vorerst) bleiben. Aber... Danke für den Hinweis!
Alles Gute für Dich!
Ralf