ใช้ Javascript CustomActions เพราะมันง่ายมาก
มีคนบอกว่าJavascript เป็นสิ่งที่ไม่ถูกต้องที่จะใช้สำหรับ MSI CustomActions เหตุผลที่กำหนด: ยากต่อการตรวจแก้จุดบกพร่องยากที่จะทำให้เชื่อถือได้ ฉันไม่เห็นด้วย การแก้ข้อบกพร่องไม่ใช่เรื่องยากแน่นอนว่าไม่ยากกว่า C ++ มันแตกต่างกันเพียง ฉันพบว่าการเขียน CustomActions ใน Javascript นั้นง่ายมากง่ายกว่าการใช้ C ++ เร็วขึ้นมาก และเชื่อถือได้เช่นกัน
มีข้อเสียเปรียบเพียงข้อเดียว: สามารถแยก CustomActions Javascript ผ่าน Orca ในขณะที่ C / C ++ CA จะต้องใช้วิศวกรรมย้อนกลับ หากคุณคิดว่าเวทมนตร์ของผู้ติดตั้งของคุณได้รับการคุ้มครองทรัพย์สินทางปัญญาคุณจะต้องหลีกเลี่ยงสคริปต์
ถ้าคุณใช้สคริปต์คุณต้องเริ่มด้วยโครงสร้างบางอย่าง นี่คือบางส่วนเพื่อให้คุณเริ่มต้น
รหัส Javascript "boilerplate" สำหรับ 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
};
}
จากนั้นให้ลงทะเบียนการกระทำแบบกำหนดเองด้วยสิ่งนี้:
<Fragment>
<Binary Id="IisScript_CA" SourceFile="CustomActions.js" />
<CustomAction Id="CA.MyCustomAction"
BinaryKey="IisScript_CA"
JScriptCall="MyCustomActionInJavascript_CA"
Execute="immediate"
Return="check" />
</Fragmemt>
แน่นอนว่าคุณสามารถแทรกฟังก์ชั่น Javascript ได้มากเท่าที่คุณต้องการสำหรับการกระทำที่กำหนดเองหลายอย่าง ตัวอย่างหนึ่ง: ฉันใช้ Javascript เพื่อทำแบบสอบถาม WMI บน IIS เพื่อรับรายการเว็บไซต์ที่มีอยู่ซึ่งตัวกรอง ISAPI สามารถติดตั้งได้ รายการนี้ถูกใช้เพื่อเติมกล่องรายการที่แสดงในลำดับ UI ทุกอย่างง่ายมาก
บน IIS7 ไม่มีผู้ให้บริการ WMI สำหรับ IIS ดังนั้นฉันจึงใช้shell.Run()
วิธีการเรียกใช้ appcmd.exe เพื่อทำงาน ง่าย.
คำถามที่เกี่ยวข้อง: เกี่ยวกับ Javascript CustomActions