【问题标题】:Windows installer: Error 1001, CustomAction _xxxxx.install returned actual error code 1603Windows 安装程序:错误 1001,CustomAction _xxxxx.install 返回实际错误代码 1603
【发布时间】:2013-05-22 13:26:31
【问题描述】:

问题:

我已经使用 Visual Studio 2012 和 InstallShield 为 Windows 服务创建了安装程序。

服务运行良好。
安装程序在我的开发机器(windows 8 64 位)和我的 XP 虚拟机(32 位)上运行良好。

但在 Windows Server 2008 R2 上,相同的安装程序会出现“错误 10001”。
没有更多信息。

事件日志中包含以下信息:

Product: DbBackupServiceSetup -- Error 1001. 
(NULL)
(NULL)
(NULL)
(NULL)
(NULL)

the message resource is present but the message is not found in the string/message table

如果我手动安装:

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe "D:\Program Files\Test\DbBackupService.exe"

那么即使在 Windows Server 2008 R2 上也能正常工作...

我创建了一个带有 32 位可执行文件的安装程序和一个带有 64 位可执行文件的安装程序,但我都收到了这个错误...

我已尝试在启用日志记录的情况下执行 msi

msiexec /i "D:\Install\DISK1\DbBackupServiceSetup.msi" /Lv "D:\example.log"

日志文件中的第一个错误指示在这里:

Created Custom Action Server with PID 3932 (0xF5C).
MSI (s) (C0:74) [14:26:28:065]: Running as a service.
MSI (s) (C0:74) [14:26:28:080]: Hello, I'm your 32bit Elevated custom action server.
MSI (s) (C0!14) [14:26:33:681]: 
MSI (s) (C0:E8) [14:26:33:681]: Leaked MSIHANDLE (16) of type 790531 for thread 3348
MSI (s) (C0:E8) [14:26:33:681]: Note: 1: 2769 2: _B384C869AD7BC0C39F5780609620645B.install 3: 1 
Info 2769. Custom Action _B384C869AD7BC0C39F5780609620645B.install did not close 1 MSIHANDLEs.
CustomAction _B384C869AD7BC0C39F5780609620645B.install returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 14:26:33: InstallFinalize. Return value 3.
MSI (s) (C0:F0) [14:26:33:697]: User policy value 'DisableRollback' is 0
MSI (s) (C0:F0) [14:26:33:697]: Machine policy value 'DisableRollback' is 0

我不明白。
相同的安装程序在其他机器上运行良好。
所有自定义操作都包含在 try-catch 中,系统帐户对文件系统具有完全访问权限,并且它不是网络共享。
并且使用 installutil 安装服务是有效的,所以它一定是安装程序本身的错误。

对我来说,它看起来像是在召唤

C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe "D:\Program Files\test\DbBackupService.exe"

而不是

C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe "D:\Program Files\test\DbBackupService.exe"

因此得到坏图像异常。

但是,如果是这种情况,我不明白为什么我同时使用 32 位和 64 位可执行文件都会出现此错误...

按理说问题出在 InstallShield 本身...
哦,我是用远程桌面(mstsc.exe)连接服务器,以防万一,而且我无法直接访问服务器,所以如果是mstsc问题,我无法尝试。

【问题讨论】:

    标签: .net windows-services windows-installer installshield-2012


    【解决方案1】:

    错误代码 1001 总是表示安装程序类自定义操作失败。 InstallShield 只是按照您的指示使用/托管它。众所周知,安装程序类自定义操作很脆弱并且会耗尽进程,因此您获得的日志记录非常少。

    您应该使用 InstallShield 在高级组件设置下公开的本机 Windows Installer ServiceInstall 和 ServiceConfigure 表,而不是使用自定义操作。创建一个组件,将您的服务 EXE 作为密钥文件添加到其中,然后定义服务元。

    首先我建议只创建安装,然后在安装后手动启动它。一旦工作正常,请添加 ServiceControl 信息,以便安装程序自动执行。冲洗并在 VM 上重复。

    如果您在安装程序尝试启动服务时收到错误 1920,这始终是服务问题。对其进行分析以了解问题,然后修复代码或修复缺少依赖项的安装程序。

    【讨论】:

    • 您假设主机包装器 InstallUtilLib.dll (Microsoft) 是防弹的。可悲的是,事实并非如此。它有许多已知的问题,即使安装程序应该完全静默,它也总是会抛出模式 1001 错误消息框。如果一个 CA 被编译为 CLR 2.0 而另一个 CA 被编译为 4.0,它也会抛出 badimageformat 异常。这是因为它在第一次调用时破坏了 msiesexec 沙箱进程。这就是为什么我强烈推荐将 DTF 用于托管代码自定义操作而不是在不需要的地方编写自定义操作的原因。
    • 我收到错误 1001 并且自定义操作中没有任何内容:/
    • 是的。我打赌你 100 美元。
    • 我遇到了这个问题,只能通过在我的项目中删除一个事件日志安装程序来解决它,我认为它会导致自定义操作。
    • “安装程序”(可悲的是超载)在这种情况下自定义操作。它们也是用劣质解决方案重新发明轮子的一个例子。事件源只需要一些注册表项就可以存在。自定义操作不合适。
    【解决方案2】:

    通过编写我自己的安装程序解决了。
    我所做的只是将服务项目的输出作为资源嵌入到安装程序项目中,并将它们写入指定的文件夹。
    然后我以编程方式运行 installutil,它可以很好地安装服务,然后它就可以工作了。
    与真正的安装程序相比,唯一的缺点是,这种方式没有卸载程序,但我不再关心了。如果推出自己的安装程序比使用 InstallShield 快几天,那么 InstallShield 就有问题了。

    重新发明轮子可能会导致错误,但至少它们是我可以制造和解决的。
    这是解决方案,以防对其他人有用。

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    
    
    namespace SimpleInstaller
    {
    
    
        static class Program
        {
    
    
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static int Main(string[] args)
            {
                if (false)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                }
    
    
                //for (int i = 0; i < args.Length; ++i)
                //{
                //    Console.WriteLine("args[{0}] = {1}", i, args[i]);
                //}
    
    
                string strPath = @"C:\pro\DbBackupService\DbBackupService\bin\Debug\DbBackupService.exe";
    
    
                string[] callArgs = null;
                string[] argInstall = new string[] { strPath };
                string[] argUnInstall = new string[] { "/u", strPath };
    
                bool bIsInstallation = true;
                bIsInstallation = false;
                callArgs = bIsInstallation ? argInstall : argUnInstall;
    
    
                System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CurrentUICulture.GetConsoleFallbackUICulture();
    
                //if(Console.OutputEncoding.CodePage != 65001 && Console.OutputEncoding.CodePage !=
                if (Console.OutputEncoding.CodePage != 65001
                    && Console.OutputEncoding.CodePage != System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.OEMCodePage
                    && Console.OutputEncoding.CodePage != System.Threading.Thread.CurrentThread.CurrentUICulture.TextInfo.ANSICodePage)
                {
                    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
                }
    
    
    
                try
                {
                    System.Configuration.Install.ManagedInstallerClass.InstallHelper(callArgs);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    //return -1;
                }
    
                Console.WriteLine(Environment.NewLine);
                Console.WriteLine(" --- Press any key to continue --- ");
                Console.ReadKey();
                return 0;
            } // End Sub Main
    
    
        } // End Class Program
    
    
    } // End Namespace SimpleInstaller
    

    【讨论】:

    • 对于以后阅读本文的人来说,这不是最佳实践,不应被模仿。这是一种技巧,而不是解决方案。
    • @Christopher Painter:是的,这是一个 hack。但它存在是因为我整整两天都找不到解决方案。它的作用与 installutil.exe 相同。它有效!唯一不好的做法是在解决问题的最初几个小时后不要放弃 InstallShield,而这些问题只能通过 google 来解决。
    • @Quandary +1。在这个安装程序技术过于复杂的时代,总有一天会过去,尤其是在 Visual Studio 安装程序项目模板的形式中;丑陋、令人困惑、容易出错的基于 XML 的“安装程序技术”,例如 Wix;可以看到您的解决方案的简单性的价值。像这样的原因我更喜欢 OSX 做事的方式。
    • 花时间学习它,你可能会发现它真的没那么难。
    • @Christopher Painter:是的,没错,但前提是您有时间这样做。顺便说一句,问题可能是由于服务没有正确停止造成的(由于 Windows 在调用“停止”之前将状态设置为停止,然后停止陷入无限循环)。
    【解决方案3】:

    通过覆盖我的安装程序类中的所有自定义操作方法来解决。试了很多次,终于成功了。

      public override void Install(IDictionary savedState)
        {
             base.Install(savedState);
    
        }
     public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
        }
    
        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
        }
    
        public override void Uninstall(IDictionary savedState)
        {
            base.Uninstall(savedState);
        }
    

    【讨论】:

      猜你喜欢
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      相关资源
      最近更新 更多