2009-03-06 65 views
6

要解决问题listed here我必须在MSI中更改InstallExecuteSequence .RemoveExistingProducts记录。在MSI中更改操作顺序记录的脚本

我想这样做,作为构建过程的一部分,而不是逆戟鲸

摆弄周围
+0

也涵盖http://stackoverflow.com/questions/370940/visual-studio-2008-service-installer-project-upgrade-issue,其中引用的问题是一个 – 2009-03-06 08:56:06

回答

13

修改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); 
} 

要调用这个脚本来执行的动作变化你可以将以下内容放在批处理文件中,然后从post build事件中调用它PostBuildEvent = $(ProjectDir)PostBuild.bat

cscript.exe MSI_SetActionSequence.js YOURINSTALLER.MSI InstallExecuteSequence RemoveExistingProducts 1525 
+0

倍的MS链接还提到删除InstallExecute线。这是必需的吗? – RBear 2010-10-18 14:50:53

+0

呃 - 什么MS链接?一直以来我一直在使用它,似乎工作得很好。 – Ryan 2010-10-18 17:44:26

0

有些注释给其他人。我有“错误1001指定的服务已经存在”的问题,并尝试了上述,它似乎没有工作。以下是我遇到的情况:

*确保安装程序项目的RemovePreviousVersions属性设置为True。这看起来很明显 - 很明显,就是说,如果你知道的话。默认情况下,它被设置为False。如果是False,上述过程不会解决您的问题。 *

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

此外,另一挑选。如果用户在尝试重新安装相同版本的产品时选择“修复”,他们仍然会收到“指定的服务已存在”错误。如果我有时间,我会尽力解决这个问题。如果其他人知道如何解决它,你可以发布吗?

所有这一切,感谢张贴这!

0

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

但是,我有另一个问题,在我的情况下,一些程序在后台运行。在安装程序可以运行之前,安装程序会抱怨一些文件正在使用中。并给出标准对话框要求关闭应用程序,或重新启动以完成更新。

有没有办法,例如。自定义操作或设置,以杀死在后台运行的进程,以便安装程序顺利进行?