InstallShield 内部错误 2769 - 安装期间出现错误 1001
InstallShield Internal Error 2769 - Error 1001 during installation
抱歉,我的问题很长,但我必须尽可能多地提供细节,以帮助您更好地理解这个问题。
我正在使用由 InstallShield 2012 创建的 msi 安装程序,它 运行 在大多数计算机上都能正常运行,但在某些计算机上我遇到了一般的 1001 错误,在该错误上单击“确定”后,一切都回滚了。为了排除故障,我 运行 以下代码从安装中生成调试日志
Setup.exe /v"/l*v \"C:\log.dat\""
调试日志显示错误 2769,自定义操作 xxxx.install 没有关闭 1 个 MSIHANDLES。
在谷歌上搜索这个问题时,我看到很多人都有这个完全相同的错误,大多数建议都是为了检查你的自定义操作在做什么,因为它是产生这个错误的那个。
以下是我到目前为止为解决和隔离此问题所做的工作:
- 打开 InstallShield 项目并查看 MSI deubbger,我注意到日志中的自定义操作名称是 InstallShield 用来安装 Window 服务的自定义操作的一部分。
- 我查看了该服务的安装方式,事实证明它是一个 C# 可执行文件,InstallShield 将其作为 .NET 安装程序调用 Class 以在组件设置下安装该服务。
根据什么是 .NET 安装程序class?您可以查看下面来自 InstallShield 的说明。
由于担心我的自定义操作代码有问题,我输入了一些调试日志记录并再次 运行 整个安装,我仍然收到相同的错误,但我没有看到任何异常被记录。该服务实际上已成功创建,我什至可以 运行 只要我不在 1001 错误上单击“确定”,这将触发回滚并卸载此服务。
public ProjectInstaller()
{
try
{
using (StreamWriter w = File.AppendText("c:\log.txt"))
{
Log("start installing", w);
}
InitializeComponent();
using (StreamWriter w = File.AppendText("c:\log.txt"))
{
Log("End Install", w);
}
}
catch (Exception ex)
{
using (StreamWriter w = File.AppendText("c:\log.txt"))
{
Log(ex.Message, w);
Log(ex.StackTrace, w);
}
}
}
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
//
// serviceInstaller1
//
this.serviceInstaller1.Description = "Healthcare Platform Service";
this.serviceInstaller1.ServiceName = "psService";
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
根据我目前的故障排除,我认为错误不在自定义操作代码中。但是,这真的让我很困惑,因为我真的不知道是什么原因导致自定义操作失败;看起来有些东西没有关闭 MSI 手柄,但这对我来说真的是一个黑盒子.....
所以知道这可能是什么吗?
我如何才能进一步深入了解此客户操作到底出了什么问题 _502E509F9B6F6675DFF9C310662BC1B5.install?
以下是自定义操作序列。
*编辑:
我发现 link 谈到了我遇到的类似错误...但是我验证了我的自定义操作没有任何参数,并且根据我的详细调试日志,我看到所有路径都已正确解析。
**编辑:添加自定义动作序列屏幕截图。
我真的需要看看这是在哪里排序的。如果这被推迟并且在安装初始化之前或安装完成之后,那可能是一个问题。
嗯,
这很有趣...我找到了一个 Microsoft link 谈论事件源
默认情况下,如果我卸载软件,事件源也会被删除。出于某种原因,我看到的情况并非如此,我认为它没有被删除,因为 EventMessageFile 指向的文件是 used/uninstall?
所以阅读上面的文章我去删除了在下面手动找到的注册表
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MyProgramName
删除上述注册表后,安装不再出现 1001 错误。看起来 InstallShield 试图安装 window 服务,但在查看此注册表时它认为该服务已经存在(即使它不存在)。
该错误是由于安装程序的基础结构 class 无法正常工作而导致的一般错误。这主要是为 Visual Studio 安装项目开发的黑盒。它使用 C++ Dll 调用 ManagedInstall,然后加载框架版本、定位程序集、使用反射实例化 class,然后调用 Install 方法。 InstallUtilLib 是特定于体系结构的,它与您的托管代码和框架版本之间的不匹配将导致错误。如果这种情况只发生在一台机器上,则可能是这种不匹配,或者该机器可能在某种程度上与该服务有关。
这些信息可能会有所帮助。但是,如果您有实际的 InstallShield 2012,那么您根本不需要安装程序 classes。它们是为 Visual Studio 设置而创建的,实际上所有其他 MSI 构建工具都不需要它们,因为它们内置了对 MSI ServiceInstall 和 ServiceControl 表的支持。
引用 Jerry MaGuire 的话...停止,你让我在 1001。必须不惜一切代价避免 InstallUtil 管理的自定义操作。第一个操作是通过使用本机 windows 安装程序功能来消除对自定义操作的需要。如果仍然需要自定义操作,第二个操作是使用 Windows Installer XML (Wix) Deployment Tools Foundation (DTF) 进行重构。是将托管代码与 MSI 集成的更好的模式。它与 InstallShield 配合使用效果很好。
IMO,InstallShield 应该从来没有让连接 InstallUtil 自定义操作变得如此容易。毫无疑问,他们这样做是为了满足客户的要求并简化向 InstallShield 的迁移,但以牺牲质量标准为代价。
抱歉,我的问题很长,但我必须尽可能多地提供细节,以帮助您更好地理解这个问题。
我正在使用由 InstallShield 2012 创建的 msi 安装程序,它 运行 在大多数计算机上都能正常运行,但在某些计算机上我遇到了一般的 1001 错误,在该错误上单击“确定”后,一切都回滚了。为了排除故障,我 运行 以下代码从安装中生成调试日志
Setup.exe /v"/l*v \"C:\log.dat\""
调试日志显示错误 2769,自定义操作 xxxx.install 没有关闭 1 个 MSIHANDLES。
在谷歌上搜索这个问题时,我看到很多人都有这个完全相同的错误,大多数建议都是为了检查你的自定义操作在做什么,因为它是产生这个错误的那个。
以下是我到目前为止为解决和隔离此问题所做的工作:
- 打开 InstallShield 项目并查看 MSI deubbger,我注意到日志中的自定义操作名称是 InstallShield 用来安装 Window 服务的自定义操作的一部分。
- 我查看了该服务的安装方式,事实证明它是一个 C# 可执行文件,InstallShield 将其作为 .NET 安装程序调用 Class 以在组件设置下安装该服务。
根据什么是 .NET 安装程序class?您可以查看下面来自 InstallShield 的说明。
由于担心我的自定义操作代码有问题,我输入了一些调试日志记录并再次 运行 整个安装,我仍然收到相同的错误,但我没有看到任何异常被记录。该服务实际上已成功创建,我什至可以 运行 只要我不在 1001 错误上单击“确定”,这将触发回滚并卸载此服务。
public ProjectInstaller()
{
try
{
using (StreamWriter w = File.AppendText("c:\log.txt"))
{
Log("start installing", w);
}
InitializeComponent();
using (StreamWriter w = File.AppendText("c:\log.txt"))
{
Log("End Install", w);
}
}
catch (Exception ex)
{
using (StreamWriter w = File.AppendText("c:\log.txt"))
{
Log(ex.Message, w);
Log(ex.StackTrace, w);
}
}
}
private void InitializeComponent()
{
this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller1 = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller1
//
this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller1.Password = null;
this.serviceProcessInstaller1.Username = null;
//
// serviceInstaller1
//
this.serviceInstaller1.Description = "Healthcare Platform Service";
this.serviceInstaller1.ServiceName = "psService";
this.serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1,
this.serviceInstaller1});
}
根据我目前的故障排除,我认为错误不在自定义操作代码中。但是,这真的让我很困惑,因为我真的不知道是什么原因导致自定义操作失败;看起来有些东西没有关闭 MSI 手柄,但这对我来说真的是一个黑盒子.....
所以知道这可能是什么吗? 我如何才能进一步深入了解此客户操作到底出了什么问题 _502E509F9B6F6675DFF9C310662BC1B5.install?
以下是自定义操作序列。
*编辑: 我发现 link 谈到了我遇到的类似错误...但是我验证了我的自定义操作没有任何参数,并且根据我的详细调试日志,我看到所有路径都已正确解析。
**编辑:添加自定义动作序列屏幕截图。
我真的需要看看这是在哪里排序的。如果这被推迟并且在安装初始化之前或安装完成之后,那可能是一个问题。
嗯,
这很有趣...我找到了一个 Microsoft link 谈论事件源
默认情况下,如果我卸载软件,事件源也会被删除。出于某种原因,我看到的情况并非如此,我认为它没有被删除,因为 EventMessageFile 指向的文件是 used/uninstall?
所以阅读上面的文章我去删除了在下面手动找到的注册表 Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MyProgramName
删除上述注册表后,安装不再出现 1001 错误。看起来 InstallShield 试图安装 window 服务,但在查看此注册表时它认为该服务已经存在(即使它不存在)。
该错误是由于安装程序的基础结构 class 无法正常工作而导致的一般错误。这主要是为 Visual Studio 安装项目开发的黑盒。它使用 C++ Dll 调用 ManagedInstall,然后加载框架版本、定位程序集、使用反射实例化 class,然后调用 Install 方法。 InstallUtilLib 是特定于体系结构的,它与您的托管代码和框架版本之间的不匹配将导致错误。如果这种情况只发生在一台机器上,则可能是这种不匹配,或者该机器可能在某种程度上与该服务有关。
这些信息可能会有所帮助。但是,如果您有实际的 InstallShield 2012,那么您根本不需要安装程序 classes。它们是为 Visual Studio 设置而创建的,实际上所有其他 MSI 构建工具都不需要它们,因为它们内置了对 MSI ServiceInstall 和 ServiceControl 表的支持。
引用 Jerry MaGuire 的话...停止,你让我在 1001。必须不惜一切代价避免 InstallUtil 管理的自定义操作。第一个操作是通过使用本机 windows 安装程序功能来消除对自定义操作的需要。如果仍然需要自定义操作,第二个操作是使用 Windows Installer XML (Wix) Deployment Tools Foundation (DTF) 进行重构。是将托管代码与 MSI 集成的更好的模式。它与 InstallShield 配合使用效果很好。
IMO,InstallShield 应该从来没有让连接 InstallUtil 自定义操作变得如此容易。毫无疑问,他们这样做是为了满足客户的要求并简化向 InstallShield 的迁移,但以牺牲质量标准为代价。