安装 C# 后,无法使用 WPF App 使用 SC.exe 创建 Windows 服务
Posted
技术标签:
【中文标题】安装 C# 后,无法使用 WPF App 使用 SC.exe 创建 Windows 服务【英文标题】:Cannot create a windows service with SC.exe using WPF App after its installation C# 【发布时间】: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/”调试应用程序/时执行时,就会安装该服务。我可以在不使用应用程序的情况下安装服务(使用命令提示符),尽管这不是我想要的,因为我想在不同的机器上/为不同的人安装应用程序。 【参考方案1】:当我进一步分析所有可能的因素时,我终于注意到在这种情况下导致问题的原因。
通常,Visual Studio 生成的路径没有任何空格,因此它们可以写成不带双引号的命令参数。在我的情况下,包含项目文件的路径也没有任何空格,这导致没有双引号的命令可以正常执行。然而,安装路径确实包含空格,因为它被设计为更加用户友好,这导致这段代码无法按预期执行:
// the path parameter in the command will end when there will be a space somewhere in the path
Arguments = $"create ServiceName binPath= path start= auto"
path
变量只包含完整路径,没有用双引号括起来。
为防止出现此问题,必须使用双引号,并且包含 \
符号会通知编译器这些双引号是字符串的一部分:
// the path parameter is wrapped in double quotes and will be fully read
Arguments = $"create ServiceName binPath= \" path \" start= auto"
当路径完全写在代码中时,很容易注意到缺少的双引号。但是,当使用字符串插值时,它可能会导致问题,就像我的情况一样。
【讨论】:
以上是关于安装 C# 后,无法使用 WPF App 使用 SC.exe 创建 Windows 服务的主要内容,如果未能解决你的问题,请参考以下文章
使用 WPF 成功连接后无法从 Access 数据库获取数据
C# wpf datagrid 动态加载数据后改变单元格颜色bug
c# - 在运行时更改 App.Config 后,实体框架 ConnectionString 不会更新