【发布时间】:2021-08-01 19:16:40
【问题描述】:
我创建了一个 WPF 桌面应用程序和一个 Worker 服务(所有 .NET 6.0 预览版 3),使用 Microsoft Visual Studio 安装程序项目扩展将它们打包到一个 .MSI 安装文件中,该扩展在计算机上安装 WPF 应用程序。
虽然应用程序安装并正常运行,但我必须以某种方式实现服务安装,该服务安装应在安装 WPF 应用程序后运行。我为此创建了一个函数,它以管理员身份运行 sc.exe,并使用Process.Start() 安装服务,如下所示:
private static void InstallService()
{
const string ServiceName = "SomeService";
var path = Path.GetFullPath(@".\SomeService.exe");
var psi = new ProcessStartInfo
{
FileName = @"C:\Windows\system32\sc.exe",
Arguments = $"create { ServiceName } binPath= { path } start= auto",
Verb = "runas",
UseShellExecute = true,
};
try
{
Process.Start(psi);
}
catch (Exception ex)
{
MessageBox.Show($"Installation has failed: { ex.Message + ex.StackTrace }");
}
}
此函数的问题在于,当应用程序在 Visual Studio 中运行以及从 Visual Studio 创建的 'bin\Release' 文件夹运行时,它可以正常执行。然后服务安装并可以启动。但是,当使用 .MSI 包安装程序时,服务不安装并且没有显示MessageBox,这表明没有抛出异常。
我尝试过的:
-
执行该函数时,会显示一个 UAC 提示符,然后 过程开始。我尝试将整个应用程序运行为 管理员,但这并没有解决问题。
-
我还尝试将“bin\Release”目录中的所有文件复制到安装应用程序的目录中,并将每个文件替换为“bin\Release”中的文件,这样两个目录应该相同,但这也没有解决问题。
安装函数执行后,服务应该启动另一个函数来启动它:
private static void RunService()
{
const string ServiceName = "SomeService";
var psi = new ProcessStartInfo
{
FileName = @"C:\Windows\system32\sc.exe",
Arguments = $"start { ServiceName }",
Verb = "runas",
UseShellExecute = true,
};
try
{
Process.Start(psi);
}
catch (Exception ex)
{
MessageBox.Show($"Running was not approved or failed: { ex.Message }");
}
}
此功能在这两种情况下都可以正常工作,但显然只有在之前安装了该服务时才能使用,而这在 .MSI 安装的应用程序中是无法完成的。至于使用Process.Start()而不是ServiceController类,应用程序默认不应该以管理员身份运行,用ServiceController是不行的,所以我用Process.Start()和Verb = "runas" 以管理员身份运行进程,仅在需要时显示 UAC 提示(仅在服务尚未运行时启动服务)。
有什么办法可以解决这个问题并在 .MSI 安装的 WPF 应用程序中安装 Worker Service?
【问题讨论】:
-
MSI安装后第一次启动应用程序时不能安装服务吗?
-
@mm8 我无法使用我正在寻找的 WPF 应用程序安装它 - 它不会引发任何异常,但在安装函数执行后没有任何反应。但是,当它在从“bin/release/”调试应用程序/时执行时,就会安装该服务。我可以在不使用应用程序的情况下安装服务(使用命令提示符),尽管这不是我想要的,因为我想在不同的机器上/为不同的人安装应用程序。
标签: c# wpf .net-core windows-services .net-core-service-worker