注意:尽管出现了同一问题的另一个问题,但事实并非如此,但选择正确的标题似乎很难,因此欢迎更合适的标题更改。
我正在尝试解决从 Windows 7 Embedded(POS 就绪)上的服务应用程序启动 GUI 应用程序(Windows Forms,.NET)的问题,并且遇到了几种解决方案,但没有一个有效,除了一个例外我一路上发现:使用批处理文件作为帮助文件。
背景: 有几篇这样的帖子描述了为什么它已被删除和保护,我理解会话 0 隔离,但在任何辩论深入探讨为什么不应该这样做之前,我只是想弄清楚它,因为我不喜欢我们公司目前使用的解决方案。
我将使用“实际应用程序”一词,它代表我尝试运行的两个 GUI 应用程序。一个是 Windows Forms .NET exe,第二个是 Adobe AIR build exe 应用程序。
我已经成功设置了测试服务并使用两个帐户进行了测试:
- 在本地系统帐户下运行服务(带有和不带有“与桌面交互”选项...)
- 在管理员帐户下运行服务-> 这种方法不允许使用 CreateProcessAsUser,因为它已经在用户会话中
在本地系统帐户下,它按预期工作,我已经成功执行了 murrayu 此处显示的 CreateProcessAsUser" 命令并使用了他的帮助程序类实现,但没有成功。虽然实际应用程序在用户帐户下的 GUI 中启动,但它要么没有启动(AIR),或者它有问题和错误,主要是存在访问被拒绝异常(.NET 应用程序)。
在管理员帐户下,使用 CreateProcessAsUser 的解决方案无法正常工作,但使用方法B(帖子末尾的代码),该方法适用于一个应用程序启动另一个应用程序,但无法正常工作。正如预期的那样,没有 GUI 存在。
第三次尝试,解决方案包括服务将调用的帮助应用程序,然后启动实际应用程序。使用本地系统帐户和 CreateProcessAsUser 对此进行测试,然后在帮助应用程序中调用方法B,结果与第一次测试中的行为相同,其中服务调用了实际应用程序。
奇怪的是,使用 CreateProcessAsUser 打开 Notepad.exe、cmd.exe、calc.exe 工作正常。
由于命令行工作,我去了那个兔子洞:第四次尝试,解决方案包括一个批处理文件,其中包括一个命令:
START D:\TESTAPP\DotNetApp.lnk
请注意,它指向快捷方式,因为直接调用 exe 不起作用。
令我惊讶的是,这种方法奏效了!实际的应用程序就像通过手动执行文件定期启动一样启动。
现在最让我烦恼的是 - 有什么我还没有找到或尝试过的东西吗?我错过了什么重要的事情吗?.NET 应用程序在报告访问被拒绝异常时使用具有完全权限的管理员帐户运行,并且如果在表单文件夹中手动执行,即使在用户帐户(受限)下也可以正常工作,因此它确实没有什么特别之处,这似乎是导致从服务运行时的错误。
最重要或最想知道的问题是:命令行/批处理是如何使它工作的?是否可以在帮助应用程序中编程它的行为/解决方案,或者更好的是,直接在服务本身中编程?
此外,当想要一个服务处理 GUI 应用程序,并且不希望依赖启动/自动运行时,什么是更好的解决方案?
附录B:
public static void ElevatedExecute(string processName, string command, bool useAdminElevationRights = false)
{
Process process = new Process();
process.StartInfo = new ProcessStartInfo(processName, command);
if (useAdminElevationRights)
{
SecureString ssPwd = new SecureString();
process.StartInfo.UserName = "Administrator";
string tmpPass = ADMIN_PASSWORD;
for (int x = 0; x < tmpPass.Length; x++)
ssPwd.AppendChar(tmpPass[x]);
process.StartInfo.Password = ssPwd;
}
process.StartInfo.UseShellExecute = false;
process.Start();
}
任何见解将不胜感激。