Karte

 

Umgebungsvariable über die CMD erstellen

Unter Windows 7 (und vermutlich auch XP, aber nicht getestet) kann man in der CMS recht simpel Umgebungsvariabeln definieren.
Die Variabeln die man mit set definiert bleiben ja nur, solange man die Session offen hat, wenn man Aber Variabel definieren will die zum einen Länger halten und auch für das komplette System Benutzbar sind, kann man das mit dem Befehl setx machen.
Um eine Umgebungsvariable nur für den aktuellen Benutzer zu erstellen benötigt man keine speziellen Benutzerrechte und kann mit dem folgenden Befehl die Variable erstellen:
setx NAME WERT

Um aber eine Variable für die ganze Maschine zu erstellen muss man Admin-Rechte haben und die CMD auch als Elevated-Process ausführen. Dann kann man ganze einfach mit dem Parameter /M die Variable global erstellen:
setx /M NAME WERT

Problem: Netzlaufwerke werden unter Windows 7 nicht verbunden

Im Geschäft haben wir inzwischen einige Maschinen mit Windows 7. Dabei hatte ich bei allen das Problem, dass die Netzlaufwerke nicht verbunden wurden. Dasselbe Startscript ist als Gruppenrichtlinie eingebunden und läuft unter Windows XP ohne Probleme. Wenn ich das Startscript unter Windows 7 manuell aufrufe funktioniert es auch Problemlos und die Netzlaufwerke werden verbunden. Zudem sehe ich auch, dass das Startscript beim Aufstarten durchläuft und Fehler werden keine ausgegeben. Was ist also das Problem?
Nach einigem Nachforschen habe ich herausgefunden, dass Windows 7 die Netzlaufwerke sehr wohl verbindet, scheinbar aber mit anderen Benutzerrechten und dementsprechend werden die Laufwerke einfach nicht angezeigt. Das ganze kann man folgendermassen umgehen:

Man öffnet die Registry:
Start -> Ausführen -> regedit.exe

Nun öffnet man dort den folgenden Tree:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System

Dort erstellt man einen neuen DWORD eintrag mit dem Namen EnableLinkedConnections und setzt den Wert darin auf 1.
http://images.t-error.ch/blog/1457/linked_connections.jpg


Und beim nächsten Start der Maschine werden die Netzlaufwerke brav verbunden und auch angezeigt.

VMware Tools unter Ubuntu installieren

Wer seine Server mit VMware virtualisiert hat, installiert auf den virtuellen Maschinen idealerweise die VMware-Tools. Auf Windows Maschinen ist das sehr simpel und auch auf Linux-Servern geht das recht einfach.
Dazu muss man zuerst im vSphere Client die Installation der VMware-Tools anstossen, damit dem Server die CD zur Verfügung gestellt wird.
http://images.t-error.ch/blog/1456/vmware_tools_01.jpg


Nun kann man das CD-Laufwerk mounten und die Installationsdatei (für Ubuntu die .tar.gz Datei) in einen anderen Ordner kopieren und das Laufwerk wieder unmounten.
root@srvWEB02:~# mount /dev/cdrom /media/cdrom/
root@srvWEB02:~# cp /media/cdrom/VMwareTools-4.0.0-261974.tar.gz /tmp
root@srvWEB02:/tmp# umount /media/cdrom/

Als nächstes wechselt man in den anderen Ordner und entpackt die Installationsdatei.
root@srvWEB02:~# cd /tmp/
root@srvWEB02:/tmp# tar -xvzf VMwareTools-4.0.0-261974.tar.gz

Jetzt ruft man die Installationsdatei auf und arbeitet sich durch alle Fragen durch. Bei mir haben alle Pfade schon gestimmt und ich musste nichts anpassen
root@srvWEB02:/tmp# vmware-tools-distrib/vmware-install.pl

Nachdem die Installation durchgelaufen ist, starten man den virtuellen Server noch neu und Voila: Die Tools sind installiert:
http://images.t-error.ch/blog/1456/vmware_tools_02.jpg

JavaScript urlEncode()

Für eine Web-Applikation bei uns im Geschäft musste ich einen Link auf eine Seite mit PHP und Javascript erstellen. An sich kein Problem, nur musste ich in der URL einige Parameter mit Umlauten und Sonderzeichen übergeben, also musste ich den Parameter richtig umwandeln. Mit PHP geht das recht simpel mit der Funktion urlEncode() nur in Javascript gibt es da keine Funktion die einen String genau gleich maskiert.
Zwar gibt es die Funktionen encodeURI() und encodeURIComponent(), nur wandeln die die Zeichen etwas anders um:
Original:                 test: äöü +?&% -*'()
PHP urlEncode():          test%3A+%E4%F6%FC+%2B%3F%26%25+-%2A%27%28%29
JS encodeURI():           test:%20%C3%A4%C3%B6%C3%BC%20+?&%25%20-*'()
JS encodeURIComponent():  test%3A%20%C3%A4%C3%B6%C3%BC%20%2B%3F%26%25%20-*'()

Also habe ich mir selber eine Funktion gebastelt, die den String zuerst mit espace() maskiert und danach noch gewisse Sonderzeichen mit replace() richtig umwandelt.
function urlEncode(str)
{
    return escape(str).replace(/\+/g,'%2B').
        replace(/%20/g,'+').replace(/@/g,'%40').
        replace(/\*/g,'%2A').replace(/\//g,'%2F');
}

Das Resultat sieht dann folgendermassen aus:
Original:         test: äöü +?&% -*'()
PHP urlEncode():  test%3A+%E4%F6%FC+%2B%3F%26%25+-%2A%27%28%29
JS urlEncode():   test%3A+%E4%F6%FC+%2B%3F%26%25+-%2A%27%28%29

PDF-Icon in Sharepoint Foundation einbinden

Im Geschäft bin ich gerade ein SharePoint Foundation am installieren bzw. konfigurieren. Eines (der vielen) Probleme ist, dass bei PDF-Dokumenten kein Icon angezeigt wird, was das ganze etwas unübersichtlich macht. Das ganze kann aber recht schnell lösen. Dazu muss man das Icon für auf den Server kopieren und eine XML-Datei anpassen.
http://images.t-error.ch/blog/1379/sharepoint_vorher.jpg

Als erstes kopiert man dazu das PDF-Icon in einer Grösse von 16x16 Pixel auf den Server. Bei meinem Windows 2008 R2 Server, war das der folgende Ordner:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\TEMPLATE\IMAGES

Dazu kann man das Icon benutzen: http://images.t-error.ch/blog/1379/icpdf.gif

Jetzt muss man noch die Datei DOCICON.XML anpassen, welche in diesem Ordner liegt:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\TEMPLATE\XML

Der macht fügt man im Abschnitt ByExtension die folgende Zeile hinzu.
<Mapping Key="pdf" Value="icpdf.gif" OpenControl=""/>
Wichtig ist, dass der Dateiname gleich ist, wie der vom Bild.

Nun muss man auf dem Server mit dem Befehl iisreset noch den Webserver neustarten und dann werden die Icons schon angezeigt.
http://images.t-error.ch/blog/1379/sharepoint_nachher.jpg

Das ganze funktioniert natürlich auch mit den Icons von anderen Dateiendungen.

Access-based Enumeration und Windows 2008 R2

Vor bald drei Jahren habe ich mal einen Artikel über Access-based Enumeration bei eine Windows 2003 Server geschrieben.
Letzthin habe ich im Geschäft einen Windows 2008 R2 Fileserver in Betrieb genommen und wollte dort auch wieder ABE einschalten. Das ganze geht nun recht einfach und ohne die Installation von zusätzlicher Software.
Dazu öffnet man eine Management Console (Start -> Ausführen -> MMC) und fügt dort das Snap-in "Share and Storage Management" hinzu. In der Liste wählt man nun den Share, auf dem man die ABE einschalten will und klickt dann auf Advanced. In diesem Fenster kann man nun die ABE einschalten.
http://images.t-error.ch/blog/1325/abe.jpg

Dateien mit zu langem Namen löschen

Letzhin hatte ich wieder das Problem, dass ich eine Datei im Windows nicht löschen konnte, weil der Name zu lang ist. Dann kann man die Datei weder löschen noch umbenennen. Auch in der CMD kommt der folgende Fehler:
Der Dateiname oder die Erweiterung ist zu lang.

Eine Lösung ist den Pfad als separates Laufwerk einzubinden und schon kann man die Datei löschen. Dies geht mit dem Befehl subst.
Zu beachten ist, dass der Pfad am besten in Anführungszeichen geschrieben wird, dann gibt es auch keine Probleme mit Abständen im Pfad. In diesem Beispiel wird der Pfad als Laufwerk s: eingebunden, man kann natürlich jedes nicht benutzte Laufwerk verwenden.
subst s: "pfad"
s:
del "datei"

Die Dateien kann man nun natürlich auch über den Datei-Explorer löschen.
Zum Schluss kann man das Laufwerk wieder aushängen:
subst s: /d

Excel Dateien mit PHPExcel erstellen

Letzte Woche habe ich hier bereits darüber geschrieben, wie man mit dem MS-Excel Stream Handler Excel Dateien erstellen kann, nun habe ich hier noch eine andere, viel umfangreichere Lösung.
Die Lösung nennt sich PHPExcel und kommt von CodePlex. Die "Installation" ist sehr simpel, ZIP Datei herunterladen und die PHP-Dateien auf dem Server speichern. Im Script, das die Excel Datei schreiben soll dann die Dateien PHPExcel.php und PHPExcel/IOFactory.php einbinden.
<?
require_once("includes/PHPExcel.php");
require_once(
"includes/PHPExcel/IOFactory.php");
?>

Die ganze Klasse ist viel zum Umfangreich um hier komplet beschrieben zu werden, ich beschränke mich lediglich auf das schreiben eines Excel Files ohne Formatierung. Wer etwas Farbe ins speil bringen will, oder Formeln, Rahmen usw. benutzen will führt sich am besten die sehr ausführliche Dokumentation zu gemüte.

Wenn die beiden Dateien eingebunden sind, muss man als erstes eine Instanz der Klasse erstellen und kann danach gewisse Dokumenteigenschaften wie den Ersteller Titel usw. schreiben.
<?
// neue instanz erstellen
$xls=new PHPExcel();

// dokumenteigenschaften schreiben
$xls->getProperties()->setCreator("David Lienhard")
                     ->
setLastModifiedBy("David Lienhard")
                     ->
setTitle("Test")
                     ->
setSubject("Test");
?>


Beim nächsten Schritt definiert man, in welches Worksheet man schreiben will. Ich habe bei diesem Beispiel nur ein Sheet und so kann ich auch nur das anwählen.
<?
// das erste worksheet anwaehlen
$sheet=$xls->setActiveSheetIndex(0);
?>


Nun kann man die gewünschten Daten in die Datei schreiben. Die Methode erwartet zwei Parameter. Zum einen das Feld, in das geschrieben werden soll und der Wert, der geschrieben werden soll. Das Feld muss im Format A1 angegeben werden, also genau wie im Excel.
<?
// den wert test in das Feld A1 schreiben
$sheet->setCellValue("A1","test");
?>


Nun kann man noch den Titel des aktuellen Worksheets definieren. Wird nichs angegebn wird einfach der Filename benutzt.
<?
// den namen vom Worksheet 1 definieren
$xls->getActiveSheet()->setTitle("Titel");
?>


Zum Schluss müssen die Daten noch in eine Datei geschrieben werden. Dazu erstellt man erstmal eine neue Instanz der IOFactory und gibt dort an, welchen Dateityp die Datei haben soll. Also Excel 2007, Excel 5 usw. Ich habe aus Kompatibilitätsgründen Excel 5 gewählt.
<?
// eine writer instanz erstellen
// das dateiformat ist hier excel5
// alt, aber von allen excel versionen lesbar
$writer=PHPExcel_IOFactory::createWriter($xls,"Excel5");

// die daten speichern
$writer->save("filename.xls");
?>


Und so sieht das ganze Script aus:
<?
// neue instanz erstellen
$xls=new PHPExcel();

// dokumenteigenschaften schreiben
$xls->getProperties()->setCreator("David Lienhard")
                     ->
setLastModifiedBy("David Lienhard")
                     ->
setTitle("Test")
                     ->
setSubject("Test");

// das erste worksheet anwaehlen
$sheet=$xls->setActiveSheetIndex(0);

// den wert test in das Feld A1 schreiben
$sheet->setCellValue("A1","test");

// den namen vom Worksheet 1 definieren
$xls->getActiveSheet()->setTitle("Titel");

// eine writer instanz erstellen
// das dateiformat ist hier excel5
// alt, aber von allen excel versionen lesbar
$writer=PHPExcel_IOFactory::createWriter($xls,"Excel5");

// die daten speichern
$writer->save("filename.xls");
?>

Excel Dateien mit PHP und MS-Excel Stream Handler erstellen

Im Geschäft musste ich eine kleine Web-App erstellen, die Excel-Files ausliest und in einem anderen Format wieder neue Excel-Files schreibt. Wie man Excel-Files ausliest habe ja ja bereits beschrieben, darum hier eine kleines Howto, wie man Excel-Dateien schreibt.

Von PHP selber gibt es dazu keine Funktionen, dafür aber verschiedene Klassen und Funktionen dritter. Eine recht simple Möglichkeit ist der MS-Excel Stream Handler, den man nach einer Registration gratis herunterladen kann.

Die Funktion wird über ein File eingebunden und registriert sich dann gleich selber einen neuen Filestream mit dem Namen xlsfile. Die Vorgehensweise ist recht simpel: Man erstellt sich einen zweidimensionalen Array und schreibt diesen serialisiert über den Stream in die Datei. Etwas unschön ist in meiner Meinung, dass der Array-Index gleich als erste Zeile benutzt wird.

Aber hier ein kleines Beispiel:
<?
// einen array erstellen
$data=array();

// zweite zeile definieren
// der array-index (ueberschrift1-5) wird als erste zeile verwendet
$data[]=array(
    
"ueberschrift1" =>  "zeile 2 - spalte 1",
    
"ueberschrift2" =>  "zeile 2 - spalte 2",
    
"ueberschrift3" =>  "zeile 2 - spalte 3",
    
"ueberschrift4" =>  "zeile 2 - spalte 4",
    
"ueberschrift5" =>  "zeile 2 - spalte 5");

// dritte zeile definieren
$data[]=array(
    
"ueberschrift1" =>  "zeile 3 - spalte 1",
    
"ueberschrift2" =>  "zeile 3 - spalte 2",
    
"ueberschrift3" =>  "zeile 3 - spalte 3",
    
"ueberschrift4" =>  "zeile 3 - spalte 4",
    
"ueberschrift5" =>  "zeile 3 - spalte 5");

// dateiname definieren
$filename="excel.xls";

// stream oeffnen
$fp=fOpen("xlsfile:/".$filename,"wb");

// check ob datei erstellt werden konnte (schreibrechte, korrekter pfad)
if(!is_resource($fp))
{
    die(
"konnte datei nicht erstellen");
}

// den serialisierten array schreiben
fWrite($fp,serialize($data));

// datei schliessen
fClose($fp);
?>

Das ergibt dann das folgende Erbebnis:
http://images.t-error.ch/blog/1256/excel.jpg


Der erstellen eines Excel-Files geht so sehr einfach und schnell von der Hand, dafür hat man aber keine weiteren Konfigurationsmöglichkeiten. Man kann keine weiteren Tabellenblätter hinzufügen und die erste Zeile ist immer der Arrayindex.
Ich werde auf meiner Blog demnächst eine andere Möglichkeit beschrieben, die etwas aufwändiger ist, aber auch mehr Konfigurationsmöglichkeiten bietet.

Energieoptionen über die Shell verwalten

Die Energieoptionen in Windows kann man zum einen über Gruppenrichtlinien verwalten, oder auch über die Shell. Das ganze funktioniert mit dem Befehl powercfg. Um zum Beispiel zu konfigurieren nach welcher Zeit der Bildschirm ausgeschaltet wird, gibt man den folgenden Befehl ein:
powercfg -CHANGE Desktop -monitor-timeout-ac 20
Desktop steht hier für das Schema das geändert werden soll. In Windows XP muss dieser Wert angegeben werden, in Windows 7 wird das aktuelle Schema verwendet, wenn dieser Parameter fehlt. -monitor-timeout-ac definiert die Zeit nach der der Bildschirm im Netzbetrieb ausgeschaltet werden soll. Für den Akkubetrieb muss man -monitor-timeout-dc verwenden. Wenn der Bildschirm nicht ausgeschaltet werden soll, kann man 0 als wert angeben. Wenn man will, dass der Bildschirm nach 20 Minuten ausschaltet, die Festplatte und der ganze Computer im weiter läuft, kann man das folgendermassen konfigurieren:
powercfg -CHANGE Desktop -monitor-timeout-ac 20
powercfg -CHANGE Desktop -disk-timeout-ac 0
powercfg -CHANGE Desktop -standby-timeout-ac 0
powercfg -CHANGE Desktop -hibernate-timeout-ac 0