已安装msi文件时确定msiexec退出代码

时间:2014-09-09 07:54:42

标签: c# .net msiexec

我在另一个进程中启动msiexec并等待退出:

var p = new Process
{
    StartInfo =
    {
        FileName = "msiexec",
        Arguments = string.Format("/i \"{0}\" /qb", @"c:\install\setup.msi"),
        Verb = "runas"
    }
};
p.Start();
p.WaitForExit();
int exitCode = p.ExitCode;

如果先前未安装setup.msi,则表示安装为静音模式并返回0.正常。

但是如果setup.msi已经安装(第二次启动此代码),则安装无法启动并返回代码0 - 成功结果!但实际上,文件尚未建立,因为产品已经安装。我怎么能确定这种情况呢?

3 个答案:

答案 0 :(得分:3)

您收到退出代码0,因为该产品已安装且您没有尝试安装新版本。换句话说,您的MSI没有新的产品代码和版本号,因此MSIExec安装程序将其视为重新配置,然后退出。我通过打开/ log switch并在安装我的一个MSI文件两次后读取输出来测试了这一点。

  

MSI(c)(98:EC)[15:19:27:912]:产品:产品名称 - 配置   顺利完成。 MSI(c)(98:EC)[15:19:27:912]:Windows   安装人员重新配置了产品。产品名称:产品名称。   产品版本:4.8.22。产品语言:1033。制造商:制造商。重新配置成功或错误状态:0。

如果您尝试安装新版本的产品且未将MSI配置为删除以前的版本,则会收到错误代码1638。请在此处查看错误代码列表:MSDN

如果您要检查产品是否已安装现有的MSI信息(而非升级),则需要在以下位置检查注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\YourProductCode

如果事实证明它已安装(根据系统/注册表 - 可能文件已删除但仍被认为已安装),您可以尝试使用/x或{{1}卸载它然后重新安装。您还可以使用/uninstall switch开关进行修复并重新安装所有文件。

/fa会将其卸载。然后,您可以在此之后再次运行安装。 msiexec.exe /x ProductCode将修复所有文件。 / f开关有很多不同的选项可用于重新安装文件,因此您可以阅读上面发布的msiexec交换机文章的链接。

关于msiexec的其他一些注释:

msiexec.exe /fa ProductCode显示基本用户界面。你可能想要/qb。 当我设置我的实时更新软件时遇到了一堆问题,我必须确保通过使用

从system32调用msiexec
/qn

答案 1 :(得分:3)

首先,关于1638返回码的其他评论有点误导。 当您第二次安装确切的MSI文件时,您会得到一个类似于已经(并且正确)观察到的返回码0。这是“正确的”行为,换句话说:这就是MSI的设计方式。 此外,在这种情况下,您的现有设置没有任何更改。如果在第二次安装之前删除所有文件,尽管MSI返回零,但最终没有任何结果。 因此,返回代码本身并不能帮助您实现这种情况。

简而言之,您有以下可能性:

  1. 简单但看似不正常:在安装之前,只需卸载(可能是默默地)产品:

    msiexec / x {yourproductcode} / qn

  2. (即使由于静音参数“/ qn”之前未安装产品,您也不会收到错误

    1. 建议您是否足够:如果您想再次安装,只需使用修复模式: 示例:

      msiexec / i ...重新安装=所有重新安装模式= vemus

    2. 最佳:使用启动器(boot-strapper或其他名称是相同的)来测试产品是否已经安装等等。使用此功能,您可以自动执行以前的选项(预卸载或添加修复)参数)。这也可以通过脚本完成,但在每种情况下这都是编程,因此不是最简单的方法。

    3. 4

      现在我们来看一下其他答案中提到的1638返回代码: IF(并且仅当)您的构建系统(例如InstallShield默认情况下)在每个构建中更改所谓的MSI PackageCode )并且您尝试将此略微不同的构建(MSI)更新为先前安装的版本,你得到1638返回代码。

      这些事情经常被误解。 更改每个构建的 PackageCode 是非常推荐的做法。 另一方面,如果你要向客户发布这样的MSI,它不仅会让你感到复杂。此更新类型的名称为“小更新或次要升级”(它们之间的区别并不重要,因为它对您有相同的限制。 如果您真的想用返回码解决问题,可以使用它。但正如所说,1638你将无法获得完全相同的MSI的第二次安装!

      要继续关于更新的建议,有更多方法:最简单的处理方式(对于初学者)是主要升级。这就是所谓的“新版本”,在另一个答案中没有错,但不是那么精确。 对于主要升级,您必须至少更改MSI PackageCode 和MSI ProductCode ,建议也更改 ProductVersion 。 (另一种方法是使用MSI补丁作为增量更新,但这也不容易。)

答案 2 :(得分:1)

MSI COM API :如果可以使用MSI COM API,则可以使用ProductState property。换句话说,如果您具有实际的产品代码(How can I find the product GUID of an installed MSI setup?),则可以用两行代码检查是否已安装产品:

Dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
MsgBox installer.ProductState("{00000000-0000-0000-0000-000000000001}") ' <= PRODUCT CODE

结果 :正常状态为已安装的 5 -1 对于未安装:

INSTALLSTATE_UNKNOWN   -1  The product is neither advertised or installed.
INSTALLSTATE_ADVERTISED 1  The product is advertised but not installed.
INSTALLSTATE_ABSENT     2  The product is installed for a different user.
INSTALLSTATE_DEFAULT    5  The product is installed for the current user.

交互式VBScript :这是VBScript的较大版本,在InputBox中具有产品GUID的交互式输入-可以以临时方式与任何产品GUID一起使用:CheckProductState-Interactive.vbs


链接