Mit Hilfe der Microsoft Windows PowerShell kann man den SF ft Community Publisher auch von der Kommandozeile und mit Skripts steuern. Aber Achtung: Hier wird es gleich sehr technisch. Hier gibt es keine bunten Bildchen und andere freundliche Sachen zum Klicken, hier sind wir in der Welt der Tastatur!

Worum geht's?

Die Windows PowerShell ist eine neue Kommandozeilen-Shell, komplett .NET-basiert und mit einer ganzen Reihe brandneuer Features. So gehen durch einen Pipe-Operator | nicht mehr, wie in all den bekannten Shells für Unix, DOS und Windows Text, sondern .NET-Objekte durch, und man kann auch direkt auf der Kommandozeile neue COM- oder .NET-Objekte instanziieren und mit denen arbeiten.

Ein einfaches Beispiel, was man so machen kann: Wie viele Bytes belegen alle *.EXE im aktuellen Verzeichnis einschließlich Unterverzeichnissen?

Get-ChildItem -filter *.exe -recurse | Measure-Object Length -sum
Count    : 2
Average  :
Sum      : 198144
Maximum  :
Minimum  :
Property : Length

PowerShell-Befehle sind immer in der Notation Verb-Substantiv aufgebaut. Für Wenigtipper gibt es aber auch Aliase (natürlich auch frei definierbar) für Befehle. Folgender Befehl würde genau dasselbe machen:

gci *.exe -r|measure-object length -s

gci ist ein vordefinierter Alias für Get-ChildItem (sowas wie "DIR" oder "ls", funktioniert aber nicht nur im Dateisystem, sondern auch in der Registry, im Zertifikatsspeicher, in der Liste der Variablen, Aliase, Befehle; "dir" und "ls" sind ebenfalls Aliase für Get-ChildItem, damit man sich nicht so umgewöhnen muss). -r für -recurse und -s für -sum reichen aus, weil man nur soviel wie zur Eindeutigkeit nötig eingeben muss.

Das Objektmodell des SF ft Community Publishers laden

So, jetzt aber zum SF ft Community Publisher: Damit die PowerShell dessen Objektmodell kennt, muss man ihr sagen, dass sie die entsprechende .NET-Assembly laden soll. Das geschieht in bester .NET-Manier und sieht auf einem System mit im Standardpfad installiertem SF ft Community Publisher so aus:

[System.Reflection.Assembly]::LoadFrom( `
'C:\Programme\SF Softwareberatung\SF ft Community Publisher\SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.dll')
GAC    Version        Location
---    -------        --------
False  v2.0.50727     C:\Programme\SF Softwareberatung\SF ft Community Publisher\SFSoftwareberatung.SFFTCommunityPub...

Das erste ist ein Befehl, der Zeilenumbruch nach dem Fortsetzungszeichen ` ist nur der Übersichtlichkeit halber. Für Benutzer der 64-Bit-Edition von Windows Vista oder Windows Server 2003 lautet die Zeile so:

[System.Reflection.Assembly]::LoadFrom( `
'C:\Program Files (x86)\SF Softwareberatung\SF ft Community Publisher\SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.dll')

Übrigens läuft der Publisher unter einem 64-Bit-Betriebssystem als echte 64-Bit-Anwendung.

Erste Übung

Die Aufgabe: Informationen über ein Projekt erhalten: Dazu laden wir eine Projektdatei (als .NET-Objekt des Objektmodells des Publishers) und lassen einfach die Variable ausgeben!

PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien> $projekt = `
[SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.Project]::FromFile( `
'C:\Dokumente und Einstellungen\Stefan\Eigene Dateien\Digitaluhr - Anfänge.ftcpub')
PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien> $projekt
ImageSources      : {Ordner}
PublisherSettings : {66ad4cbe-7593-4c34-a7f3-ad041f759d9f, f8492baf-4bd7-477e-8833-bf9713a713b3, a063b9de-bd61-405b-a25
                    c-dd773b6e60c4, 04820ec2-70eb-4f1d-a1ed-f60b7c2a04b9...}
Statistics        : 8 Bilder (1 - 8), alle zu veröffentlichen
Identifier        : 5927f4a9-7a08-4f59-a3ad-b73d737a75dd
Title             : Anfänge einer Digitaluhr
Description       : Dies sind die Anfänge einer Digitaluhr mit mechanischer 7-Segment-Anzeige.
Constructor       : SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.Person
Photographer      : SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.Person
Limits            : SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.PictureLimit

Informationen über Konstrukteur und Bildgrenzen gefällig?

PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien> $projekt.Constructor
Name                                    DefaultValueSource                                                   UseDefault
----                                    ------------------                                                   ----------
Stefan Falk                                                                                                        True

PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien> $projekt.Limits

MaxPublishedWidth    : 800
MaxPublishedHeight   : 800
MaxPublishedSizeInKB : 80
DefaultValueSource   :
UseDefault           : True

Etwas Spannenderes

Die Aufgabe: Erstelle ein leeres Projekt, packe alle *.JPG von hier incl. Unterverzeichnissen rein, gib Informationen über das Projekt aus und speichere es:

PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien\fischertechnik\Eigene Modelle> $projekt = `
New-Object SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.Project
PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien\fischertechnik\Eigene Modelle> Get-ChildItem -filter *.jpg -recurse `
| ForEach-Object { `
$bild = New-Object SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.FileImageSource($_.FullName); `
$projekt.ImageSources.Add($bild); $bild.LoadImages() }
PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien\fischertechnik\Eigene Modelle> $projekt
ImageSources      : {Bild, Bild, Bild, Bild...}
PublisherSettings : {}
Statistics        : 401 Bilder (1 - 401), alle zu veröffentlichen, 401 fehlende Titel, 401 fehlende Beschreibungen
Identifier        : f855a926-c171-4325-8348-3686407bc333
Title             :
Description       :
Constructor       : SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.Person
Photographer      : SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.Person
Limits            : SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.PictureLimit
PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien\fischertechnik\Eigene Modelle> $projekt.ImageSources.Count
401
PS C:\Dokumente und Einstellungen\Stefan\Eigene Dateien\fischertechnik\Eigene Modelle> $projekt.Save( `
'C:\Dokumente und Einstellungen\Stefan\Eigene Dateien\PowerShell-Test.ftcpub')

Was man so alles machen kann...

Eine wiederverwendbare Funktion

Noch zwei PowerShell-Scripts. Die Kommentare darin sollten für Leute, die sich sowas antun wollen, ausreichen. Dieses Skript erzeugt eine SF ft Community Publisher Projektdatei mit allen Unterordnern des aktuellen Verzeichnisses, in denen JPG-Dateien vorkommen:

function New-AllFoldersFtcProject
{
# Erzeugt eine SF ft Community Publisher Projektdatei mit allen Unterordnern
# des aktuellen Verzeichnisses, in dem JPG-Dateien vorkommen.
# 2007-02-01 sf   Erste Version.
# Publisher-Objektmodell laden:
[System.Reflection.Assembly]::LoadFrom( `
'C:\Programme\SF Softwareberatung\SF ft Community Publisher\SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.dll') `
| Out-Null
# Neues, leeres Projekt erzeugen:
$project = New-Object 'SFSoftwareBeratung.SFFTCommunityPublisher.ObjectModel.Project'
# Titel des Projektes setzen:
$project.Title = 'Projekt mit allen Unterordnern'
# Beschreibung des Projektes setzen:
$project.Description = 'Dieses Projekt enthält alle Unterordner von "' + (Get-Location) + '", die mindestens eine JPG-Datei enthalten.'
# Vom aktuellen Ordner ausgehend:
# - alle Unterobjekte suchen
# - nur nach Ordnern gefiltert
# - nur solche, die mindestens eine .JPG-Datei enthalten
# - für jeden solchen Ordner eine Publisher-Ordner-Bildquelle erzeugen
# - die Bildquelle die Bilder laden lassen (das erzeugt die Informationen
#   über die Bilder in den Ordnern)
# - die Bildquelle dem Publisher-Projekt hinzufügen
# - für jedes Bild in der Bildquelle den Titel des Bildes auf den reinen
#   Dateinamen des Bildes (ohne Pfad und Erweiterung) setzen
Get-ChildItem -recurse `
| Where {$_.PSIsContainer -eq $True} `
| Where {(Get-ChildItem $_.FullName -filter *.jpg).Count -gt 0} `
| ForEach-Object {$imagesource = New-Object SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.FolderImageSource($_.FullName);
$imagesource.LoadImages();
$project.ImageSources.Add($imagesource);
$imagesource.GetAllImages() `
| ForEach-Object {$_.Title = [System.IO.Path]::GetFileNameWithoutExtension($_.FileName)
}
}
# Dateinamen für das Projekt festlegen:
$filename = (Join-Path -path (Get-Location) -childPath 'AllFoldersProject.ftcpub')
# Dateinamen ausgeben:
Write-Host $filename
# Projektstatistik ausgeben:
Write-Host $project.Statistics
# Projekt speichern:
$project.Save($filename)
# Publisher aufrufen und das Projekt laden lassen:
Invoke-Item $filename
}

Nachträgliche Bearbeitung eines Projekts

Das folgende Skript verwendet eine bereits bestehende Projektdatei und verändert die Bildschärfe aller darin enthaltenen Bilder und speichert die so geänderte Projektdatei unter dem alten Namen mit dem Zusatz sharpened:

function Set-FtcProjectSharpness([String] $path, [int] $sharpness)
{
[System.Reflection.Assembly]::LoadFrom( `
'C:\Programme\SF Softwareberatung\SF ft Community Publisher\SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.dll') `
| Out-Null
$project = [SFSoftwareberatung.SFFTCommunityPublisher.ObjectModel.Project]::FromFile($path)
$project.ImageSources | ForEach-Object {$_.Images | ForEach-Object {$_.Sharpness = $sharpness}}
$extension = [IO.Path]::GetExtension($path)
$project.Save($path.Insert($path.Length - $extension.Length, ' sharpened'))
}

Na? Genug Technik für heute? ;-)