Mai 142010
 
Ausganslage

Zur Zeit arbeite ich an einem grossen Projekt wo wir eine VB6 Anwendung nach .NET (C#) migrieren. Im grossen und ganzen wird einfach die Logik migriert, ohne gross neue Funktionen hinzuzufügen.

In der alten Anwendung wurde zu Berechnungszwecken einiges an Logik in VBScripte ausgelagert. Das machte man, um die Logik anpassen zu können ohne das neue DLLs erstellt werden müssten. Das muss ich jetzt in C# nachbauen. Die VBScripte sollen noch nicht migriert werden. Schlicht vom Aufwand her.

Ich muss ein .NET Objekt an ein VBScript übergeben, das macht die Berechnungen und gibt danach das Objekt wieder an C# zurück.

Zuerst dachte ich, man könnte einfach WScript.exe mit ein paar Parametern aufrufen. Allerdings kann ich so natürlich keine Objekte übergeben. Nach einigem suchen wurde ich dann fündig wie dich ein .NET Objekt an ein VBScript übergeben kann und auch wieder zurück bekomme. Das Stichwort lautet: Microsoft Script Control 1.0

Was muss nun alles gemacht werden um das Problemchen zu lösen.

Erstellen eines COM Visible .NET Objektes

Um ein .NET Objekt in einer COM Umgebung zu bearbeiten muss das Objekt für COM Sichtbar gemacht werden. Das kann in der Projekteinstellung der Klassen gemacht werden.

COM Visible einstellen

COM Visible registrieren

Mit diesen Einstellungen wird das Objekt automatisch von Visual Studio als COM Registriert. Auf einem produktiven System müsste das natürlich das Setup übernehmen oder ein Batch. Mit regasm MyAssembly.dll wird die DLL auf der Commandline registriert oder aus einem Batch raus.

Die Klasse selber kann sehr einfach aussehen.

Aufrufen des VBScriptes

Für den Test habe ich ein ganz einfaches VBScript erstellt. Es wird ein .NET Objekt übergeben und über eine MsgBox gibt es ein paar Meldungen zum Objekt. Somit ist klar das die Wert auch wirklich im VBScript manipuliert werden und auch wieder zurück ins .NET kommen.

Aber um ein VBScript auszuführen muss noch eine DLL eingebunden werden.

Microsoft Scripting Control 1.0

Unter Verweis hinzufügen wechselt man in das COM Register und sucht dort das Microsoft Scripting Control 1.0. Danach kann man auf das Control im Code zugreifen. Einfach noch das using hinzufügen wie in Zeile 6 im folgenden Code zu sehen.

In den Zeilen 14 bis 16 wird ein VBScript geladen das im selben Verzeichnis liegt wie die Testanwendung. Das Script wird noch erläutert.

In Zeile 27 bis 42 findet die Ausführung des VBScriptes statt. Zuerst wird eine neue Instanz von ScriptControlClass erstellt und ein paar Parameter gesetzt. Mit script.AddCode übergibt man dem Control den Code den es ausführen soll. Achtung. Wenn das VBScript keine Sub oder Function enthält wird das Script schon in der Zeile 38 ausgeführt. Aber sobald das VBScript eine Function oder Sub enthält passiert in dieser Zeile noch nichts.

In Zeile 35 erstelle ich das Objekt das ich an das VBScript übergeben will. Man beachte das Alter. Das ist beim initialisieren auf 35 gesetzt. Zur Kontrolle gebe ich das in Zeile 36 aus.

In Zeile 38 übergebe ich das Objekt an das VBScript. Hier wird es auch wieder interessant. Im ersten Parameter geben ich eine Bezeichnung für das Objekt an. Genau mit dieser Bezeichnung greift man dann im VBScript auf die Person zu. In Zeile 42 wird schlussendlich die Funktion CalculateStatus() aufgerufen.

In Zeile 44 gebe ich nochmals das Alter aus. Und siehe da, es ist nicht mehr 35 sondern 99. Das alter 99 wurde im VBScript gesetzt. Der Informationsaustausch fand also statt. Ich kann ein .NET Objekt in VBScript manipulieren und die Ergebnisse stehen mir in .NET zur Verfügung.

Das VBScript

Das VBScript macht nicht viel spezielles.

In Zeile 1 ist die Sub CalculateStatus definiert. In Zeile 3 definiere ich das Objekt oPerson und setze es in der Zeile 4. Und hier sieht man wieder die Person. Das ist genau die Person die man mit script.AddObject("Person", person, true);  übergeben hat.

In Zeile 9 wird die original Person kurz Visualisiert. Und Zeile 11 wird das Alter auf 99 gesetzt und in Zeile 13 wird die Person nochmals Visualisiert. Danach ist das VBScript fertig.

Im .NET ist das Alter der Person nun 99.

Result

Fazit

Was mir am Anfang als unlösbar mit .NET erschien ist im nachhinein sehr einfach zu lösen. Dank dem Internet und Google findet man irgend wann schon eine Lösung.

Jetzt gilt es nur noch ein Problem zu lösen. Die VBScripte müssen im Debugger gestartet werden können. Dazu gäbe es ja das Schlüsselwort stop im VB. Allerdings greift das nicht. Hier muss ich noch nach einer Lösung suchen was aber auch machbar sein wird.

Was noch cool wäre

So etwas sollte es auch mit C# als Script geben.

kick it on dotnet-kicks.de

Sorry, the comment form is closed at this time.