问题:
我使用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"
日志文件中出现错误的第一个指示是:</ p>
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问题。
答案 0 :(得分:4)
错误代码1001 始终表示Installer类自定义操作失败。 InstallShield只是按照您的指示消费/托管它。安装程序类自定义操作非常脆弱,并且在进程外运行,因此您只需很少的日志记录。
您应该使用InstallShield在高级组件设置下公开的本机Windows Installer ServiceInstall和ServiceConfigure表,而不是使用自定义操作。创建一个组件,将您的服务EXE作为密钥文件添加到它,然后定义服务元。
首先,我建议仅创建安装,然后在安装后手动启动它。一旦工作正常,请添加ServiceControl信息,以便安装程序自动完成。在VM上冲洗并重复。
如果安装程序尝试启动服务时出现错误1920,则始终存在服务问题。对其进行分析以了解问题,然后修复代码或修复安装程序,如果它缺少依赖项。
答案 1 :(得分:3)
通过编写我自己的安装程序解决
我所做的只是将服务项目的输出作为资源嵌入到安装程序项目中,并将它们写入指定的文件夹。
然后我以编程方式运行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
答案 2 :(得分:1)
通过覆盖我的Installer类中的自定义操作的所有方法来解决。经过大量的尝试,最终它就像一个魅力。
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);
}