Windows Defender mit C# ansprechen 👍 👎

Windows stellt unter der Bezeichnung Antimalware Scan Interface native Funktionalität zur Interaktion mit Windows Defender bereit. Wir werden für C# also – wieder einmal – auf DllImport setzen:
Wrapper implementieren
01020304050607080910111213141516171819202122232425262728293031
public static class AmsiWrapper {    public static Result Scan(string content, string name = null) {        AmsiInitialize(nameof(AmsiWrapper), out IntPtr context);        AmsiScanString(context, content, name, IntPtr.Zero, out Result result);        AmsiUninitialize(context);
return result; }
public enum Result { Clean = 0, NotDetected = 1, Detected = 32768 }

[DllImport("Amsi")] private static extern int AmsiInitialize(string appName, out IntPtr amsiContext);
[DllImport("Amsi")] private static extern int AmsiScanString( IntPtr amsiContext, string @string, string contentName, IntPtr session, out Result result );
[DllImport("Amsi")] private static extern void AmsiUninitialize(IntPtr amsiContext);}
Die Verwendung der empfohlenen Funktion AmsiResultIsMalware ist kurioserweise leider nicht möglich, da diese schlicht nicht in Amsi.dll gefunden werden kann. Es gilt also die Hinweise von AMSI_RESULT zu beachten.

Die Überprüfung gestaltet sich nun jedoch grundsätzlich äußerst einfach durch Übergabe des fraglichen Inhalts:
Wrapper verwenden
0102030405
if(AmsiWrapper.Scan("sehrGefährlicherInhalt") == AmsiWrapper.Result.Detected) {    /* Inhalt als Bedrohung erkannt */} else {    /* Inhalt nicht als Bedrohung erkannt */}
Zum Test der Erkennung potentiell bedrohlicher Inhalte kann beispielsweise die EICAR-Testdatei dienen.

Vor einem tatsächlichen Einsatz sollten natürlich mindestens noch Überprüfungen der Rückgabewerte (HRESULT) mit entsprechender (Fehler-)Behandlung ergänzt werden.

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.

Melodien mit Systemtönen in C# 👍 👎

Im letzten Beitrag hatte ich Systemtöne mit C# vorgestellt. Der Übersicht wegen – und nicht ganz ernstzunehmen – möchte ich mit diesem separaten Beitrag noch ein paar Beispiele zur Umsetzung einfacher Melodien zeigen.

Dazu implementieren wir zuerst eine kleine Hilfsklasse mit einigen vordefinierten Werten:
Klasse zur Arbeit mit der Tonart C-Dur
01020304050607080910111213141516171819
public static class BeepMusic {    private static readonly Dictionary<char, int> frequencyCollection = new Dictionary<char, int>() {        ['C'] = 264, ['D'] = 297, ['E'] = 330, ['F'] = 352,        ['G'] = 396, ['A'] = 440, ['H'] = 495, ['c'] = 528    };
public static void PlayNotes(Duration duration, string noteList) { foreach(char note in noteList) { Console.Beep(frequencyCollection[note], (int) duration); } }
public enum Duration { Whole = 1600, Half = (Whole / 2), Quarter = (Half / 2), Quaver = (Quarter / 2) }}
Nun können wir diese Klasse statisch importieren und (sehr) einfache Melodien erzeugen:
Melodien
01020304050607080910111213141516171819202122232425262728293031323334353637383940
using static BeepMusic;
// TonleiterPlayNotes(Duration.Quarter, "CDEFGAHc");
// Alle meine EntchenPlayNotes(Duration.Quaver, "CDEF");PlayNotes(Duration.Quarter, "GG");PlayNotes(Duration.Quaver, "AAAA");PlayNotes(Duration.Half, "G");PlayNotes(Duration.Quaver, "AAAA");PlayNotes(Duration.Half, "G");PlayNotes(Duration.Quaver, "FFFF");PlayNotes(Duration.Quarter, "EE");PlayNotes(Duration.Quaver, "GGGG");PlayNotes(Duration.Half, "C");
// Hänschen KleinPlayNotes(Duration.Quarter, "GE");PlayNotes(Duration.Half, "E");PlayNotes(Duration.Quarter, "FD");PlayNotes(Duration.Half, "D");PlayNotes(Duration.Quarter, "CDEFGG");PlayNotes(Duration.Half, "G");PlayNotes(Duration.Quarter, "GE");PlayNotes(Duration.Half, "E");PlayNotes(Duration.Quarter, "FD");PlayNotes(Duration.Half, "D");PlayNotes(Duration.Quarter, "CEGG");PlayNotes(Duration.Whole, "C");PlayNotes(Duration.Quarter, "DDDDDE");PlayNotes(Duration.Half, "F");PlayNotes(Duration.Quarter, "EEEEEF");PlayNotes(Duration.Half, "G");PlayNotes(Duration.Quarter, "GE");PlayNotes(Duration.Half, "E");PlayNotes(Duration.Quarter, "FD");PlayNotes(Duration.Half, "D");PlayNotes(Duration.Quarter, "CEGG");PlayNotes(Duration.Whole, "C");
Interessante Effekte ergeben sich darüber hinaus bei (pseudo-)zufälligen Tonfolgen. In einem späteren Beitrag möchte ich gerne aufzeigen, wie man auch etwas ernsthafter mit diesem Thema in C# umgehen kann.

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);

Projektverweise

Kategorien / Archiv  |  Übersicht RSS-Feed

Schlagworte

Suche