Category Archives: Programmierung

Fun with FunScript

FunScript is a compiler or better a transpiler, which converts F# code into JavaScript code.
I have not tried it much since the last couple of days and I’m really amazed how well it works.

I had really good expierences creating D3 charts but I wasn’t shure how well it works with AngularJS, with all his dependency mechanisms and “magic” behind the scenes.
So I thought I give it a try!

I came up with this DSL like syntax:

The DSL code looks like this (mainly it wraps the kinda ugly generated code):

It is still a bit clunky to use (mainly to get angular’s dependency injection to work) and it is far from completed, but at least a simple controller works!

The downsides of using FunScript to generate JavaScript code is the additional code generation step, it generates more verbose code than writing similar code in JavaScript and the debugging is chunky (but that’s a problem nearly every transpiler has). I don’t know of a source map file for the generated code, but maybe I’m missing something.

On the other side you can use this nice functional and composable code in places where I never thought it is possible to get it to work!

The sample project can be found here.

Tagged , , , ,

Import NuGet Packages to F# Interactive Scripts

Yes, it’s been a long time (exactly one year, but that’s a coincidence) since my last blog post. The main reason was that in the last year I learnt F# and slowly I have the feeling that I have understood the language and especially the paradigm shift that comes with F#.

I jump over the usual homage of why F# is a wonderful language – that’s material for a plethora of blog posts – and come straight to the motivation of this blog post.

If you are like me and you learn by trying things out you probably love the interactive and iterative nature of F#. Just create a new fsx (F# Interactive) file and start hacking until you have a working prototype. You don’t even have to save the file!
I actually have a folder full of F# scripts with my experimentations in them.

One pain point though is that F# interactive does not have support for NuGet package management. You can reference the library files manually but that’s very cumbersome.

There exists an older blog post from Daniel Mohl where he suggests how to add NuGet support to F# Interactive, but his solution requires the VS Object Model and doesn’t support loose fsx files (without the creation of a F# project).

So I wrote my own “PackageManagement.fsx” file which can be initialized with F# Interactive:

And here is the script code: https://gist.github.com/toburger/9786275

It depends on the NuGet.Core.dll which you can get from here and you must define your target NuGet packages directory, where the packages are downloaded and from where they are referenced (you can define the “NugetLibDir” environment variable so you can use the same script on multiple machines). I ignore the versioning of the packages (I always download the latest stable release), but you can enable it by setting the boolean parameter “useSideBySidePaths” on line 11 to true.

So how to work with this script?

The main command is “ipr” which stands for “install package and references”, which downloads the package with all its dependencies and adds the references to the clipboard, so the only thing you have to do is to paste the references on top of your script file.

Just enter ipr “package name”;; in the f# Interactive REPL (don’t forget the two semicolons) and it will try it’s best to download and reference the packages.

There are also commands to update and uninstall packages or to simply copy the references without trying to download the latest package.

Limitations:

I try my best to find the best matching references for the framework version in which F# interactive runs, but this matching is not bullet proof and unfortunately the NuGet lib doesn’t provide a way to get the best matching references automatically (at least I didn’t found any practical way).

The script should also work without VS and should work on Mono but I don’t have tested it so please feel free to contact me or edit the file if you have any problems.


Actually there is now a suggestion on fslang uservoice with a propose to natively support NuGet packages: http://fslang.uservoice.com/forums/245727-f-language/suggestions/5670137–package-directive-to-import-nuget-packages-in-f

Tagged , ,

Easy monitoring of a folder with pswatch

pswatch is a easy to use little module for PowerShell to montitor a folder for changes.

You can choose if you want to monitor file additions, changes, renames or deletions. You can also monitor file sin subfolders.

Based on this monitoring you can further add scripting to automatically run other commands (see example on github).

I further customized the output to include the time of the occurrence of the event:

watch $env:Temp -includeDeleted | % { $_ | Add-Member ScriptProperty Time { Get-Date } -PassThru }

This adds a dynamic Time property which automatically updates itself when a new file change event is happening.

Tagged , ,

Reset your login credentials for „Visual Studio Tools for Git“

If you change your login credentials for one of the git hosting services (github, bitbucket, …) and you try to pull, fetch or push you probably receive the same error as in the screenshot below:

I struggled a while with the problem until I found the solution.

You have to reset the credentials in the Windows Credential store.

Sorry, I have to translate the text on the fly because I have a German version of Windows 7.

Go to your user account settings and click on “manager your own credentials”:

Pick the credentials for e.g. git:https://bitbucket.org and click on edit:

You should now be able to work with your git remote again:

Hope this helps!

Tagged , , , , ,

PowerShell: Set-Content mit Binärwerten

Ich stoße in PowerShell-Scripts immer wieder auf folgenden Befehl:

[System.IO.File]::WriteAllBytes(<pfad>, <wert>)

Nichts dass daran irgendetwas falsch wäre, es gibt jedoch eine PowerShell-freundlichere Möglichkeit Binärwerte in eine Datei zu schreiben, und zwar mit folgendem Befehl:

Set-Content -Path ... -Value ... -Encoding Byte

Dies hat den Vorteil, dass der Pfad richtig aufgelöst wird und man kann dadurch den Binärwert über die PowerShell Pipeline übergeben.

Beispiel aus der Praxis: Das Auslesen des Profilbildes eines ActiveDirectory-Benutzers und anschließendem Speichern als Datei

Import-Module ActiveDirectory
(Get-ADUser TBurger -Property thumbnailPhoto).thumbnailPhoto | Set-Content TBurger.jpg -Encoding Byte

„eval“-Äquivalent in PowerShell

Heute hatte ich ein vermeintlich einfaches Problem zu lösen:

Ich sollte eine Textdatei mit PowerShell auslesen, welche wiederum PowerShell-Variablen enthält (z.B. $datum, $_.Name, …).

Content.txt:

Hier ist normaler Text
$date

Ergebnis:

Hier ist normaler Text
08/23/2012 09:53:12

Ein einfaches

Get-Content

funktioniert hier nicht, da hierbei die Variablen nicht interpretiert werden und der Text wird so ausgegeben, wie er in der Textdatei steht.

Die Lösung ist, die Methode ExpandString auszuführen, welche in der PowerShell über

$ExecutionContext.InvokeCommand.ExpandString

aufrufbar ist.

$date = Get-Date
$content = Get-Content .\Content.txt    # PowerShell 3 Tipp: -Raw liest die Datei in einem String aus, normalerweise wird ein String-Array ausgelesen.
$content = $ExecutionContext.InvokeCommand.ExpandString($content)

Und schon hat man das gewünschte Resultat. J

Sehr praktisch wenn man z.B. Emails mit einem Body-Template verschicken will.

Man kann sogar so weit gehen, dass man ganze PowerShell-Kommandos ausführen kann (im Prinzip verhält sich der Text wie Text aus einem “Here-String“):

$(get-date)

eval is evil

Wie auch bei eval gilt: Vorsicht, was man einliest, da prinzipiell jedes Kommando im Kontext der ausführenden PowerShell-Instanz ausgeführt wird kann man sehr böse Dinge anstellen!

PowerShell Cmdlet zum Auslesen der Anmeldeinformationen aus der “Windows Anmeldeinformationsverwaltung”

Will man PowerShell-Operationen automatisieren benötigt man gelegentlich Anmeldeinformationen, welche dann irgendwie im Script zur Verfügung gestellt werden müssen. Normalerweise erledigt man dies über Get-Credential, welches allerdings immer eine Benutzerabfrage bedingt und in einem automatisch ablaufenden Script nutzlos ist.

Der einfachste (aber auch unsicherste) Weg ein Passwort auszulesen ist folgender:

$password = ConvertTo-SecureString <plaintextpassword> -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential <username>, $password

Dass dies nicht der bevorzugte Weg ist, sieht man am Umstand, dass der Paramter –Force angegeben werden muss, da ansonsten folgender Fehler ausgegeben wird: “Nur-Text-Eingaben können vom System nicht geschützt werden.”
Und wenn man (hoffentlich) etwas nachdenkt, ist dieses Verhalten auch vollkommen verständlich, denn wer will schon seine Passwörter im Klartext in einer Textdatei hinterlegen.
Auf der anderen Seite ist es doch immer wieder praktisch Logininformationen eines Systems zu ermitteln, indem man Dateien mit den klingenden Namen config.(php|asp|*), connection.(php|asp|*), usw.. durchstöbert. Zwinkerndes Smiley

Nun gibt es zwei Möglichkeiten Passwörter sicher zu hinterlegen

  1. Das Password wird verschlüsselt im Script selbst hinterlegt oder in einer Datei ausgelagert.
  2. Die Anmeldeinformationen werden im “Windows Credential Manager” (das ist die englische Bezeichnung für die Windows Anmeldeinformationsverwaltung) hinterlegt.

Methode 1: PowerShell “out-of-the-box”

Das Password wird in eine Date gespeichert:

// Die Login-Informationen werden abgefragt
$credential = Get-Credential
// Das Password wird in einer Datei gespeichert
$credential.Password | ConvertFrom-SecureString | Set-Content <file>

Das Auslesen des Passwortes wird dann folgendermaßen erledigt:

$password = Get-Content <file> | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential(<username>, $password)

Dieses PSCredential kann man dann den Cmdlets übergeben, welche die Anmeldeinforationen benötigen (z.B. Enter-PSSesssion <server> –Credential $credential).

Zu beachten ist, dass diese Methode nur funktioniert, wenn das Passwort auf demselben Computer ausgelesen wird, auf welchem es auch erstellt wurde, da für die Verschlüsselung/Entschlüsselung der MachineKey verwendet wird.

Damit die Methode über mehrere Computer funktioniert, kann man entweder den MachineKey der Computer angleichen (!) oder ConvertFrom-SecureString und ConvertTo-SecureString einen –Key oder -SecureKey übergeben, welcher dann wiederum sicher aufbewahrt werden sollte, und da man dies mit Methode 1 endlos wiederholen müsste, würde sich Methode 2 anbieten. Zwinkerndes Smiley

Methode 2: “Windows Anmeldeinformationsverwaltung”

Informationen zur Windows Anmeldeinformationverwaltung (englisch: Windows Credential Manager) findet man hier: http://windows.microsoft.com/de-DE/windows7/What-is-Credential-Manager

Hinterlegt werden diese Anmeldeinformationen über Systemsteuerung/Benutzerkonten/Anmeldeinformationsverwaltung. Dabei wird eine Internet- oder Netzwerkadresse (welche später als Schlüssel dient) das Login und das Passwort hinterlegt.

Leider bietet PowerShell keine Möglichkeiten diese Anmeldeinformationen nativ auszulesen. Aus diesem Grund habe ich ein PowerShell Cmdlet erstellt, welches diese Aufgabe übernimmt.

Die Datei findet man hier:

Die Verwendung gestaltet sich dann wie folgt:

$credential = .\Get-CredentialFromWindowsCredentialManager.ps1 <internet- oder netzwerkadresse>
Enter-PSSession <server> –Credential $credential

Die Anmeldeinformationen sind lokal und Benutzerbezogen, das heißt natürlich, sie sind bei Bedarf für ein weiteres Benutzerkonto oder auf einem weiteren Rechner ebenfalls im Windows Credential Manager des jeweiligen Benutzerkontos zu hinterlegen.

Tagged , , ,

dynamic^2 oder ”variable Variablen”

(Irgendwie mag Windows Live Writer kein ² in der Überschrift…) Erzürnt

Seit .NET 4 gehört C# (und natürlich VB.Net) zu dem Kreis der dynamisch typisierten Sprachen. Dies ermöglicht die DLR, die Dynamic Language Runtime.
D.h. man kann Variablen “spät binden” (late binding), d.h. sie werden erst zur Laufzeit in ihren konkreten Typ materialisiert.
Das erlaubt einem eine hohe Flexibilität für verschiedenste Szenarien, wie z.B. beim COM Interop, der Kommunikation mit anderen dynamischen Sprachen für .NET (IronPython, IronRuby, IronJS, Phalanger, …) oder einfach in Situationen in denen der konkrete Typ erst zur Laufzeit bekannt ist (Reflection, XML, …).

Ich möchte jetzt nicht weiter auf die Grundlagen eingehen, da es inzwischen genügend Dokumentation dazu gibt. Einfach mal in die MSDN Doku reinschauen.

Basierend auf dem Beispiel aus der Doku mit dem DynamicDictionary möchte ich auf eine kleine Erweiterung eingehen: variable Variablen.
PHP Programmierer wissen vielleicht was ich meine. In PHP ist es beispielsweise möglich folgendes zu schreiben:

$variableName = "age";
$obj = new stdClass();
$obj->{$variableName} = "31";

echo $obj->age;

Also die Variable (bzw. den Member) variabel zu halten.

In C# ist das Out of the Box nicht möglich. Durch zwei Erweiterungsmethoden kann diese “dynamische Dynamik” aber leicht nachgereicht werden:

public static object GetMember(this object obj, string memberName)
{
    var binder = Binder.GetMember(
        CSharpBinderFlags.None, memberName, obj.GetType(),
        new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
    var getterSite = CallSite<Func<CallSite, object, object>>.Create(binder);
    return getterSite.Target(getterSite, obj);
}

public static void SetMember(this object obj, string memberName, object value)
{
    var binder = Binder.SetMember(CSharpBinderFlags.None, memberName, obj.GetType(),
        new CSharpArgumentInfo[] {
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
            CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant | CSharpArgumentInfoFlags.UseCompileTimeType, null)
        });
    var setterSite = CallSite<Func<CallSite, object, object, object>>.Create(binder);
    setterSite.Target.Invoke(setterSite, obj, value);
}

Somit ist es auch in C# möglich folgendes zu schreiben:

string variableName = "Age";
dynamic obj = new DynamicDictionary();
((object)obj).SetMember(variableName, 31);

Console.WriteLine(obj.Age);

Das Unboxing mittels ((object)obj).SetMember/GetMember… ist dabei notwendig, da es sich um eine Erweiterungsmethode handelt und diese für dynamische Objekte nicht aufgelöst werden.

Alternativ könnte man auch schreiben:

DynamicObjectExtensions.SetMember(
obj, variableName, 31);

Interessant ist, dass die beiden Befehle komplett unterschiedlichen IL Code generieren. Wo bei ersterem Befehl der Methodenaufruf SetMember steht, wird bei zweiterem Befehl SetMember wiederum dynamisch aufgerufen, was einen kleinen Performanceoverhead bedeutet. Man kann diesen jedoch wieder verschwinden lassen, indem man einfach obj nach object castet:

DynamicObjectExtensions.SetMember(
(
object)obj, variableName, 31);
Tagged , , ,

Musste erst kürzlich ein PowerShell-Script über eine Batch-Datei aufrufen, welche sich im selben Ordner befindet. Mit folgendem Befehl kann dies gemacht werden:

 @echo off
 powershell.exe -File "%~dp0\<psscript>.ps1"

Innerhalb des PowerShell-Scriptes kann nun wiederum auf den relativen Pfad verwiesen werden:

 $parentPath = Split-Path -Parent $MyInvocation.MyCommand.Definition

Miscellaneous IT Pimpery

The %~dp0 (that’s a zero) variable when referenced within a Windows batch file will expand to the drive letter and path of that batch file.

View original post 129 more words

PowerPivot OData Feeds filtern

Wenn jemand PivotTabellen erstellen möchte, welche sich über mehrere unabhängige Datenquellen verteilen ist PowerPivot ein geniales Werkzeug.

SharePoint kann über die REST-Schnittstelle eingebunden werden, welches das OData Protokoll implementiert. Dazu muss lediglich die WCF Data Services Bibliothek – die Implementierung von OData über WCF – installiert werden. Diese Schnittstelle ist über http://<sharepoint_server>/_vti_bin/listdata.svc erreichbar.

Eigentlich dachte ich, dass dieses Protokoll voll und ganz von PowerPivot unterstützt wird (zumindest wird einem das immer so erklärt). Leider gibt es einen Bereich, welcher nicht unterstützt wird:
Das Vorfiltern der Daten über den QueryString ist leider nicht möglich. Dies ist dann nützlich, wenn man vermeiden möchte, dass die komplette Liste ausgelesen wird (und anschließend in der Excel-Tabelle gespeichert wird). Die Excel Datei kann so gut und gerne 20 bis 50 MB und größer werden, je nach Anzahl an Elementen.

OData bietet für das Filtern, Sortieren und Selektieren QueryString-Parameter an.
Um z.B. alle Buchungen aus dem Jahr 2012 zu filtern kann folgendes geschrieben werden:
…/listdata.svc/Buchungen?$filter=year(Erhalten) eq 2012

Leider mag PowerPivot QueryStrings ganz und gar nicht! Und mit ganz und gar nicht meine ich, dass diese einfach ignoriert werden. Dass ich nicht der Einzige mit diesem Problem ist sieht man an folgendem Bug Report: https://connect.microsoft.com/SQLServer/feedback/details/724823/import-odata-feed-datasource-into-powerpivot-without-filter

Da ich aber nicht so lange warten wollte, bis dieses Feature in PowerPivot Einzug findet habe ich eine Quick & Dirty Lösung zusammengebastelt, welche funktioniert, aber nicht wirklich schön ist.

Eigentlich sind mir zwei Lösungen eingefallen, die Eine greift in die IIS-Konfiguration von SharePoint ein (der geneigte Leser soll selbst entscheiden, ob dies eine gute Lösung ist), die Andere dient als Gateway zum OData-Feed von SharePoint.
Die zweite Lösung ist etwas komplexer – nicht sehr viel komplexer – aber genug, um aus dem Artikel zwei zu machen. Ich habe zurzeit nicht vor auf diese Lösung genauer einzugehen, es sei den ein Leser ist an der zweiten Lösung interessiert, dann werde ich einen weiteren Blog-Eintrag posten.

Quick & Dirty Lösung: Eingriff in die IIS-Konfiguration von SharePoint

Okay, das Ändern der IIS-Konfiguration von SharePoint ist eigentlich ein absolutes NoGo (außer in den von der SharePoint Dokumentation ausdrücklich erlaubten Fällen), die Lösung hat sich aber als recht einfach und wirkungsvoll erwiesen.

Ich bediene mich hier einfach dem URL Rewriting Modul, welches einem im IIS ab Version 7 zur Verfügung steht (muss aber nachinstalliert werden: http://www.iis.net/download/URLRewrite). Eine “User-friendly URL” Rule später funktioniert das Ganze auch schon. Zu beachten ist allerdings, dass der Webserver-Prozess recycelt wird (nicht der App-Pool, geht also etwas schneller), nachdem Änderungen am URL-Rewriting vorgenommen wurden, das Ganze ist in Produktion also mit Vorsicht zu genießen.

Die URL-Regel in meinem Fall sieht beispielsweise so aus:
image

Im Grunde wird nichts Anderes gemacht, als dass die URL
http://portal/projects/buchungsportal/_vti_bin/listdata/BuchungenKundeImJahr/2012
über einen URL Match
^projects/buchungsportal/_vti_bin/listdata/BuchungenKundeImJahr/([^/]+)/?$
umgeleitet wird zu
projects/buchungsportal/_vti_bin/listdata.svc/Buchungen?$filter=InhaltstypID%20eq%20’0x010100F72541062D58004C81F84CFC226B954702007BDDD584C443764C8A87B2F22748C1AF’%20and%20year(Erhalten)%20eq%20{R:1}

Das Jahr ist also variabel und wird in {R:1} eingefügt, der Inhaltstyp ist immer derselbe, muss also nicht über die URL bestimmt werden (könnte aber ohne Weiteres gemacht werden).

Ein rascher Test mit PowerPivot beweist, dass das Rewriting funktioniert:
image

image

Es kommen auch wirklich nur die Buchungen zurück, welche nach der InhaltstypID und dem Jahr gefiltert wurden.

Tagged