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

问题描述 投票:2回答:3

我在另一个进程中启动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-成功!但是实际上,尚未建立文件,因为已经安装了产品。我如何确定这种情况?

c# .net windows-installer msiexec
3个回答
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/uninstall switch卸载它,然后重新安装。您也可以使用/fa开关进行修复并重新安装所有文件。

msiexec.exe /x ProductCode将卸载它。然后,您可以在那之后再次运行安装。msiexec.exe /fa ProductCode将修复所有文件。 / f开关在重新安装文件方面有许多不同的选项,因此您最好阅读我上面发布的msiexec开关文章的链接。

关于msiexec的其他注意事项:

/qb显示基本的用户界面。您可能需要/qn。当我设置实时更新软件时,遇到了很多问题,我必须确保使用[

从system32调用了msiexec。
p.StartInfo.FileName == Path.Combine(System.Environment.ExpandEnvironmentVariables("%windir%\\system32"), "MSIExec.exe"); 

3
投票

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

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

  1. 容易,但似乎不正常:在使用以下产品进行安装之前,只需卸载(可能是静默地)产品:

    msiexec / x {您的产品代码} / qn

((由于静默参数“ / qn”,即使以前未安装该产品,也不会出现错误

  1. 足够的建议:如果您要第二次安装,请使用修复模式:例如:

    msiexec / i ... REINSTALL = ALL REINSTALLMODE = vemus

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

4。

现在我们在其他一些答案中提到上述1638返回代码:如果(并且仅在以下情况下)您的构建系统(默认情况下像InstallShield一样)在每个构建中都更改了所谓的MSI PackageCode,并且您尝试将此稍有不同的构建(MSI)更新为以前安装的版本, 1638返回码。

这些东西经常被误解。强烈建议为每个构建更改PackageCode。另一方面,如果您将此类MSI发布给您的客户,则不仅会使您的事情复杂化。此更新类型的名称为“ 小更新或次要升级”(它们的区别在这里并不重要,因为它对您有相同的限制。如果您确实想使用返回码解决问题,则可以使用此代码。但是正如您所说的,1638您将无法获得完全相同的MAME MSI的第二次安装!

要继续有关更新的建议,还有更多方法:([对于初学者来说]最容易处理的方法是主要升级。这是另一个答案中所谓的“新版本”,它没有错,但并不那么精确。对于重大升级,您必须至少更改MSI PackageCode和MSI ProductCode,建议同时更改ProductVersion。(另一种方法是将MSI补丁用作增量更新,但这也不容易)。


0
投票

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

[Results:正常状态为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.

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


链接

© www.soinside.com 2019 - 2024. All rights reserved.