Scripting 用于更改MSI中的操作序列记录的脚本

Scripting 用于更改MSI中的操作序列记录的脚本,scripting,build-process,windows-installer,Scripting,Build Process,Windows Installer,要解决问题,我必须更改MSI中的InstallExecuteSequence.RemoveExistingProducts记录 我想将此作为构建过程的一部分来完成,而不是在Orca中修改MSI_SetProperty.js脚本 // MSI_SetActionSequence.js <msi-file> <table> <action> <sequence> // Performs a post-build fixup of an msi to s

要解决问题,我必须更改MSI中的InstallExecuteSequence.RemoveExistingProducts记录


我想将此作为构建过程的一部分来完成,而不是在Orca中修改MSI_SetProperty.js脚本

// MSI_SetActionSequence.js <msi-file> <table> <action> <sequence>
// Performs a post-build fixup of an msi to set the specified table/action/sequence

// Constant values from Windows Installer SDK
var msiOpenDatabaseModeTransact = 1;

var msiViewModifyInsert         = 1;
var msiViewModifyUpdate         = 2;
var msiViewModifyAssign         = 3;
var msiViewModifyReplace        = 4;
var msiViewModifyDelete         = 6;

if (WScript.Arguments.Length != 4)
{
    WScript.StdErr.WriteLine("Usage: " + WScript.ScriptName + " file table action sequence");
    WScript.Quit(1);
}

var filespec = WScript.Arguments(0);
var table = WScript.Arguments(1);
var action = WScript.Arguments(2);
var sequence = parseInt(WScript.Arguments(3));

var installer = WScript.CreateObject("WindowsInstaller.Installer");
var database = installer.OpenDatabase(filespec, msiOpenDatabaseModeTransact);

WScript.StdOut.WriteLine("Looking for action:" + action);

try
{   
    var sql = "SELECT Action, Sequence FROM " + table + " WHERE Action = '" + action + "'";
    var view = database.OpenView(sql);  

    view.Execute();     
    var record = view.Fetch();  

    if (record)
    {       
        while (record)
        {
            WScript.StdOut.Write("Found: " + record.StringData(0) + ", " + record.StringData(1) + ", " + record.StringData(2));
            if (record.IntegerData(2) != sequence)
            {
                WScript.StdOut.WriteLine(" - changing to " + sequence);
                record.IntegerData(2) = sequence;
                view.Modify(msiViewModifyUpdate,record);
            }
            else
                WScript.StdOut.WriteLine(" - OK");

            record = view.Fetch();
        }

        view.Close();
        database.Commit();
    }
    else
    {           
        view.Close();   
        throw("Warning - Could not find " + table + "." + action);
    }
}
catch(e)
{
    WScript.StdErr.WriteLine(e);
    WScript.Quit(1);
}

一些笔记给其他人。我遇到了“错误1001。指定的服务已经存在”的问题,并尝试了上面的方法,但似乎不起作用。以下是我遇到的情况:

*确保安装程序项目上的RemovePreviousVersions属性设置为True。这似乎很明显,很明显,如果你知道的话。默认情况下,它设置为False。如果为False,上述步骤将无法解决您的问题*

我在GAC中安装了一些程序集。似乎当我移动RemoveExistingProducts序列时,这些文件已从GAC中删除,但未重新安装。为了解决这个问题,我在应用程序文件夹中安装了所有程序集。仅供参考,我正在使用VS2010

还有,另一个吹毛求疵的地方。如果用户在尝试重新安装同一版本的产品时选择“修复”,则仍然会出现“指定的服务已存在”错误。如果我有时间,我会设法解决这个问题。如果有其他人知道如何修复它,你能发布吗


说了这么多,谢谢你发这个帖子

Ryan提供的解决方案解决了我面临的部分问题。它会执行完全卸载,然后执行安装

然而,我有另一个问题,在我的例子中,一些程序是在后台运行的。在安装程序运行之前,安装程序会抱怨某些文件正在使用中。并提供标准对话框,要求关闭应用程序或重新启动以完成更新


是否有一种方法(例如自定义操作或设置)来终止后台运行的进程,以便安装程序顺利进行?

也包括了这一点,引用的问题是MS link的dup还提到删除InstallExecute行。这是必需的吗?呃-什么MS链接?我已经使用它一年多了,似乎效果很好。你在另一篇文章中链接到的那篇文章无论哪种方式都有效。你最好把它作为自己的问题来问,而不是把它作为答案发布在这里-查看右上角的常见问题解答。
cscript.exe MSI_SetActionSequence.js YOURINSTALLER.MSI InstallExecuteSequence RemoveExistingProducts 1525