Projekt Vorschau
23. Jan 2009 16:01 (bearbeiten)
Hier eine kleine Vorschau des Projekts an dem ich gerade arbeite.

Wie man hoffentlich sieht, handelt es sich um einen App Launcher, also so etwas wie Launchy. Wenn das Projekt fertig ist, soll das Programm aber mehr können, als nur Programme zu öffnen. Ich habe folgendes geplant:
- Starten, Beenden (und Bearbeiten) von Programmen
- Öffnen und Bearbeiten von Dateien
- Arbeiten mit markierten Dateien, Ordnern und Text
- Index Unterstützung, d. h. eigene Indexer können beliebige Objekte (wie Mails, Termine, usw.) indexieren, mit denen dann gearbeitet werden kann.
- Plugin Unterstützung, d. h. eigene Aktionen für Objekte können geschrieben werden. Beispielsweise könnte ein Mail Plugin E-Mails an indexierte Kontakte versenden, ein Packer-Plugin könnte markierte Ordner zipppen und via FTP-Plugin hochladen
- Skin Unterstützung
- Einfache(ste) Bedienung
Das wichtigste an diesem Programm wird die einfache Bedienung sein (auch wenn ich das als letzten Punkt in der Liste aufgeführt habe). So soll es mit nur wenigen Tastendrücken möglich sein, beispielsweise in Windows markierte Dateien zu zippen, zu verschlüsseln und anschließend auf einen FTP Server zu laden.
Dabei werden Plugins miteinander verknüpft die unterschiedliche Objekte an das nächste vom Benutzer ausgewählte Plugin zurückliefern.
Gemäß obigem Beispiel:
Ausgewählte Dateien -> Plugin: ZIP -> Gezippte Dateien -> Plugin: Verschlüsselung -> Verschlüsselte Dateien -> Plugin: FTP -> Auswahl FTP-Verbindungsdaten -> Fertig.
Wer Quicksilver für den Mac kennt, wird sicherlich viele Gemeinsamkeiten entdecken, was daran liegt, dass Quicksilver für mich eine Art inspirierende Vorlage war (was es für Windows Alternativen zu Quicksilver gibt, hat Lifehacker übrigens in diesem Artikel zusammengefasst).
Bis das alles so funktioniert wie ich das gerne hätte, muss ich aber noch einiges an Arbeit in das Projekt stecken. Ein Schritt in diese Richtung ist allerdings bereits gemacht.
VB .NET - Displayname / Beschreibung einer Datei ermitteln
21. Jan 2009 15:12 (bearbeiten)

Ich wollte für ein Programm an dem ich gerade arbeite statt der Dateiendung die Beschreibung zu der Dateiendung anzeigen.
Windows selbst zeigt diese Beschreibung beispielsweise in der Statusleiste des Explorers, wenn man auf eine bekannte Datei klickt. Beispielsweise bei "*.MOV" Dateien wäre die Anzeige (je nachdem mit welchem Programm die Endung verknüpft ist) "VLC media file (.mov)" oder "Quicktime Movie".
Nunja, als ich noch mit Delphi programmierte hätte ich hierzu die Shell32 SHGetFileInfo Funktion verwendet, doch unter .NET binde ich ungerne DLLs ein, also habe ich mir eine Funktion gebastelt, die die Info aus der Registry ausliest.
''' <summary> ''' Retrieve the Description/Displayname for a FileExtension ''' </summary> ''' <param name="aExtension">The Extension with a leading dot</param> ''' <returns>The Description of an Extension</returns> ''' <remarks></remarks> Public Shared Function GetDisplayNameFromExtension(ByVal aExtension As String) As String If aExtension = String.Empty Or Not aExtension.StartsWith(".") Then Return String.Empty ' First the get the key for the extension ' Extension is for example ".MOV", Key is "VLC.mov" Dim key As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot.OpenSubKey(aExtension) If key IsNot Nothing Then ' Then we look in the sub key for the description Dim SubkeyName As String = key.GetValue(String.Empty) Dim SubKey As Microsoft.Win32.RegistryKey = My.Computer.Registry.ClassesRoot.OpenSubKey(SubkeyName) If SubKey IsNot Nothing Then Return SubKey.GetValue(String.Empty) End If End If Return String.Empty End Function
Beispielaufruf:
Msgbox(GetDisplayNameFromExtension(".zip"))
VB .NET - Mit Lotus Notes E-Mails und Dateianhängen arbeiten
29. Dec 2008 12:05 (bearbeiten)
Mit den folgenden Klassen ist es möglich, aus einer Domäne heraus, eine beliebige Lotus Notes-Datenbank zu öffnen und alle E-Mails darin aufzulisten. Es werden dabei alle Dateianhänge aus den E-Mails in eine Liste gefügt.
Ein Beispielaufruf findet sich am Ende dieses Artikels.
Public Class NotesMail Public Subject As String Public From As String Public Body As String Public AttachmentFilenames As New List(Of Domino.NotesEmbeddedObject) End Class Public Class NotesMailCollection Inherits List(Of NotesMail) End Class Public Class MailAccount Public Host As String Public DatabaseFilename As String Public Password As String End Class Public Class NotesTools Public Shared Function GetMails(ByVal aMailAccount As MailAccount, ByVal MoveMails As Boolean) As NotesMailCollection Try Return _GetMails(aMailAccount, MoveMails) Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical) Return Nothing End Try End Function Private Shared Function _GetMails(ByVal aMailAccount As MailAccount, ByVal MoveMails As Boolean) As NotesMailCollection ' Die Session starten Dim Session As New Domino.NotesSession Session.Initialize(aMailAccount.Password) ' Datenbank öffnen Dim MailDB As Domino.NotesDatabase Dim MailServer As String = Session.GetEnvironmentString("MailServer", True) ' Dim DatabaseFilename As String = Session.GetEnvironmentString("MailFile", True) MailDB = Session.GetDatabase(MailServer, aMailAccount.DatabaseFilename) If Not MailDB.IsOpen Then MailDB.Open() End If Dim result As New NotesMailCollection Dim n_View As Domino.NotesView Dim n_ViewNav As Domino.NotesViewNavigator Dim n_ViewEntry As Domino.NotesViewEntry Dim n_Document As Domino.NotesDocument n_View = MailDB.GetView("($Inbox)") n_ViewNav = n_View.CreateViewNav n_ViewEntry = n_ViewNav.GetFirstDocument ' For all mails Do While Not (n_ViewEntry Is Nothing) n_Document = n_ViewEntry.Document Dim oAttachment As Domino.NotesEmbeddedObject If n_Document.HasEmbedded Then ' Add data to our object Dim nm As New NotesMail With nm .Body = n_Document.GetItemValue("Body")(0).ToString .Subject = n_Document.GetItemValue("Subject")(0).ToString .From = n_Document.GetItemValue("From")(0).ToString End With Dim fileNames As Object() = Session.Evaluate("@AttachmentNames", n_Document) For Each fileName As String In fileNames oAttachment = n_Document.GetAttachment(fileName) nm.AttachmentFilenames.Add(oAttachment) Next ' Add object to our list result.Add(nm) ' Remove from list If MoveMails Then ' n_Document.PutInFolder("Importiert " & Now.ToShortDateString, True) ' n_Document.RemoveFromFolder("($Inbox)") End If End If ' Next Mail n_ViewEntry = n_ViewNav.GetNextDocument(n_ViewEntry) Loop Return result End Function End Class
public Sub Test ' Account Einstellungen Dim acc As New MailAccount With acc .Host = "DominoServer" .DatabaseFilename = "mail\postfach.nsf" .Password = "meingeheimespasswort" End With ' GO! GO! GO! Alle Mails auflisten Dim lstMails As NotesMailCollection = NotesTools.GetMails(acc, False) For Each itm As NotesMail In lstMails ' Alle Anhänge in Verzeichnis abspeichern For Each att As Domino.NotesEmbeddedObject In itm.AttachmentFilenames strFilename = att.Name strDirectory = "C:\tmp" My.Computer.FileSystem.CreateDirectory(strDirectory) strFullFilename = strDirectory & "\" & strFilename att.ExtractFile(strFullFilename) Next Next end sub
Dupe Files Beispiel Tasks verfügbar
25. Oct 2008 16:59 (bearbeiten)

Für die im neuen Dupe Files eingeführte Tasks-Funktion (welche kurz gesagt der Automatisierung oder Skript-Steuerung von Dupe Files dient) habe ich nun vier Beispiel Tasks hochgeladen.
Um diese Tasks in Dupe Files zu testen, bitte das Archiv aus dem Download-Bereich von Dupe Files herunterladen und in das Dupe Files Verzeichnis entpacken. Dabei müsste der Entpacker automatisch einen Unterordner namens "Tasks" erstellen.
(Sollen die Tasks in einem anderen Verzeichnis abgelegt werden, so kann man dieses über den Menüpunkt "Optionen / Erweitert / Task Verzeichnis auswählen..." festlegen.)
Anschließend startet man Dupe Files und wählt über das Menü den Punkt "Optionen / Erweitert / Task Manager" aus.
Fortan gibt es im Menü unter "Datei" einen neuen Eintrag namens "Tasks", welcher alle Task-Dateien aus dem Task-Verzeichnis auflistet. Mit einem Klick auf einen solchen Eintrag wird die jeweilige Task-Datei ausgeführt.
VB .NET Programm zum Autostart in der Registrierung hinzufügen
29. Sep 2008 18:45 (bearbeiten)

Wer hätte das gedacht... unter .NET ist auch das mittlerweile ein Klacks...
Die folgende Prozedur fügt die aktuelle Application im Bereich CurrentUser in die Registrierung als Autostart Eintrag hinzu.
Der erste Wert "My.Application.Info.Productname" ist dabei der Name des Eintrags und dessen Wert ist der komplette Dateiname des Programms, den man via "System.Reflection.Assembly.GetEntryAssembly.Location" ermitteln kann.
Die Anführungszeichen vorne und hinten sind notwendig, wenn der Pfad zum Programm Leerzeichen enthält. Ansonsten würde Windows nur das Verzeichnis statt das Programm an sich öffnen.
Public Shared Sub AddToAutorun() Dim key As Microsoft.Win32.RegistryKey = My.Computer.Registry.CurrentUser.CreateSubKey("Software\Microsoft\Windows\CurrentVersion\Run") key.SetValue(My.Application.Info.ProductName, """" & System.Reflection.Assembly.GetEntryAssembly.Location & """") End Sub
VB .NET Prozess starten und auf sein Ende warten
16. Sep 2008 10:41 (bearbeiten)

Public Sub Execute(ByVal aFilename As String) Dim p As New Process p.StartInfo.FileName = aFilename p.StartInfo.UseShellExecute = True p.Start() p.WaitForExit() End Sub
Beispielaufrufe:
Execute("C:\test.doc") Execute("C:\test.pdf")
HowTo: VB .NET Enums mit Beschreibungen versehen
13. Sep 2008 13:41 (bearbeiten)
Dieses HowTo beschreibt, wie man Enums mit Beschreibungen versehen kann und diese Beschreibungen dann beispielsweise in einer Combobox oder Listbox anzeigt.
Beispiel vorher:

So sehen die Einträge bisher aus. Für den Endanwender ziemlich unpraktisch.
Beispiel nachher:

So sollen die Einträge später angezeigt werden.
Auf gehts!
Unser Beispiel enum:
Public Enum eFileListActionType eflatNone = 0 eflatCompress = 1 eflatDeleteForever = 2 eflatRecyclebin = 3 eflatReplaceWithTextfile = 4 eflatReplaceWithLink = 5 eflatReplaceWithZeroByteFile = 6 eflatMoveToDirectory = 7 End Enum
Um nun alle Namen diesse Enums beispielsweise in einer Combobox anzuzeigen, kann man bekanntermaßen folgendes machen:
Me.cbFileActionType.Items.AddRange([Enum].GetNames(GetType(eFileListActionType)))
Dann hätte man die Combobox mit den Werten eflatNone, eflatCompress usw. usf. gefüllt. Also praktisch so wie im ersten Bild oben. Dass das für den Endanwender nicht unbedingt ideal ist, sollte klar sein. Was wir also benötigen ist eine Möglichkeit den enums eine Beschreibung zu verpassen und diese Beschreibung stattdessen in die Combobox zu schreiben.
Zum Glück gibt es Reflection und das Attribut Description, das uns hierbei aus der Patsche hilft.
Also, wie geht das jetzt?
Zuerst müssen wir unseren enum um das Attribut Description ergänzen. Das sieht dann wie folgt aus:
Imports System.ComponentModel ' Wichtig! Public Enum eFileListActionType <Description("Keine")> _ eflatNone = 0 <Description("Komprimieren")> _ eflatCompress = 1 <Description("Für immer löschen")> _ eflatDeleteForever = 2 <Description("In Papierkorb verschieben")> _ eflatRecyclebin = 3 <Description("Durch Textdatei mit Link ersetzen")> _ eflatReplaceWithTextfile = 4 <Description("Durch Dateilink ersetzen")> _ eflatReplaceWithLink = 5 <Description("Durch 0-Byte Datei ersetzen")> _ eflatReplaceWithZeroByteFile = 6 <Description("In Verzeichnis verschieben")> _ eflatMoveToDirectory = 7 End Enum
Wie man sieht wird einfach der Tag
Zum Auslesen dieser Werte müssen wir nun Reflection bemühen:
Die erste Funktion gibt uns dabei eine Beschreibung für einen Enum-Wert zurück.
Public Shared Function GetEnumDescription(ByVal EnumConstant As [Enum]) As String Dim fi As Reflection.FieldInfo = EnumConstant.GetType().GetField(EnumConstant.ToString()) Dim attr() As System.ComponentModel.DescriptionAttribute = DirectCast(fi.GetCustomAttributes(GetType(System.ComponentModel.DescriptionAttribute), False), System.ComponentModel.DescriptionAttribute()) If attr.Length > 0 Then Return attr(0).Description Else Return EnumConstant.ToString() End If End Function
Für folgenden Befehl
Dim str as String = GetEnumDescription(eflatReplaceWithTextfile)
bekämen wir also das als Ausgabe:
Durch Textdatei mit Link ersetzen
Um das ganze noch etwas zu optimieren habe ich noch eine Hilfs-Funktion geschrieben, die alle Werte eines Enums übersetzt (also die Description einliest) und diese in ein String Array schreibt, das man dann einfach an die Combobox übergeben kann.
Public Shared Function GetEnumDescriptions(ByVal EnumConstant As Type) As String() Dim res(-1) As String For Each ec As [Enum] In [Enum].GetValues(EnumConstant) ReDim Preserve res(UBound(res) + 1) res(UBound(res)) = GetEnumDescription(ec) Next Return res End Function
Beispielanwendung:
Me.cbFileActionType.Items.AddRange(GetEnumDescriptions(GetType(eFileListActionType)))
Und damit hätten wir alle Beschreibungen eines Enums sauber in einer Combobox oder Listbox untegebracht.
