Schlagwort: Softwareentwicklung

Laufwerke mit C# ermitteln 👍 👎

Eine häufig gefragte – und eigentlich auch gar nicht besonders versteckte – Funktionalität ist das Abrufen der verfügbaren Laufwerke und Informationen dazu. Daher im Folgenden gerne eine kleine Übersicht dazu:
Laufwerksinformationen abrufen
010203040506070809101112131415161718192021222324
foreach(DriveInfo driveInfo in DriveInfo.GetDrives()) {    /**     * driveInfo.AvailableFreeSpace     *   -> Verfügbarer Speicherplatz (mit Berücksichtigung des Benutzers)     *        * driveInfo.DriveFormat     *   -> Dateisystem (z. B. NTFS)     *        * driveInfo.DriveType     *   -> Laufwerkstyp (z. B. Network oder Fixed für lokale Festplatten)     *        * driveInfo.Name     *   -> Laufwerksbuchstabe (z. B. "C:\")     *        * driveInfo.TotalFreeSpace     *   -> Verfügbarer Speicherplatz (ohne Berücksichtigung des Benutzers)     *        * driveInfo.TotalSize     *   -> Gesamtspeicherplatz     *        * driveInfo.VolumeLabel     *   -> Beschriftung (z. B. "System")     */}
In diesem Zusammenhang sei außerdem nochmals auf meinen Beitrag Byte-Angaben mit C# formatieren verwiesen, um die rohen Byte-Angaben auf besser lesbare Größen zu bringen. In einem späteren Beitrag möchte ich gerne noch aufzeigen, wie sich programmatisch Laufwerke erzeugen und weitergehend verwenden lassen.

PHP-Funktionen in C# (noch nicht) als Programmbibliothek 👍 👎

Meine beispielhaften PHP-Funktionen in C# erfreuen sich gewisser Beliebtheit, sodass mich mittlerweile schon ein paar mal die Frage erreicht hat, ob ich diese nicht als Programmbibliothek zur Verfügung stellen möchte.

Aus technischer Sicht wäre das tatsächlich kein Problem und grundsätzlich sogar mit überschaubarem Aufwand automatisierbar. Ich habe daher auch selbst schon einmal mit dem Gedanken der Veröffentlichung als Paket gespielt, dennoch möchte ich erst einmal Abstand davon nehmen und zwar vor allem aus folgenden Gründen:
  • Design

    Die Umsetzung der Methoden (Bezeichner, Datentypen, Parameter) ist stark an PHP angelehnt, sprich ist soweit möglich identisch zu den gleichnamigen PHP-Funktionen. Diese Umsetzung widerspricht jedoch in nahezu allen Fällen in vielerlei Hinsicht den .NET-Guidelines für Programmbibliotheken und auch die Datentypen entsprechen oftmals nicht den bei C# für den jeweiligen Einsatzzweck üblichen.

  • Qualität

    Die Umsetzungen sollen einen Ansatz bzw. Tipps liefern, entsprechen jedoch in einigen Fällen nicht einer Qualität, die einen sofortigen und ungeprüften Einsatz in Produktionsumgebungen ermöglicht. Dies wäre für eine tatsächliche Veröffentlichung jedoch zwingend erforderlich. Darüber hinaus wären an einigen Stellen Optimierungen für den effizienten Einsatz in echten Projekten durchaus sinnvoll.

Dennoch stimme ich natürlich grundsätzlich zu, dass die Implementierungen einige praktische Funktionen anbieten, die in PHP durchaus üblich sind, in C# standardmäßig jedoch nicht ohne Weiteres zur Verfügung stehen. Daher werde ich an einer entsprechenden Programmbibliothek arbeiten, die ausschließlich solche Funktionalität in stabiler Qualität zur Verfügung stellt. Einen konkreten Zeitplan kann und möchte ich derzeit jedoch noch nicht nennen.

Systemtöne mit C# ausgeben 👍 👎

Eine häufige Frage ist das Ausgeben von Systemtönen mit C#. Da sich dieses Blog explizit nicht nur an Experten richten soll, möchte ich natürlich gerne auch dazu erst einmal ein paar Beispiele auflisten:
Systemtöne ausgeben
01020304050607080910
// Systemton per Steuerzeichen/KonsoleConsole.Write('\a');Console.Beep();
// Systemtöne per MethodenaufrufSystemSounds.Asterisk.Play();SystemSounds.Beep.Play();SystemSounds.Exclamation.Play();SystemSounds.Hand.Play();SystemSounds.Question.Play();
Etwas interessanter ist die Überladung von Console.Beep(…), welche nicht nur in der Lage ist, den Standardton (800 Hz, 200 ms) auszugeben, sondern darüber hinaus dessen Konfiguration in Tonhöhe und -länge ermöglicht:
Benutzerdefinierten Ton ausgeben
0102
// 2350 Hz-Ton für 650 ms abspielenConsole.Beep(2350, 650);

Zertifikat einer Adresse mit C# ermitteln 👍 👎

Manchmal möchte man gerne Zertifikate von Webseiten automatisiert abrufen. Im Rahmen eines Monitorings bietet es sich beispielsweise an, die Gültigkeitsdauer zu überwachen. Dazu eine beispielhafte Implementierung:
Zertifikat einer Webseite ermitteln
010203040506070809
public static X509Certificate2 GetCertificate(string hostName, int port = 443) {    using(TcpClient client = new TcpClient(hostName, port)) {        using(SslStream stream = new SslStream(client.GetStream())) {            stream.AuthenticateAsClient(hostName);
return new X509Certificate2(stream.RemoteCertificate); } }}
Die Implementierung ist dabei – wie üblich – auf das Wesentliche beschränkt; es findet keine umfassende Problembehandlung statt. Sofern die Methode in größerem Kontext zum Einsatz kommen soll, empfiehlt sich auf jeden Fall ein Blick auf die beteiligten Klassen TcpClient, SslStream und X509Certificate2 im MSDN.

Nun stehen uns diverse Informationen zur Verfügung; einige Beispiele zur Ausgabe auf der Konsole:
Methode verwenden und Informationen ausgeben
010203040506
X509Certificate2 certificate = GetCertificate("coders-online.net");
Console.WriteLine(certificate.Subject); // "CN=coders-online.net"
Console.WriteLine(certificate.NotBefore); // 30.04.2017 08:01:00Console.WriteLine(certificate.NotAfter); // 29.07.2017 08:01:00
Im Besonderen sei abschließend noch auf RemoteCertificateValidationCallback hingewiesen, mit welchem sich das Verhalten bei Zertifizierungsfehlern beeinflussen lässt.

Byte-Angaben mit C# formatieren 👍 👎

Mit gewisser Regelmäßigkeit kommt man als Softwareentwickler in die Verlegenheit, Dateigrößen statt in der Form 10110 Byte in der "üblichen" Schreibweise mit größeren Einheiten (in diesem Fall 9.87 KiB) darzustellen.

Zwar gäbe es hier wieder einmal die Möglichkeit per DllImport und beispielsweise StrFormatByteSizeW zu arbeiten, jedoch möchten wir in diesem Fall die Implementierung selbst vornehmen, um die Basis (Stichwort: Binärpräfixe) konsistent bestimmen zu können. Ich stelle dazu zwei mögliche Implementierungen vor:
Hilfsklasse mit Methode zur Formatierung
0102030405060708091011121314151617
public static class Helper {    private static readonly IReadOnlyList<string> unitList = new string[] {        "Byte", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"    };

public static string FormatBytes(double bytes) { int index = 0;
while(bytes >= 1024 && index < Helper.unitList.Count) { bytes /= 1024; index++; }
return $"{Math.Round(bytes, 2).ToString("N2")} {Helper.unitList[index]}"; }}
Alternativ lässt sich das Problem jedoch auch ohne Schleife – und daher mathematisch etwas eleganter – durch ein ähnliches Vorgehen wie bei der Ermittlung der Anzahl der Ziffern einer Zahl mittels Logarithmen lösen:
Alternativer Lösungsansatz
010203040506
public static string FormatBytes(double bytes) {    int index = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));    bytes /= Math.Pow(1024, index);
return $"{Math.Round(bytes, 2).ToString("N2")} {Helper.unitList[index]}";}
Die Verwendung gestaltet sich nun in jedem Fall recht einfach:
Formatierung verwenden
010203
string formattedBytes = Helper.FormatBytes(1024);         // 1,00 KiBformattedBytes = Helper.FormatBytes(1024 * 1024);         // 1,00 MiBformattedBytes = Helper.FormatBytes(1024 * 1024 * 1024);  // 1,00 GiB
Abschließend möchte ich auch noch kurz eine beispielhafte Implementierung zur Verwendung im Rahmen einer benutzerdefinierten Formatierung per String.Format skizzieren:
Implementierung der benutzerdefinierten Formatierung
010203040506070809
public class FileSizeFormatProvider : ICustomFormatter, IFormatProvider {    public string Format(string format, object arg, IFormatProvider formatProvider) {        return Helper.FormatBytes(Convert.ToDouble(arg));    }
public object GetFormat(Type formatType) { return this; }}
Bitte beachtet jedoch, dass diese Implementierung noch nicht vollständig ist. Weiterführende Informationen zur korrekten Implementierung finden sich im MSDN per ICustomFormatter und IFormatProvider. Verwendung:
Verwendung der benutzerdefinierten Formatierung verwenden
01
formattedBytes = String.Format(new FileSizeFormatProvider(), "{0}", (1024 * 1024));  // 1,00 MiB
Ich werde eine vollständige Implementierung vermutlich in einem späteren Beitrag nachreichen.

Projektverweise

Kategorien / Archiv  |  Übersicht RSS-Feed

Schlagworte

Suche