Daten|teiler
Kopieren als Kulturtechnik

„I don’t like spam“, oder wie man einen Mailserver testet

5. September 2011 von Christian Imhorst

Dieser Artikel erschien erstmals in freiesMagazin 09/11: Es begann mit einem Irrtum. Im Werbebrief vom Google für den AdWords-Dienst befand sich ein Gutschein über 75 Euro, der auf einen völlig fremden Menschen ausgestellt war. Wenn man Sandra Fründt, Head of Business Marketing Google Deutschland, auf ihren Fehler aufmerksam machen will, immerhin hat sie diesen Brief unterschrieben, stößt man auf ein Problem: Im Schreiben ist überhaupt keine E-Mail-Adresse angegeben. Das Unternehmen, das mit Suchmaschine und E-Mail-Dienst im Internet groß geworden ist, zeigt sich in seiner Werbung ganz schön verschlossen.

Den restlichen Eintrag lesen »

Geschrieben in Gnu/Linux | Kommentare deaktiviert für „I don’t like spam“, oder wie man einen Mailserver testet

Windows-Programme mit Python steuern

4. September 2011 von Christian Imhorst

Im Blog Der Bayer und der Würschtlmann bin ich auf den Beitrag Windows-(GUI-)Programme mit Python fernsteuern von Sebastian gestoßen. Für die Automatisierung der Windows-Programme benutzt er pywinauto, das einen sehr interessanten Eindruck macht, aber leider etwas durch die Abwesenheit von Dokumentation glänzt. Trotzdem soll man laut Sebastian schnell zu guten Ergebnissen kommen. Pywinauto ist sicherlich ein Vesuch wert, weil es objektorientierter und pythonmäßiger sein soll. Wenn man sich aber schon etwas mit dem Windows Script Host (WSH) oder dem Component Object Model (COM) auskennt, liegt einem Win32com vielleicht mehr.

Um überhaupt etwas mit Pywinauto oder Win32com zu machen, muss man Python unter Windows installiert haben. Ich habe mich zum Beispiel für Python 3.2 entschieden. Alternativ gibt es auch noch die Communuty Edition von ActivePython, das schon extra Module wie Win32com mitbringt. Beim original Python muss man auf jeden Fall noch die Erweiterung Pywin32 herunterladen, wenn man das Modul Win32com nutzen möchte. Allerdings kann es passieren, dass der erste Versuch, das Modul zu importieren, auf einen Fehler hinaus läuft:

>>> import win32com.client 
Traceback (most recent call last):
File "D:\EQ\InventoryDumps\testScript1.py", line 1, in <module>
import win32com.client as win32
File "D:\Python32\lib\site-packages\win32com\__init__.py", line 5, in <module>
import win32api, sys, os
ImportError: DLL load failed: The specified module could not be found.

Ist das der Fall, kann man das Problem mit folgendem Befehl beheben:

C:\Python32\Scripts\pywin32_postinstall.py

Wenn die Installation erfolgreich ist, steht einem die Welt der Windows-Objekte wie COM oder WSH mehr oder weniger offen. So kann man mit COM Anwendungen aus dem Microsoft Office-Paket oder den Internet Explorer automatisieren. COM dient dabei zur Interprozesskommunikation und dynamische Objekterzeugung unter Windows. Bevor man die Funktionen von COM-Objekten nutzen kann, muss man sie instanzieren, wofür die COM-Komponenten Schnittstellen anbieten. Im folgenden Beispiel wird eine Instanz des Internet Explorers durch die Angabe seiner ProgID („InternetExplorer.Application“) erzeugt:

import win32com.client
ie = win32com.client.Dispatch("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate("http://www.datenteiler.de")
ie.GoHome()
ie.quit()

Nach der Instanzierung steht ein Internet Explorer bereit, der allerdings noch nicht zu sehen ist, außer als Prozess im Taskmanager oder mit dem Cmdlet Get-Process in der PowerShell. Der Prozess ist unabhängig vom Python-Interpreter. Wird die Konsole geschlossen, bleibt der Prozess erhalten und aktiv. Erst wenn man der Eigenschaft von Visible auf wahr setzt, wird diese Instanz des Internet Explorers sichtbar.
Wenn man sich mit dem Einsatz von COM-Anwendungen in der PowerShell auskennt, kommt einem der Quelltext doch bekannt vor:

$ie = New-Object -ComObject InternetExplorer.Application
$ie.Visible = $true
$ie.Navigate("http://www.datenteiler.de")
$ie.GoHome()
$ie.Quit()

Das folgende SendKey-Beispiel mit dem WSH kann auch zu einem Déjà-vu führen, wenn man den Python-Quelltext mit dem VBScript-Code vergleicht. Erstmal das Beispiel um Tastendrücke zu simulieren in Python:

import win32api
import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.Run("Notepad") 
win32api.Sleep(1500) 
shell.AppActivate("Notepad") 
win32api.Sleep(1500) 
shell.SendKeys("Hallo Welt!{ENTER}") 
shell.SendKeys("^s")
shell.SendKeys("{ENTER}")
win32api.Sleep(1500)
shell.SendKeys("Hallo.txt{ENTER}")

Das Äquivalent in VBScript sieht dann so aus:

' SendkeyBeispiel.vbs
Option Explicit
Dim objWScriptShell
Set objWScriptShell = CreateObject("WScript.Shell")
objWScriptShell.Run "notepad"
Wscript.Sleep 1500 ' Warte bis Notepad fertig ist
objWScriptShell.SendKeys "Hallo Welt!{ENTER}"
objWScriptShell.SendKeys "^s"
objWScriptShell.SendKeys "{ENTER}"
Wscript.Sleep 1500
objWScriptShell.SendKeys "Hallo.txt{ENTER}"
WScript.Quit

Man kann mit dem Win32Com-Modul in Python noch einiges mehr anfangen, zum Beispiel die Maus positionieren und Mausklicks senden. Damit sind die Möglichkeiten von Python im Component Object Model oder des Windows Script Host bei weitem noch nicht ausgeschöpft.

Geschrieben in Python, Windows | Kommentare deaktiviert für Windows-Programme mit Python steuern

Tanz den Bubblesort

29. August 2011 von Christian Imhorst

Endlich habe ich mal verstanden, wie der Bubblesort funktioniert! Nicht schlecht was die Jungs und Mädels dort Vortanzen. Hier zum Beispiel der Tanz in Python implementiert, allerdings nur mit dem unsortierten Anfang, dem sortierten Ende und ohne das Ganze im Mittelteil:

# Bubblesort in Python
 
def bubblesort(a):
    for j in range(len(a) - 1):
        for i in range(len(a) - j - 1):
            if a[i] > a[i+1]:
                tmp = a[i]
                a[i] = a[i+1]
                a[i+1] = tmp
    return a
 
a = [3, 0, 1, 8, 7, 2, 5, 4, 6, 9]
print("Unsortiert: ", a)
 
result = bubblesort(a)	
print("Sortiert  : ", result)

Ich hoffe nur, dass ich die Musik auch wieder aus meinem Kopf bekomme. ;-)

[via zipfelmaus.com]

Geschrieben in Programmieren, Python | Kommentare deaktiviert für Tanz den Bubblesort

Steganografie für Anfänger

22. August 2011 von Christian Imhorst

Für die August-Ausgabe der Hakin9 habe ich meinen alten Blog-Post Steganografie für Anfänger „recycelt“. Der neue Artikel ist etwas anders strukturiert und um Befehle für die PowerShell erweitert worden:

Steganografie kommt aus dem Griechischen und heißt “geheimes Schreiben”. Herodot berichtet, dass einem Sklaven der Kopf geschoren wurde, um die Nachricht auf seine Kopfhaut zu tätowieren. Als das Haar wieder nachgewachsen war, wurde er zum Empfänger der geheimen Nachricht geschickt, der den Kopf des Sklaven wieder rasierte, um sie lesen zu können. Die Haare haben also die eigentliche Nachricht verdeckt. Ähnlich funktioniert Steganografie noch 2500 Jahre danach. Steganografie ist die Kunst, Information zu tarnen, um sie verborgen zu übermitteln. Ihr Zweck ist also, geheime Information mithilfe anderer unverfänglicher Information so zu verbergen, dass sie von einem unbedarften Beobachter, Mensch oder Maschine, nicht erkannt wird. Eine geheime Nachricht wird dabei in einer anderen Nachricht, zum Beispiel in einer Bilddatei versteckt. Dem Empfänger muss natürlich bekannt sein, dass das Bild eine geheime Nachricht enthält, so wie dem Empfänger in der Antike klar sein musste, dass sich die Nachricht unter dem Haar des Sklaven befand. Wenn das Originalbild fehlt, ist es sehr schwierig herauszufinden, ob ein Bild eine Geheimbotschaft versteckt. Die meisten Steganogramme werden enttarnt, wenn sie mit der Originaldatei verglichen werden und sich daraus Abweichungen ergeben. Wenn das Original gelöscht und ein gutes Bild mit vielen Unschärfen, hoher Pixelzahl und wenig Kanten gewählt wurde, dann ist im Prinzip nicht mehr festzustellen, ob eine Bilddatei ein Steganogramm ist.

Den restlichen Eintrag lesen »

Geschrieben in Publikationen | Kommentare deaktiviert für Steganografie für Anfänger

Wie kann man prüfen, ob eine E-Mail-Adresse nicht existiert, ohne eine E-Mail zum Testen zu verschicken?

13. August 2011 von Christian Imhorst

Vielleicht kennt ihr das Problem ja auch: Man hat vom Format her eine korrekte E-Mail-Adresse, trotzdem wird sie nicht zugestellt, weil das Ziel dem Mail-Server unbekannt ist. Eine formal richtige E-Mail-Adresse wäre zum Beispiel lpage@google.com. Sollte ich aber an diese Adresse eine E-Mail schicken, würde ich folgende Antwort erhalten:

Delivery to the following recipient failed permanently:
 
     lpage@google.com
 
Technical details of permanent failure: 
Google tried to deliver your message, but it was rejected by the recipient domain. We recommend contacting the other email provider for further information about the cause of this error. The error that the other server returned was: 550 550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at                             
550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596 c20si4840621fai.47 (state 14).

Den restlichen Eintrag lesen »

Geschrieben in Gnu/Linux, MacOS X und iPhone, Windows | Kommentare deaktiviert für Wie kann man prüfen, ob eine E-Mail-Adresse nicht existiert, ohne eine E-Mail zum Testen zu verschicken?

Gurus AI auf Google+

11. August 2011 von Christian Imhorst

Ich kann mir schon vorstellen, dass es ein paar Leute gibt, die über Google+ genauso denken wie Katja Kullmann in der FAZ: „Bei Google+ ist niemand außer Sascha Lobo. Es ist wirklich schrecklich einsam dort.“ Man kann aber auf keinen Fall auch nur ein bisschen ein Nerd sein, wenn man diesen Gedanken ansatzweise teilt. Denn für Nerds und Geeks wie mich ist Google+ eine kleine Fundgrube: Als Geek habe ich natürlich um Wil Wheaton und Sheldon Cooper einen Kreis gezogen. Beide in einem Kreis zu haben ist einfach klasse, und ich gehe jede Wette ein, dass Wil Wheaton auch bei Google+ wieder sich selbst spielt.

Als Nerd habe ich den Kreis „Gurus of the Information Age“ oder kurz „Gurus AI“ natürlich um Leute wie Linus Torvalds, Tim O’Reilly, Larry Page, Guido van Rossum, Steven Levy, Miguel de Icaza, Ted Ts’o, Sergey Brin, Eric Raymond und Jon „maddog“ Hall gezogen. Ich weiß nicht, habe ich noch wen vergessen?

Geschrieben in Allgemein | Kommentare deaktiviert für Gurus AI auf Google+

Kleiner Stolperstein bei Funktionen in der PowerShell

9. August 2011 von Christian Imhorst

Bei der Definition von Funktionen in der PowerShell gibt es einen kleinen Stolperstein, den man kennen sollte, wenn man nicht stürzen — oder besser — keine falschen Ergebnisse haben will. Gegeben ist zum Beispiel die kleine Funktion Add-Together():

# Add-Together.ps1
 
function Add-Together([string]$text,[int]$zahl1,[int]$zahl2)
    {
    Write-Host $text ($summe = $zahl1 + $zahl2)
    }

Jetzt könnte man meinen, dass die Funktion Add-Together() genauso eingesetzt wird, wie sie definiert wurde, also mit Klammern, einem Text-String und zwei Integer-Zahlen, die durch zwei Kommas voneinander getrennt werden:

Add-Together("Das Ergebnis ist", 4, 5)

In der Konsole ausgegeben wird aber Das Ergebnis ist 4 5 0, da die PowerShell Add-Together() in dieser Schreibweise nicht als Funktion ansieht, sondern als Array.

Ein Array wird in der PowerShell erstellt, indem eine kommaseparierte Liste mit Werten an eine Variable übergeben wird, was im kurzen Tutorial „Programmieren mit der Windows PowerShell“ von Nils Gutsche sehr schön prägnant beschrieben ist. Für die Funktion bedeutet das, dass der erste Wert das Array ist und die beiden anderen leer bleiben, also 0 sind. Daher die Ausgabe Das Ergebnis ist 4 5 0 in der Konsole.

In der PowerShell werden die Parameter einer Funktion ohne Klammern und ohne trennende Kommas übergeben, so dass der vollständige Code dann folgendermaßen aussieht:

# Add-Together.ps1
 
function Add-Together([string]$text,[int]$zahl1,[int]$zahl2)
    {
    Write-Host $text ($summe = $zahl1 + $zahl2)
    } 
Add-Together "Das Ergebnis ist" 4 5

Geschrieben in Powershell, Windows | Kommentare deaktiviert für Kleiner Stolperstein bei Funktionen in der PowerShell

Suchen und auflisten in der PowerShell

14. Juli 2011 von Christian Imhorst

In der Windows-Befehlszeile cmd.exe oder in DOS hat man zum Auflisten von Dateien den DIR-Befehl benutzt. Der Befehl klappt in der PowerShell auch noch, ist allerdings ein Alias zum Cmdlet Get-Childitem.
Wenn man den Befehl DIR nicht mehr benutzen möchte, Get-Childitem aber zu lang findet, kann man auch den Alias gci nehmen, oder auch ls, wenn man mehr an Shells wie die Bash gewöhnt ist. Eine Einschränkung hat die Geschichte mit den Aliasen allerdings: Parameter zu den Befehlen kann man nicht so einfach in die PowerShell übertragen. Der Befehl dir /s klappt nicht, stattdessen muss man den Parameter -recurse nehmen, wenn man Unterordner in die Auflistung mit einbeziehen will.

PS C:\Users\Christian> dir -recurse
 
    Verzeichnis: C:\Users\Christian
 
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d-r--        28.05.2011     15:56            Contacts
d-r--        27.06.2011     11:37            Desktop
d-r--        05.06.2011     22:49            Documents
d-r--        12.07.2011     21:20            Downloads
[...]

Wie sucht man nun in der PowerShell? Der Befehl Get-ChildItem C:\ listet einfach alle Dateien im Wurzelverzeichnis C: auf. Wie schon oben erwähnt, kann man mit dem Parameter -recurse auch Dateien in Unterordnern auflisten.
Dabei kann man auch nach bestimmten Dateien suchen. Der folgende Befehl listet zum Beispiel alle Dateien auf, auch die in den Unterordnern, die ein „python“ im Namen tragen:

gci -recurse | Where-Object {$_.Name -like "*python*"}

Man kann aber nicht nur nach Namen sortieren, sondern auch nach bestimmten Endungen:

gci  $env:windir -recurse | Where-Object {$_.Extension -eq ".dll"}

Leitet man die Ausgabe der Suche nach Format-Table oder Select-Object um, dann bekommt man sie schön vorsortiert:

PS C:\Users\Christian> gci  $env:windir -recurse `
>> | Where {$_.Extension -eq ".dll"} `
>> | Format-Table FullName, CreationTime, Length
>>
 
FullName                               CreationTime                 Length                                         
--------                               ------------                 ------                                                 
C:\Windows\RtlExUpd.dll                 15.11.2010 07:59:44         1251944                                                
C:\Windows\twain.dll                    10.06.2009 23:41:17           94784                                              
C:\Windows\twain_32.dll                 14.07.2009 02:14:33           51200  
C:\windows\assembly\GAC\Microsoft.In... 14.07.2009 06:42:34          356352
C:\windows\assembly\GAC\Microsoft.In... 14.07.2009 06:42:34          516096
C:\windows\assembly\GAC\Microsoft.In... 05.06.2011 22:27:52            6656
C:\windows\assembly\GAC\Microsoft.St... 05.06.2011 22:29:56           22552                                           
[...]

Hier ist allerdings ein kleiner Exkurs zur formatierten Ausgabe von Format-Table nötig: Wenn der Inhalt der Spalte breiter bzw. länger ist, als die Spalte selbst, dann wird der Inhalt abgeschnitten und der Rest durch drei Punkte dargestellt. Man kann also nicht wirklich erkennen, wie es in der Spalte weiter geht. Übergibt man die Ausgabe in eine Textdatei, in der die Spalten ja breiter sein könnten, da sie nicht durch die Konsole begrenzt wird, bekommt man dasselbe Ergebnis. Der AutoSize-Parameter von Format-Table hilft leider auch nicht weiter, weil er gerade mal nur so viele Spalten darstellt, wie sie in die Konsole passen. Alles was darüber hinaus geht, lässt er weg. Auch diese Spalten landen nicht in der Ausgabedatei. Die Lösung hier heißt Strings, da Strings nicht den selben Beschränkungen wie andere Objekte der PowerShell unterliegen:

PS C:\Users\Christian> gci $env:USERPROFILE -r `
>> | Where {($_.lastwritetime -gt "2011-06-20")} `
>> | Format-Table -Property * -AutoSize `
>> | Out-String -Width 4096 `
>> | Out-File $env:USERPROFILE\log.txt
>>

Lässt man das Cmdlet Out-File am Ende weg, um die Ausgabe direkt in das Terminal umzuleiten, sieht das Ergebnis auf Grund der Beschränkungen durch die Konsole sehr wüst aus. Die Text-Datei kann sich aber sehr gut sehen lassen.

Doch zurück zum eigentlichen Thema: Nun sieht Where-Object doch recht kompliziert aus. Anstatt die Ausgabe des Get-ChildItem-Befehls an ein Where-Objekt weiterzuleiten, stellt der Befehl selbst Parameter zur Sortierung bereit. Eine vereinfachte Schreibweise, in der statt -recurse einfach nur -r geschrieben wird, ist dann zum Beispiel:

Get-ChildItem -r -filter *.dll -path $env:windir

Ersetzt man -filter durch -exclude schließt man Dateien von der Suche aus. Davon abgesehen kann man auch die Parameter-Bezeichnungen wie -filter oder -path ganz weglassen:

gci -recurse $env:USERPROFILE *python*

Wann nützt aber eine Umleitung in ein Where-Objekt? Zum Beispiel dann, wenn man nur Dateien auflisten will, die eine bestimmte Größe überschreiten,

Get-ChildItem | Where-Object {$_.length -gt 4000}

oder Dateien, die nach einem bestimmten Datum erstellt worden sind, in diesem Fall nach dem 20.06.2011:

Get-ChildItem | Where-Object {($_.lastwritetime -gt "2011-06-20")}

Das sind beides wichtige Befehle, wenn man sich mal wieder fragt, warum der Fileserver innerhalb kürzester Zeit voll gelaufen ist, bzw. welche großen Dateien auf dem Server schon seit ewigen Zeiten nicht mehr angefasst worden sind. In diesem Zusammenhang habe ich im Blog von Christian Jäckle einen Befehl gefunden, der alle Dateien in einem Verzeichnis anzeigt, die in den letzten 15 Minuten bearbeitet wurden:

gci -r C:\ | Where-Object {$_.LastWriteTime -gt (Get-Date).AddMinutes(-15)} | export-csv $env:userprofile\Log.csv -notype

Mit dem Cmdlet Get-Date wird die aktuelle Zeit ermittelt, von der 15 Minuten abgezogen werden. Das Ergebnis wird in eine CSV-Datei im User-Verzeichnis geschrieben. Den Pfad zum User-Verzeichnis liefert die Umgebungsvariable userprofile, die der Ausdruck $env:userprofile liefert.
Welche Umgebungsvariablen es überhaupt gibt, liefert übrigens auch der Befehl Get-ChildItem:

Get-Childitem env:
 
Name                           Value
----                           -----
ALLUSERSPROFILE                C:\ProgramData
APPDATA                        C:\Users\Christian\AppData\Roaming
CommonProgramFiles             C:\Program Files\Common Files
COMPUTERNAME                   KDBSH4-PC
ComSpec                        C:\windows\system32\cmd.exe
[...]

Aber das ist noch nicht alles, was Get-ChildItem auflisten kann. Man kann auch Registry-Einträge anzeigen lassen, um sie anschließend eventuell zu bearbeiten. Der folgende Befehl listet die installierte Software des Rechners auf, zumindest diejenige, die auch in die Registry eingetragen wurde:

Get-ChildItem hklm:\software

Geschrieben in Powershell, Windows | Kommentare deaktiviert für Suchen und auflisten in der PowerShell

MessageBox und PowerShell

4. Juni 2011 von Christian Imhorst

Wenn ich auf der Arbeit ein Skript an die Fachabteilungen verteile, damit die Benutzer dort mehr oder weniger automatisiert beispielsweise ein Programm installieren oder einen Netzwerkpfad ändern oder ihre Outlook-Signatur schnell bearbeiten können, habe ich die Erfahrung gemacht, dass die Anwender sich Infos darüber wünschen, was das Programm gerade so macht. Besonders Rückmeldungen darüber, dass das Skript die Änderungen durchgeführt hat und nun zu Ende ist, sind sehr beliebt. Solche kleinen Werkzeuge von der IT wirken auf ihre Nutzer in den Fachabteilungen einfach professioneller, wenn sie kurze Nachrichtenfenster erzeugen.

Vor der PowerShell habe ich mit VBScript eine Messagebox erzeugt, die dann zum Beispiel das Programmende angezeigt hat. Entweder war das Skript gleich in VBScript für den Windows Script Host geschrieben, oder es wurde mit ähnlichen Mitteln über einen Trick aus einer Batch-Datei heraus erzeugt:

:: Test mit Messagebox - MessageBox.bat
 
@echo off
echo msgbox "Die Datei wird ausgeführt.", VbInformation + VbOKOnly, "Der Test hat geklappt!" >%TEMP%\Test.vbs 
start %TEMP%\Test.vbs
pause
del %TEMP%\Test.vbs

Der Nachteil dieses Tricks liegt auf der Hand, es muss zumindest temporär eine neue Datei erzeugt werden.

Im Gegensatz zu VBScript kann die PowerShell allerdings nicht direkt eine Messagebox erzeugen, das geht nur über den Umweg, ein COM-Objekt zu instanziieren. Dafür spart man sich aber die temporäre Datei, wie in der Batch-Datei.

$wshshell = new-object -comobject wscript.shell
$Answer = $wshshell.popup("Die Datei wird ausgeführt.",5,"Der Test hat geklappt!",0)

Das Popup-Fenster funktioniert wie in WScript mit VBScript: Wenn die erste Zahl größer Null ist, sind das die Anzahl der Sekunden, nach denen sich das Popup-Fenster wieder schließt. Also im oberen Beispiel schließt sich das Fenster nach 5 Sekunden. Die zweite Zahl bestimmt die Anzahl der Buttons. Die „0“ steht für den „OK“-Button, die „1“ für die Button „OK“ und „Abbrechen“, „4“ für „Ja“ und „Nein“ und so weiter.

Dann kann man sich für die Darstellung einer Messagebox auch mit Windows Forms aus dem .Net-Framework bedienen:

[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
[windows.forms.messagebox]::Show("Die Datei wird ausgeführt.","Der Test hat geklappt!", `
[Windows.Forms.MessageBoxButtons]::OK ,[Windows.Forms.MessageBoxIcon]::Information)

Das erinnert nicht von ungefähr an eine stark verkürzte Darstellung eines einfachen C#-Programms, das die Windows Forms-Bibliothek nutzt:

// ButtonMitWindowsForms.cs
 
using System;
using System.Windows.Forms;
 
public class HalloWelt
{
   [STAThread]
   public static void Main()
   {
      MessageBox.Show("Die Datei wird ausgeführt.","Der Test hat geklappt!");
   }
}

Kompilieren und ausführen kann man das kleine Beispiel-Programm mit folgenden Befehlen in der Konsole:

%windir%\Microsoft.NET\Framework\v3.5\csc ButtonMitWindowsForms.cs
ButtonMitWindowsForms.exe

Man kann auch Nachrichtenfenster mithilfe der Windows Presentation Foundation (WPF) in der PowerShell erzeugen, was aber ein bisschen komplexer ist, und das nicht nur, weil man die Powershell in die Single Thread-Betriebsart zwingen muss, dem STA-Mode. Dazu ruft man die PowerShell mit folgendem Befehl auf:

powershell.exe -sta

Den Thread-Status kann man dann mit folgendem Befehl abfragen:

[System.Management.Automation.Runspaces.Runspace]::DefaultRunspace

Die Bildschirmausgabe sollte dann in etwa so aussehen (vgl. dazu auch MSXFAQ.DE):

Da der Wechsel in den STA-Modus leider noch nicht dazu führt, dass die WPF-Assemblies automatisch geladen werden, muss man das noch händisch nachholen:

Add-Type -assemblyName PresentationFramework
Add-Type -assemblyName PresentationCore
Add-Type -assemblyName WindowsBase

Anschließend kann man endlich damit loslegen, ein neues Fenster-Objekt zu erzeugen und das Fenster zeichnen zu lassen:

$window = New-Object Windows.Window
$window.Title = "Der Test hat geklappt!"
$window.Content = "Die Datei wird ausgeführt."
$window.SizeToContent = "WidthAndHeight"
$null = $window.ShowDialog()

Geschrieben in Powershell, Windows | Kommentare deaktiviert für MessageBox und PowerShell

PowerShell-Skript mit Doppelklick ausführen

3. Juni 2011 von Christian Imhorst

Wenn man im Windows-Explorer auf ein PowerShell-Skript doppelklickt, wird nicht das Skript ausgeführt, so wie man es von Batch-Dateien oder dem Windows Script Host (WSH) gewohnt ist, stattdessen öffnet sich Notepad und zeigt den Inhalt der Textdatei an. Um ein Skript mit einem Doppelklick auszuführen, ist etwas mehr Aufwand nötig.

Zum Testen kann man ganz gut folgendes Skript nehmen, das quasi ein erweitertes „Hallo Welt“-Skript darstellt. Das letzte Read-Host am Ende des Skripts dient dazu, dass das Konsolen-Fenster noch bis zum nächsten Tastendruck geöffnet bleibt und sich nicht gleich wieder schließt:

# HalloWelt.ps1
set-psdebug -strict
 
[string]$Name = Read-Host "Wie heißt Du? "
Write-Host "Hallo $Name!"
Read-Host

Das Skript kann man nun in seinen favorisierten Skript-Ordner speichern und eine Verknüpfung auf den Desktop erstellen. Danach muss man noch die Eigenschaften der Verknüpfung bearbeiten und folgendes eintragen:

powershell.exe -Command "& 'C:\Users\Christian\HalloWelt.ps1'"

Anstelle von C:\Users\Christian\ muss man natürlich den eigenen Pfad zum Skript wählen. Wichtig ist hier das kaufmännische Und (&-Zeichen), da die PowerShell den Pfad in den Anführungszeichen ansonsten als String interpretiert. Anstelle des &-Zeichens kann man auch einen Punkt (.) nehmen:

powershell.exe -Command ". 'C:\Users\Christian\HalloWelt.ps1'"

Ob man das kaufmännische Und wählt, oder den Punkt für das sogenannte dot sourcing, hängt davon ab, welchen Sichtbarkeitsbereich (Scope) die Variablen des Skripts haben sollen. Da der Sichtbarkeitsbereich aber beim direkten Start eines Skripts keine Bedeutung hat, ist es an dieser Stelle nicht wichtig, welcher der beiden Befehle eingesetzt wird. Der Scope spielt allerdings eine wichtige Rolle, wenn man ein Skript direkt aus der Konsole oder aus einem anderen Skript heraus startet.

Anschließend kann man das Skript mit einem Doppelklick auf den Link ausführen. Wenn man das Konsolen-Fenster vor dem nutzer verstecken möchte, kann man die Option -WindowStyle Hidden noch vor -Command einfügen.
Die Parameter im einzelnen findet man bei Microsofts TechNet.

Anstelle des Parameters -command kann man auch -noexit verwenden. Der Vorteil ist, dass die Konsole nach dem Ausführen des Skripts geöffnet bleibt:

powershell.exe -noexit &'C:\Users\Christian\HalloWelt.ps1'

Interessant wird die Geschichte, wenn man mit dieser Methode nicht nur ein einzelnes Skript aufruft, sondern stattdessen die PowerShell schon mit einem Befehl aus dem Ausführen-Dialog heraus startet.

Geschrieben in Powershell, Windows | Kommentare deaktiviert für PowerShell-Skript mit Doppelklick ausführen

« Previous Entries Next Entries »