Displaying posts tagged as -net

Countdown Programm aktualisiert

29. Dec 2009 2:29 (edit)

Da das Jahr sich ja langsam aber sicher dem Ende neigt, ich Urlaub und zudem ein kleines Projekt zum Überarbeiten gesucht habe, bot es sich irgendwie an, Countdown zu aktualisieren.

  • Neu: Neue Aktion "Schriftfarbe zufällig ändern"
  • Neu: Anzeigeformat der Restzeit konfigurierbar
  • Neu: Schrift lässt sich auf Wunsch frei im Fenster positionieren. Hierzu mit Strg-Linksklick das Label positionieren oder mit der Tastatur via (Strg) und hoch/runter links/rechts
  • Neu: Interne Programmprotokollierung mit NLog
  • Verbessert: Alle Aktionen in Threads ausgelagert
  • Verbessert: Vollbild Modus überdeckt nun in allen Windows Versionen die Taskleiste korrekt und kann mit Escape geschlossen werden.
  • Verbessert: Korrekte Positionierung des Textes beim Ändern der Fenstergröße
  • Verbessert: Shortcuts für Notebooks ohne Ziffernblock angepasst
  • Verbessert: Kontextmenü aufgeräumt
  • Änderung: Modifikator-Taste geändert von Umschalt auf Steuerung.
  • Weitere kleinere Änderungen

Die neue Version von Countdown findet sich auf der Programmseite.

Mit NLog unter .NET protokollieren

08. Nov 2009 14:58 (edit)

Wer kennt das nicht? Mal eben ein kleines Programm geschrieben, an die Anwender verteilt und auf irgendeinem Rechner läuft das Programm nicht wie es soll.

Nun ist guter Rat teuer, denn welcher Programmierer gibt sich schon die Mühe in kleinere Tools eine ausgefeilte Protokoll-Funktion zu implementieren um dem Fehler gegebenenfalls schnell auf die Schliche zu kommen?

Mit NLog ist das anders. NLog ist ein Framework fürs Protokollieren unter .NET. Ist der Verweis zu NLog im Projekt erst einmal eingebunden, kann man mit einer Zeile wie

  1. Me.Logger.Warn(ex.Message)

eine Exception inklusive aufrufender Methode und kompletter Exception-Fehlerausgabe protokollieren.

Auf der NLog Webseite ist zwar relativ einfach beschrieben, wie man das Framework in das eigene Projekt einbaut, was ich hier im folgenden allerdings beschreibe, ist noch etwas kürzer, da ausschließlich für VB .NET.

Verweis einbinden

Bevor man das NLog Framework verwenden kann, muss man als Verweis die NLog.dll zum Projekt hinzufügen. Hierzu lädt man auf der Codeplex Projekteseite von NLog am einfachsten die vorkompilierte DLL herunter (man kann sich natürlich auch den Quellcode schnappen und selbst kompilieren :-).

Konfigurationsdatei erstellen

Es gibt zwar viele Varianten, wie NLog nach einer Konfigurationsdatei sucht, aber die einfachste ist, eine Datei namens "nlog.config" im Programmverzeichnis zu erstellen.

Als Inhalt dieser Datei empfehle ich für Anfänger folgendes:

  1. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  3. <targets>
  4. <target name="file" xsi:type="File"
  5. layout="${longdate} ${logger} ${callsite} ${message} ${exception:Format=tostring} ${newline}"
  6. fileName="${basedir}/${windows-identity:domain=false}.log"/>
  7. </targets>
  8. <rules>
  9. <logger name="*" minlevel="Debug" writeTo="file"/>
  10. </rules>
  11. </nlog>

In der Konfigurationsdatei wird mit dem Tag "Target" bestimmt, wohin der Protokolleintrag wandern soll.

Das Target vom Typ "file" beispielsweise schreibt alle Einträge in eine Datei. Außer der Möglichkeit Protokolleinträge in Dateien zu schreiben, bietet NLog dem Benutzer auch eine Mail, ein Textcontrol, ein Netzwerk, das Windows Ereignisprotokoll einen Webservice und eine per ADO.NET ansprechbare Datenbank als Ziel an. Darüberhinaus ist es auch noch möglich, sich eigene Targets, wie beispielsweise einen FTP-Server, zu schreiben. Und natürlich kann man auch mehrere Targets gleichzeitig befüllen.

Im obigen Beispiel wir als Ziel eine Datei verwendet, deren Dateiname aus dem Windows-Benutzername besteht. Die Datei wird dabei automatisch in Unterordnern gelagert, deren Name aus dem aktuellen Datum generiert wird.

Der Tag "Layout" beschreibt dabei, wie die Protokolleinträge formatiert bzw. ergänzt werden.

Der Platzhalter "${longdate}" wird durch das Datum, der Platzhalter "${logger}" durch den Namen der Logging-Klasse, "${callsite}" durch die aufrufende Methode und schließlich "${message}" als die eigentliche Protokollmeldung ersetzt.

Der Zusatz "${exception:Format=tostring}" regelt, dass Exceptions inklusive der Detailmeldungen erfasst werden. Der Platzhalter "${newline}" schließlich, fügt einen Zeilenumbruch am Ende der Meldung ein.

Verwendung

Im Programm selbst, greift man auf NLog beispielsweise so zu:

  1. Public Logger as NLog.Logger = NLog.LogManager.GetCurrentClassLogger
  2. ...
  3. Me.Logger.Info("Dies ist ein Test")
  4. Me.Logger.Warn(ex.Message)

VB .NET: MSI Pakete automatisch installieren

09. Jun 2009 6:41 (edit)

Dieses kleine Modul installiert alle MSI-Pakete, die im aktuellen Programmverzeichnis gefunden werden im "Quiet"-Modus, d. h. ohne irgendwelche Nachfragen.

  1. Module modMain
  2.  
  3. Sub Main()
  4. Console.WriteLine("Installiere MSI Pakete...")
  5. Try
  6. RunAll()
  7. Catch ex As Exception
  8. Console.WriteLine("Fehler: " & ex.Message)
  9. Console.WriteLine("Bitte drücken Sie eine beliebige Taste zum Beenden.")
  10. Console.ReadLine()
  11. End Try
  12. Console.WriteLine("Installation abgeschlossen.")
  13. End Sub
  14.  
  15. ''' <summary>
  16. ''' Nach MSI-Paketen im aktuellen Verzeichnis (dieser EXE) suchen und alle MSI-Pakete
  17. ''' nacheinander ausführen.
  18. ''' </summary>
  19. ''' <remarks></remarks>
  20. Public Sub RunAll()
  21.  
  22. Dim lstFiles As Collections.ObjectModel.ReadOnlyCollection(Of String) = _
  23. My.Computer.FileSystem.GetFiles(Environment.CurrentDirectory, FileIO.SearchOption.SearchTopLevelOnly, "*.MSI")
  24.  
  25. For Each fn As String In lstFiles
  26. ExecuteAndWait(fn, "/quiet")
  27. Next
  28.  
  29. End Sub
  30.  
  31. ''' <summary>
  32. ''' Einen Prozess starten und auf dessen Ende warten
  33. ''' </summary>
  34. ''' <param name="ProcessPath">Name der Datei die ausgeführt werden soll</param>
  35. ''' <param name="Arguments">Optionale Parameter</param>
  36. ''' <remarks></remarks>
  37. Public Sub ExecuteAndWait(ByVal ProcessPath As String, Optional ByVal Arguments As String = "")
  38.  
  39. Dim proc As System.Diagnostics.Process
  40.  
  41. Try
  42. proc = New System.Diagnostics.Process()
  43. proc.StartInfo.FileName = ProcessPath
  44. proc.StartInfo.Arguments = Arguments
  45. proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal
  46. proc.Start()
  47. proc.WaitForExit()
  48. proc.Close()
  49. Catch ex As Exception
  50. MsgBox(String.Format("Prozess {0} konnte nicht gestartet werden. Fehler: {1}.", ProcessPath, ex.Message))
  51. End Try
  52.  
  53. End Sub
  54.  
  55. End Module

Tags ¦ , , , , und
0 Comments

HowTo: VB .NET Barcodes und Reports

27. Apr 2009 9:54 (edit)

Wir haben in den letzten Tagen nach einer Möglichkeit gesucht, in Crystal Reports Barcodes anzuzeigen, und zwar so, dass man sie nachher mit einem Barcode Scanner auch wieder einlesen kann.

Um dies zu tun habe ich nach einer kostenlosen Open-Source Variante gesucht.

Nach unzähligen Versuchen fand ich dann endlich das Barcode Rendering Framework ZEN auf Codeplex.com.

Das Framework kann über Verwendung der drei DLLs als Verweis recht simpel eingebunden werden. Es beherrscht folgende Varianten:

  • Code 11 (mit oder ohne Prüfsumme)
  • Code 25 standard/interleaved (mit oder ohne Prüfsumme)
  • Code 39 (mit oder ohne Prüfsumme)
  • Code 93 (nur mit Prüfsumme)
  • Code 128 (nur mit Prüfsumme)
  • Code EAN 13 (nur mit Prüfsumme)
  • Code EAN 8 (nur mit Prüfsumme)
  • Code PDF417 2D (mit Prüfsumme)

Im Prinzip wird im Code unten folgendes gemacht:

  • Barcode Bild erstellen und als temporäre Datei abspeichern
  • Das abgespeicherte Bild in ein Dataset laden, damit wir es im Report anzeigen können

Das Dataset, das der Report verwendet, besitzt nur zwei Spalten. Eine namens ImageFilename (vom Typ String) welche den Dateinamen des temporären Barcode Bildes enthält, und eine namens Image (vom Typ base64Binary bzw. System.Byte()), die das Bild selbst enthält.

  1. Public Sub ShowRepDemo()
  2.  
  3. ' Barcode-Bild erstellen und als temporäre Datei abspeichern
  4. Dim tmpfile As String
  5. tmpfile = My.Computer.FileSystem.GetTempFileName & ".bmp"
  6. Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum.Draw("Dies ist ein Barcode 128 Test", 30).Save(tmpfile)
  7.  
  8. Dim ds As New dsMain
  9.  
  10. ' Barcode Bild in Datatable schreiben
  11. ds.dtImage.AdddtImageRow(tmpfile, Nothing)
  12.  
  13. ' Image binär in Datatable schreiben
  14. For index As Integer = 0 To ds.Tables(0).Rows.Count - 1
  15. If Not String.IsNullOrEmpty(ds.Tables(0).Rows(index).Item("ImagePath").ToString) Then
  16. LoadImage(ds.Tables(0).Rows(index), "Image", ds.Tables(0).Rows(index).Item("ImagePath").ToString)
  17. End If
  18. Next
  19.  
  20. ' Report öffnen
  21. Dim rptdoc As New repDemo
  22. rptdoc.SetDataSource(ds.Tables(0))
  23.  
  24. Dim rv As New CrystalDecisions.Windows.Forms.CrystalReportViewer
  25. rv.Dock = DockStyle.Fill
  26. Me.Controls.Add(rv)
  27. rv.ReportSource = rptdoc
  28.  
  29. End Sub
  30.  
  31. ' Bild in DataTable schreiben
  32. Private Sub LoadImage(ByVal objDataRow As DataRow, ByVal strImageField As String, ByVal FilePath As String)
  33. Try
  34. Dim fs As System.IO.FileStream = New System.IO.FileStream(FilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
  35. Dim Image() As Byte = New Byte(fs.Length) {}
  36. fs.Read(Image, 0, CType(fs.Length, Integer))
  37. fs.Close()
  38. objDataRow(strImageField) = Image
  39. Catch ex As Exception
  40. Throw New Exception(ex.Message)
  41. End Try
  42.  
  43. end Sub

Tags ¦ , , , und

VB .NET - E-Mails mit Indy empfangen und Anhänge abspeichern

21. Apr 2009 19:50 (edit)

Um in VB .NET E-Mails zu versenden, verwendet man am besten den Namespace Net.Mail.

Leider gibt es in VB .NET allerdings noch keine Möglichkeit, E-Mails zu empfangen um beispielsweise die Dateianhänge abzuspeichern.

Um dieses Problem zu beseitigen, zeige ich im Folgenden, wie man mit Hilfe von Indy eine E-Mail von einem POP3 Postfach herunterlädt und eventuelle Anhänge der E-Mails auf dem Dateisystem abspeichert.

Wichtig, zur Verwendung von Indy muss als Referenz die Indy.Sockets und Mono.Security DLL in das Projekt eingebunden werden.

Zu erst einmal eine kleine Hilfsklasse, in der wir die Konten-Informationen unseres POP3 Kontos ablegen:

  1. Public Class MailAccount
  2.  
  3. ''' <summary>
  4. ''' Hostname des E-Mail Servers
  5. ''' </summary>
  6. ''' <remarks></remarks>
  7. Public Host As String
  8.  
  9. ''' <summary>
  10. ''' Benutzername des E-Mail Kontos
  11. ''' </summary>
  12. ''' <remarks></remarks>
  13. Public Username As String
  14.  
  15. ''' <summary>
  16. ''' Benutzer-Passwort des E-Mail Kontos
  17. ''' </summary>
  18. ''' <remarks></remarks>
  19. Public Password As String
  20.  
  21. End Class

Nun der interessantere Teil. Die Methode SaveAllAttachments speichert vom übergebenen Mailkonto alle Anhänge aller E-Mails temporär auf der Festplatte lokal ab.

Hierfür verbinden wir uns erst mit dem Mailkonto, ermitteln dann die Menge aller E-Mails auf dem Postfach und iterieren dann durch jede einzelne E-Mail.

Eine E-Mail besteht aus mehreren sogeannten Messageparts. Ist ein Messagepart vom Typ Octet-Stream, handelt es sich um einen Dateianhang, den wir ja abspeichern wollen.

  1. Public Class IndyTools
  2.  
  3. ''' <summary>
  4. ''' Speichert alle Dateianhänge des Postfachs aAccount im Servicevertrags-Verzeichnis des jeweils ermittelten Servicevertrags
  5. ''' </summary>
  6. ''' <param name="aAccount">Postfach Konto</param>
  7. ''' <remarks></remarks>
  8. Public Sub SaveAllAttachments(ByVal aAccount As MailAccount)
  9.  
  10. Dim tempfilename As String
  11. Dim IsAttachment As Boolean
  12.  
  13. Dim o As NewIndy.Sockets.TIdNetNativeComponent
  14. Dim p As NewIndy.Sockets.POP3(o)
  15. Dim att As Indy.Sockets.Attachment
  16.  
  17. ' Verbindungsdaten an Indy übergeben
  18. With p
  19. .Host = aAccount.Host
  20. .Username = aAccount.Username
  21. .Password = aAccount.Password
  22. End With
  23.  
  24. Try
  25.  
  26. Try
  27. ' Verbinden und Mailmenge feststellen
  28. p.Connect()
  29.  
  30. ' Anzahl er Mails auf dem Postfach ermitteln
  31. Dim Amount As Integer = p.CheckMessages
  32.  
  33. ' Für alle Mails
  34. For i As Integer = 1 To Amount
  35.  
  36. ' Mail abholen
  37. Dim msg As New Indy.Sockets.Message
  38. p.Retrieve(i, msg)
  39.  
  40. ' Für jeden Messagepart
  41. For x As Integer = 1 To msg.MessageParts.Count - 1
  42.  
  43. ' Ist dieser Messagepart ein Anhang?
  44. IsAttachment = msg.MessageParts.Items(x).ContentType = "application/octet-stream"
  45.  
  46. If IsAttachment Then
  47.  
  48. Try
  49. ' Anhang holen
  50. att = msg.MessageParts.Items(x)
  51.  
  52. ' Anhang temporär speichern
  53. tempfilename = System.IO.Path.GetTempFileName
  54. att.SaveToFile(tempfilename)
  55.  
  56. Catchex As Exception
  57. MsgBox(ex.Message, MsgBoxStyle.Critical)
  58. End Try
  59.  
  60. End If
  61.  
  62. Next
  63.  
  64. Next
  65.  
  66. Catch ex As Exception
  67. MsgBox(ex.Message, MsgBoxStyle.Critical)
  68. End Try
  69.  
  70. Finally
  71. p.Disconnect()
  72. p.Dispose()
  73. End Try
  74.  
  75. End Sub
  76.  
  77. End Class

Hier noch ein Modul mit einem kleinen Beispielaufruf obiger Klassen:

  1. Module modTest
  2.  
  3. Sub Main()
  4. Dim it As New IndyTools
  5. Dim ac As New MailAccount
  6.  
  7. ac.Username = "frank.miller@gmx.net"
  8. ac.Password = "BestMovie300"
  9. ac.Host = "pop.gmx.de"
  10.  
  11. it.SaveAllAttachments(ac)
  12. End Sub
  13.  
  14. End Module

Tags ¦ , , , , , und

VB .NET - DataTable nach Excel exportieren

28. Jan 2009 20:05 (edit)

Da ich heute ein DataTable möglichst schnell und einfach als Bericht brauchte, habe ich nach einer Möglichkeit gesucht, dieses DataTable nach Excel zu exportieren.

Irgendwo im Internet habe ich dann folgenen, leicht abgeänderten Schnipsel entdeckt (die Quelle weiß ich leider nicht mehr).

Da ich das sicherlich noch häufiger brauche und andere eventuell auch, poste ich den Code mal hier.

Als Referenz muss das Excel COM Objekt zu den Projekt Referenzen hinzugefügt werden.

  1. ''' <summary>
  2. ''' Export a DataTable into an Excel Datasheet
  3. ''' </summary>
  4. ''' <param name="aDataTable"></param>
  5. ''' <param name="aOutputFilename"></param>
  6. ''' <returns></returns>
  7. ''' <remarks></remarks>
  8. Public Shared Function DatatableToExcel(ByVal aDataTable As DataTable,
  9. ByVal aOutputFilename As String) As Boolean
  10.  
  11. Dim app As New Excel.ApplicationClass
  12. Dim wb As Excel.Workbook
  13. Dim ws As Excel.Worksheet
  14.  
  15. wb = app.Workbooks.Add()
  16. ws = wb.ActiveSheet()
  17.  
  18. Dim dc As DataColumn
  19. Dim dr As DataRow
  20. Dim colIndex As Integer
  21. Dim rowIndex As Integer
  22.  
  23. ' Columns erstellen
  24. For Each dc In aDataTable.Columns
  25. colIndex += 1
  26. app.Cells(1, colIndex) = dc.ColumnName
  27. Next
  28.  
  29. ' Rows hinzufügen
  30. For Each dr In dt.Rows
  31. rowIndex += 1
  32. colIndex = 0
  33. For Each dc In aDataTable.Columns
  34. colIndex += 1
  35. app.Cells(rowIndex + 1, colIndex) = dr(dc.ColumnName)
  36. Next
  37. Next
  38.  
  39. ws.Columns.AutoFit()
  40.  
  41. wb.SaveAs(aOutputFilename)
  42. app.Workbooks.Open(aOutputFilename) ' Excel anzeigen wenn fertig exportiert
  43. app.Visible = True
  44.  
  45. Return True
  46. End Function

Update am 01.12.2009:

Da ich immer häufiger auf die obigen Funktionen zugreife, habe ich meine Klasse ExcelTools mittlerweile etwas ergänzt. Wer möchte, kann sich den Quellcode hier herunter laden.

Tags ¦ , , , , und

Projekt Vorschau

23. Jan 2009 16:01 (edit)

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.