Assemblies nur einen Mausklick entfernt vom GAC
So, jetzt hab ich keine Lust mehr. Ich hab keine Lust mehr, Aufwand zu treiben, um Assemblies im GAC zu installieren: Consolenfenster auf, in das Assembly-Verzeichnis wecheln, gacutil aufrufen, beim Deinstallieren vergessen, dass der Dateiname ohne Extension geschrieben werden muss usw. usf.
Mit dem folgenden Utility ist das Problem einfürallemal gelöst. Und sie leistet noch mehr.
Installation:
Code in ein VB Console App Projekt einsetzen und compilieren. Einmal aufrufen. Das Programm trägt sich in der Registry ein, so dass es per Kontextmenü auf DLL-Dateien aufgerufen werden kann (Eintrag "GacUtils").
Anwendung:
-Kontextmenü im Explorer auf einer Assembly öffnen.
-GacUtils auswählen.
-Aus dem Menü im Konsolenfenster wählen. Das Programm kann Assemblies im GAC registrieren und sie wieder daraus entfernen. Gleichzeitig kann es auch das Verzeichnis der Assembly so registrieren, dass die Assemblies darin in der VS.NET "Add Reference" Dialogbox gelistet werden, wie die .NET Framework Assemblies (s. dazu: http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B306149).
Vielleicht baue ich auch noch die automatische Registrierung in COM+ ein. Mal schauen. Stay tuned.
Viel Spaß erstmal damit.
imports Microsoft.Win32
Module Module1
Sub Main(args() as string)
Dim shellKey as RegistryKey = Registry.ClassesRoot.CreateSubKey("dllfile\Shell\GacUtils\Command")
shellKey.SetValue("", string.Format("{0} ""%1""", Reflection.Assembly.GetExecutingAssembly.Location))
if args.Length <> 1 then
msgbox("Usage: GacUtils
exit sub
End If
dim ass as Reflection.Assembly = Reflection.Assembly.LoadFrom(args(0))
dim assName as String = ass.FullName.Split(",")(0)
Console.WriteLine("1=Register in GAC, 2=Unreg from GAC, 3=Affect 'Add references' dialog")
Console.Write(" multiple commands allowed: ")
dim cmds as String = console.ReadLine
dim p as Process
if cmds.IndexOf("2") >= 0 then
' delete from GAC
console.WriteLine("gacutil.exe " & string.Format("/u {0}", assName))
dim psi as New ProcessStartInfo("gacutil.exe", string.Format("/u {0}", assName))
psi.UseShellExecute = false
p = New Process
p.Start(psi)
if cmds.IndexOf("3") >= 0 then AffectAddRefListing(assName)
End If
if cmds.IndexOf("1") >= 0 then
' reg in GAC
console.WriteLine("gacutil.exe " & string.Format("/i {0}.dll", assName))
dim psi as New ProcessStartInfo("gacutil.exe", string.Format("/i {0}.dll", assName))
psi.UseShellExecute = false
p = new Process
p.Start(psi)
if cmds.IndexOf("3") >= 0 then AffectAddRefListing(assName, IO.Path.GetDirectoryName(args(0)))
End If
if cmds = "3" then
AffectAddRefListing(assName, IO.Path.GetDirectoryName(args(0)))
End If
console.readline
End Sub
private sub AffectAddRefListing(assemblyName as String, optional path as string = "")
console.WriteLine
if path <> "" then
console.WriteLine("Registering directory {0} for inclusion in 'Add references'", path)
dim refKey as RegistryKey = Registry.LocalMachine.CreateSubKey("Software\Microsoft\.NETFramework\AssemblyFolders\" & assemblyName)
refKey.SetValue("", path)
else
console.WriteLine("Unregistering directory {0} from 'Add references'", path)
Registry.LocalMachine.DeleteSubKey("Software\Microsoft\.NETFramework\AssemblyFolders\" & assemblyName)
End If
End Sub
End Module
Was mich ein wenig Zeit gekostet hat bei der Entwicklung: Wenn man ein Programm über das Kontextmenü startet, dann wir der Name, der Datei, auf die man geklickt hat, als erster Kommandozeilenparameter übergeben. Aber - und das ist der Trick - in seiner Kurzform: alle Namen sind im 8.3 Format. Damit kann gacutil.exe aber nichts anfangen.
Meine Tests hatte ich aus VS.NET mit einem vollständigen Pfad gemacht und alles funktionierte. Sobald ich dann aber über das Kontextmenü gegangen bin, lief es aber schief. Es hat einen Moment gedauert, bis ich darauf gekommen bin. Dafür habe ich dann auch gacutil.exe nicht in einem eigenen Konsolenfenster gestartet (psi.UseShellExecute=false), sondern im Fenster der Utility. Damit konnte ich dann erstmal überhaupt sehen, dass gacutil.exe verschnupft war.