Verwenden Sie Javascript CustomActions, weil sie so einfach sind
Die Leute haben gesagt, dass Javascript das Falsche für MSI CustomActions ist . Gründe angegeben: schwer zu debuggen, schwer zuverlässig zu machen. Ich stimme nicht zu Es ist nicht schwer zu debuggen, schon gar nicht schwerer als C ++. Es ist einfach anders. Ich fand das Schreiben von CustomActions in Javascript sehr einfach, viel einfacher als die Verwendung von C ++. Viel schneller. Und genauso zuverlässig.
Es gibt nur einen Nachteil: Javascript CustomActions können über Orca extrahiert werden, während eine C / C ++ - Zertifizierungsstelle ein Reverse Engineering erfordern würde. Wenn Sie die Magie Ihres Installationsprogramms als geschütztes geistiges Eigentum betrachten, sollten Sie Skripte vermeiden.
Wenn Sie ein Skript verwenden, müssen Sie nur mit einer Struktur beginnen. Hier sind einige, um Ihnen den Einstieg zu erleichtern.
Javascript "Boilerplate" Code für CustomAction:
//
// CustomActions.js
//
// Template for WIX Custom Actions written in Javascript.
//
//
// 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, // success
Cancel : 2,
Abort : 3,
Retry : 4, // aka suspend?
Ignore : 5 // skip remaining actions; this is not an error.
};
function MyCustomActionInJavascript_CA() {
try {
LogMessage("Hello from MyCustomActionInJavascript");
// ...do work here...
LogMessage("Goodbye from MyCustomActionInJavascript");
}
catch (exc1) {
Session.Property("CA_EXCEPTION") = exc1.message ;
LogException(exc1);
return MsiActionStatus.Abort;
}
return MsiActionStatus.Ok;
}
// Pop a message box. also spool a message into the MSI log, if it is enabled.
function LogException(exc) {
var record = Session.Installer.CreateRecord(0);
record.StringData(0) = "CustomAction: Exception: 0x" + decimalToHexString(exc.number) + " : " + exc.message;
Session.Message(MsgKind.Error + Icons.Critical + Buttons.btnOkOnly, record);
}
// spool an informational message into the MSI log, if it is enabled.
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
};
// Run a command via cmd.exe from within the MSI
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+")");
// use cmd.exe to redirect the output
var rc = wshell.Run("%comspec% /c " + command + "> " + tmpFileName, WindowStyle.Hidden, true);
LogMessage("shell.Run rc = " + rc);
// here, optionally parse the output of the command
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 wie folgt:
<Fragment>
<Binary Id="IisScript_CA" SourceFile="CustomActions.js" />
<CustomAction Id="CA.MyCustomAction"
BinaryKey="IisScript_CA"
JScriptCall="MyCustomActionInJavascript_CA"
Execute="immediate"
Return="check" />
</Fragmemt>
Sie können natürlich beliebig viele Javascript-Funktionen für mehrere benutzerdefinierte Aktionen einfügen. Ein Beispiel: Ich habe Javascript verwendet, um eine WMI-Abfrage in IIS durchzuführen und eine Liste der vorhandenen Websites abzurufen, auf denen ein ISAPI-Filter installiert werden kann. Diese Liste wurde dann verwendet, um ein Listenfeld zu füllen, das später in der UI-Sequenz angezeigt wird. Alles sehr einfach.
Unter IIS7 gibt es keinen WMI-Anbieter für IIS, daher habe ich den shell.Run()
Ansatz verwendet, um appcmd.exe aufzurufen, um die Arbeit auszuführen. Einfach.
Verwandte Frage: Über Javascript CustomActions