Code zu Anwendungen in .NET
- Einbetten von Win32-Ressourcendateien in Visual-Basic-Projekten
- Erkennen laufender Instanzen einer Anwendung
- Unterscheiden zwischen Kunde und Entwicklungsumgebung
- Ermitteln des Pfades der Anwendungsdatei
Einbetten von Win32-Ressourcendateien in Visual-Basic-Projekten
Während Visual Studio 2005 für C#-Projekte das Einbetten von Win32-Ressourcendateien über die Projekteigenschaften unterstützt (siehe Embedding multiple icons into .NET Executables), ist dies für Visual-Basic-Projekte nicht vorgesehen. Win32-Ressourcendateien können verwendet werden, um beispielsweise mehrere Symbole in das Programm einzubetten. Das im nachstehenden Listing wiedergegebene Makro SelectWin32Resource
schafft Abhilfe, indem es dem Benutzer ermöglicht, dem gerade geöffneten Projekt eine Win32-Ressourcendatei zuzuordnen. Win32-Ressourcendateien können mit Visual Studio erstellt und bearbeitet und Projekten hinzugefügt werden. Sie tragen die Dateinamenserweiterung .res
. Beim Kompilieren mit dem Compiler vbc
kann die Ressourcendatei im Parameter /win32resource
(-win32resource
) angegeben werden.
Erkennen laufender Instanzen einer Anwendung
Einige Anwendungen dürfen nur ein Mal zur gleichen Zeit ausgeführt werden. In Classic Visual Basic konnte die Eigenschaft App.PrevInstance
verwendet werden, um zu überprüfen, ob die Anwendung bereits ausgeführt wird. Im .NET Framework findet sich jedoch keinen adäquater Ersatz für diese Eigenschaft. Die folgende Funktionsprozedur PrevInstance
ersetzt die aus Classic Visual Basic bekannte Möglichkeit. Damit das Beispiel funktioniert, muß der Namensraum System.Diagnostics
importiert werden:
Nachteilig an der oben angegebenen Lösung ist, daß Prozeßnamen auf einem System nicht notwendigerweise eindeutig sein müssen. Um dieses Problem zu umgehen, wird zusätzlich zum Prozeßnamen auch der Ort verglichen, an dem die Anwendung abgelegt ist. Wird ein und die selbe Anwendung jedoch mehrfach aus unterschiedlichen Verzeichnissen gestartet, können die Instanzen einander nicht erkennen.
Weiters gilt es zu entscheiden, ob mehrere Benutzer gleichzeitig die Anwendung ausführen dürfen. Zu diesem Zweck bietet sich die Verwendung eines Mutex, das ist ein Mittel zu Synchronisation von Prozessen, an. Im zweiten Parameter des Konstruktors der Klasse Mutex
wird der Name des Mutex übergeben. Dieser Name sollte eindeutig sein, weshalb sich die Verwendung eines GUIDs als gute Wahl erweist.
Der Präfix Local\
gibt an, daß der Mutex nur für den aktuellen Benutzer gilt. Damit kann gesteuert werden, ob mehrere Benutzer in der Lage sein sollen, jeweils eine Instanz der Anwendung auszuführen, oder auf dem gesamten System nur eine Instanz existieren darf. Damit folgender Code funktioniert, ist es erforderlich, den Namensraum System.Threading
zu importieren:
Unterscheiden zwischen Kunde und Entwicklungsumgebung
Während des Entwickelns von Anwendungen häuft sich meist eine Menge an Code an, der nur bei verschiedenen Testdurchläufen kompiliert und ausgeführt werden soll. Wie zwischen Ausführung im Debugmodus und dem Releasemodus unterschieden werden kann, wird im folgenden Listing gezeigt. Damit das Beispiel funktioniert, muß die Konstante DEBUG
definiert sein. Dies erreicht man in der Entwicklungsumgebung von Visual Studio .NET durch Aktivieren der Option DEBUG
-Konstante definieren unter Konfigurationseigenschaften → Erstellen:
Alternativ kann man überprüfen, ob ein Debugger vorhanden ist. Wenn dies der Fall ist, dann wird es sich um den Entwicklungsrechner handeln, andernfalls um die Umgebung des Kunden. Auskunft über das Vorhandensein eines Debuggers gibt System.Diagnostics.Debugger.IsAttached
. Beim Entwickeln von Steuerelementen kommt es vor, daß sich diese in der Entwurfsansicht der Entwicklungsumgebung anders verhalten sollen, als im fertigen Produkt, wenn sie auf einem Formular plaziert werden. Diese Unterscheidung kann man anhand von Me.DesignMode
durchführen.
Ermitteln des Pfades der Anwendungsdatei
Unter Classic Visual Basic war das Ermitteln des Anwendungspfades, also des Verzeichnisses, in dem sich die ausgeführte Datei befindet, sehr einfach mittels App.Path
möglich. In .NET ist dies nicht so einfach. Vielfach wird auf Application.StartupPath
aus dem Namensraum System.Windows.Forms
zurückgegriffen. Diese Methode kann aber beim Start von Anwendungen über Dateiverknüpfungen unter älteren Windows-Versionen angeblich falsche Werte zurückgeben. Außerdem zahlt es sich bei Konsolenanwendungen bzw. Klassenbibliotheken nicht aus, die doch recht große Datei System.Windows.Forms.dll
zu laden.
Eine einfache Lösung, die auch in Klassenbibliotheken den gewünschten Pfad zurückgibt, findet sich über Reflection. Dabei wird der Pfad der ausführenden Assembly ermittelt und zurückgegeben. Damit folgender Code funktioniert, müssen die Namensräume System.IO
und System.Reflection
importiert werden. Um den Pfad der ausgeführten Assembly zu ermitteln, reicht es aus, GetEntryAssembly
durch GetExecutingAssembly
zu ersetzen: