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 ", MsgBoxStyle.Information)
            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.

1 Comment

Comments have been disabled for this content.