Verwenden Sie Javascript-CustomActions, weil sie soooo einfach sind
Manche Leute haben gesagt, dass Javascript das falsche Werkzeug für MSI CustomActions ist. Gründe dafür sind: schwer zu debuggen, schwer zuverlässig zu machen. Ich stimme dem nicht zu. Es ist nicht schwer zu debuggen, sicherlich nicht schwieriger als C++. Es ist einfach anders. Ich fand das Schreiben von CustomActions in Javascript super einfach, viel einfacher als mit C++. Viel schneller. Und genauso zuverlässig.
Es gibt nur einen Nachteil: Javascript CustomActions können mit Orca extrahiert werden, während eine C/C++-CA Reverse-Engineering erfordern würde. Wenn Sie möchten, dass Ihr Installationsprogramm als geistiges Eigentum geschützt ist, sollten Sie Skripten ausweichen.
Wenn Sie Skript verwenden, müssen Sie nur mit einer Struktur beginnen. Hier ist etwas, um Ihnen den Einstieg zu erleichtern.
Javascript-"Boilerplate"-Code für CustomAction:
//
// CustomActions.js
//
// Vorlage für WIX-Custom Actions in Javascript geschrieben.
//
//
// Mon, 23. Nov 2009 10:54
//
// ===================================================================
// http://msdn.microsoft.com/en-us/library/sfw6660x(VS.85).aspx
var Buttons = {
OkOnly : 0,
OkCancel : 1,
AbortRetryIgnore : 2,
YesNoCancel : 3
};
var Icons = {
Critical : 16,
Question : 32,
Exclamation : 48,
Information : 64
};
var MsgKind = {
Error : 0x01000000,
Warning : 0x02000000,
User : 0x03000000,
Log : 0x04000000
};
// http://msdn.microsoft.com/en-us/library/aa371254(VS.85).aspx
var MsiActionStatus = {
None : 0,
Ok : 1, // Erfolg
Cancel : 2,
Abort : 3,
Retry : 4, // auch suspend genannt?
Ignore : 5 // überspringt restliche Maßnahmen; das ist kein Fehler.
};
function MyCustomActionInJavascript_CA() {
try {
LogMessage("Hallo von MyCustomActionInJavascript");
// ...hier arbeiten...
LogMessage("Auf Wiedersehen von MyCustomActionInJavascript");
}
catch (exc1) {
Session.Property("CA_EXCEPTION") = exc1.message ;
LogException(exc1);
return MsiActionStatus.Abort;
}
return MsiActionStatus.Ok;
}
// Zeigt eine MessageBox an. Schreibt auch eine Nachricht ins MSI-Protokoll, wenn es aktiviert ist.
function LogException(exc) {
var record = Session.Installer.CreateRecord(0);
record.StringData(0) = "CustomAction: Ausnahme: 0x" + decimalToHexString(exc.number) + " : " + exc.message;
Session.Message(MsgKind.Error + Icons.Critical + Buttons.btnOkOnly, record);
}
// Schreibt eine Informationsnachricht ins MSI-Protokoll, wenn es aktiviert ist.
function LogMessage(msg) {
var record = Session.Installer.CreateRecord(0);
record.StringData(0) = "CustomAction:: " + msg;
Session.Message(MsgKind.Log, record);
}
// http://msdn.microsoft.com/en-us/library/d5fk67ky(VS.85).aspx
var WindowStyle = {
Hidden : 0,
Minimized : 1,
Maximized : 2
};
// http://msdn.microsoft.com/en-us/library/314cz14s(v=VS.85).aspx
var OpenMode = {
ForReading : 1,
ForWriting : 2,
ForAppending : 8
};
// http://msdn.microsoft.com/en-us/library/a72y2t1c(v=VS.85).aspx
var SpecialFolders = {
WindowsFolder : 0,
SystemFolder : 1,
TemporaryFolder : 2
};
// Führt einen Befehl über cmd.exe innerhalb des MSI aus
function RunCmd(command)
{
var wshell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject");
var tmpdir = fso.GetSpecialFolder(SpecialFolders.TemporaryFolder);
var tmpFileName = fso.BuildPath(tmpdir, fso.GetTempName());
LogMessage("shell.Run("+command+")");
// Verwende cmd.exe, um die Ausgabe umzuleiten
var rc = wshell.Run("%comspec% /c " + command + "> " + tmpFileName, WindowStyle.Hidden, true);
LogMessage("shell.Run rc = " + rc);
// hier optional die Ausgabe des Befehls parsen
if (parseOutput) {
var textStream = fso.OpenTextFile(tmpFileName, OpenMode.ForReading);
while (!textStream.AtEndOfStream) {
var oneLine = textStream.ReadLine();
var line = ParseOneLine(oneLine);
...
}
textStream.Close();
}
if (deleteOutput) {
fso.DeleteFile(tmpFileName);
}
return {
rc : rc,
outputfile : (deleteOutput) ? null : tmpFileName
};
}
Registrieren Sie dann die benutzerdefinierte Aktion mit etwas Ähnlichem:
Sie können natürlich beliebig viele Javascript-Funktionen einfügen, für mehrere benutzerdefinierte Aktionen. Ein Beispiel: Ich habe Javascript verwendet, um eine WMI-Abfrage auf IIS auszuführen, um eine Liste vorhandener Websites zu erhalten, an die ein ISAPI-Filter installiert werden könnte. Diese Liste wurde dann verwendet, um später in der UI-Sequenz ein Listenfeld zu bevölkern. Alles ganz einfach.
Bei IIS7 gibt es keinen WMI-Anbieter für IIS, daher habe ich den Ansatz shell.Run()
verwendet, um appcmd.exe aufzurufen und die Arbeit auszuführen. Einfach.
Zugehörige Frage: Über Javascript CustomActions
0 Stimmen
Blicken Sie sich gui4wix.codeplex.com an
10 Stimmen
Als nicht konstruktiv geschlossen? Ich habe eine Menge gelernt, indem ich diese Frage gestellt habe! Ein wenig Konsistenz von StackOverflow wäre auch schön...z.B. stackoverflow.com/questions/550632/…
15 Stimmen
Es bekam '203' Likes, das reicht aus, um seine Nützlichkeit zu beweisen.
0 Stimmen
SO-Fragen müssen eine definitive, korrekte Antwort haben; offene Fragen führen dazu, dass die Fragen, die die Leute zu tatsächlichen Problemen stellen, von der Startseite abrutschen. FAQ @Si.: Diese Richtlinie war meines Wissens schon immer da, aber sie wird jetzt besser durchgesetzt; diese Frage ist fast drei Jahre alt.
0 Stimmen
Fair genug, Jim, es handelt sich um eine offene Frage, und ich denke, es liegt an der SO-Community zu entscheiden, aber ich muss sagen, dass es eigenartig erscheint, sie als nicht konstruktiv zu schließen, da ich persönlich und anscheinend auch viele andere Personen diese Frage nützlich gefunden haben (z. B. goo.gl/Zqp2X), und dass sie sehr gut zum Teil des FAQs passt, der sich mit
praktischen, beantwortbaren Fragen basierend auf tatsächlichen Problemen, mit denen Sie konfrontiert sind
befasst.0 Stimmen
Es ist nützlich (warum ich hier bin), aber es handelt sich nicht um ein Frage-und-Antwort-Spiel, sondern um eine Diskussion. Die Frage selbst scheint eine legitime Frage zu sein und die aktuell am meisten hochgevotete Antwort scheint eine legitime Antwort zu sein, aber der Rest der Antworten fügen nur ihren Senf hinzu, was es zu einer Diskussion macht.