C# WPF应用程序在由使用Topshelf创建的Windows服务启动时不显示窗体。

huangapple go评论83阅读模式
英文:

C# WPF App doesnt show form when launched by windows service created with topshelf

问题

I have:

  1. 一个由Visual Studio创建的简单WPF应用程序,带有一个窗口
  2. 使用Topshelf创建的Windows服务,用于启动该应用程序

如果我手动启动应用程序,它会出现在任务管理器中,并显示窗体,就像应该的那样。

但是当Windows服务启动它时,应用程序会出现在任务管理器中,但窗体不会显示。可能的原因是什么?

在Windows服务中启动应用程序的代码如下:

System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = _app.MainAppDirectory;
startInfo.Arguments = "";
process.StartInfo = startInfo;
process.Start();
英文:

I have:

  1. Simple WPF app, with 1 window created by Visual studio
  2. Windows service (created with topshelf) that starts that app

If I start app manually, it appears in task manager and shows form as it should.

But when it is started by windows service, app appears in task manager, but form isnt shown. What should it the reason?

App launch code in win service

                    System.Diagnostics.Process process = new System.Diagnostics.Process();
                System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                startInfo.FileName = _app.MainAppDirectory;
                startInfo.Arguments = "";
                process.StartInfo = startInfo;
                process.Start();

答案1

得分: 3

"Windows services" 不在 "当前用户" 会话下运行。当您登录到 Windows 时,会获得一个活动会话,包括(桌面、环境变量等),每当您运行应用程序(如简单的 "WindowsForm" 或 "WPF")时,它都会在您的活动会话下运行。您可以打开 "任务管理器" 并导航到 "详细信息" 选项卡,以查看每个进程的运行用户信息(当您的 Windows 服务运行 "WPF" 应用程序时,请检查此信息)。

您可以在 "开始菜单" 中键入 "服务" 并打开 "服务" 窗口,找到已安装的服务。您可以检查一个名为 "登录为" 的列。这是运行您的 "Windows 服务" 的用户帐户(可能是 "本地系统" 或 "本地服务")。

这是一个有趣的事实,您可以编写一个应用程序,即使没有已登录的用户也可以运行。

我在5年前有相同的任务,尝试窃取用户会话。使用 "模拟",您可以窃取用户令牌并以特定用户身份运行您的应用程序。但仍然无法在桌面上看到您的应用程序。

寻找不同的项目类型以满足您的需求。也许将您的应用程序标记为启动应用程序,并将其 "表单" 隐藏起来可以满足要求。

英文:

You can't do it. Windows services are not running under current user session. When you login to your Windows, you will get an active session including (Desktop, Environment variables, ..) and whenever you run an application (like a Simple WindowsForm or WPF, ...) it will runs under your active session. You can open up the Task manager and navigate to Detail tab to see information about the user who ran each Process (Check this for the WPF app when it's ran by your windows service).

You can type Services on the Start menu and open up Services window and find your installed service. You can check a column named Log on As there. It's the user account who runs your Windows service (it might be Local System or Local Service).

It's an interesting fact, you can write an application who runs even with no logged-in user.

I had the same task, 5 years ago, I tried to steal users session. Using Impersonation you are able to steal user token and run your application as an specific user. But still you are not able to see your Application on the desktop.

Look for a different project type to fill your requirements. maybe mark your application as an startup app and hide it's Forms from the user.

答案2

得分: 0

Windows服务运行在会话0中,这将服务与用户应用程序隔离开来。以下是关于为什么要将用户应用程序与会话0分开的文章摘录的详细信息。

> 在Windows XP、Windows Server 2003以及Windows操作系统的早期版本中,所有服务都在与首次登录到控制台的用户相同的会话中运行。这个会话被称为会话0。在会话0中同时运行服务和用户应用程序会带来安全风险,因为服务以提升的权限运行,因此成为恶意代理寻求提升其自身权限级别手段的目标。

以前有一种方法可以实现您正在尝试的功能,通过创建一个交互式服务,但该文档中的第一个重要部分指出。

> 自Windows Vista以来,服务不能直接与用户交互。因此,不应该在新代码中使用标题为"使用交互式服务"的部分中提到的技术。

据我所知,复选框仍然存在以使服务具有交互性,但仅供与可能设置或读取它的安装程序兼容的情况下使用。

C# WPF应用程序在由使用Topshelf创建的Windows服务启动时不显示窗体。

该图像来自我的Windows 10计算机,因此存在打开它的选项,但正如我所说,我印象中它除了防止尝试设置它的应用程序失败外,什么都不做。

通常,我看到应用程序绕过这个限制的方式是编写一个相应的桌面应用程序,安装并在启动时启动,然后使用某种形式的进程间通信,比如套接字来与该应用程序通信。

英文:

Windows services run in session 0, which isolates services from user applications. This quote from the article gives more details on why they separated user applications from session 0.

> In Windows XP, Windows Server 2003, and earlier versions of the Windows operating system, all services run in the same session as the first user who logs on to the console. This session is called Session 0. Running services and user applications together in Session 0 poses a security risk because services run at elevated privilege and therefore are targets for malicious agents who are looking for a means to elevate their own privilege level.

There used to be a means to do what you are trying to do by making a interactive service but the first important section in that document states.

> Services cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code.

As far as I know, the checkbox is still there to make a service interactive but is only there for compatibility with installers that might have set it or read it.

C# WPF应用程序在由使用Topshelf创建的Windows服务启动时不显示窗体。

That image is from my Windows 10 machine so the option to turn it on is there but like I said, I am under the impression it does nothing other than prevent applications which attempted to set it from breaking.

Typically the way I have seen applications work around this limitation is by writing a corresponding desktop app that is installed to launch at start and then uses some form of inter-process communication, like a socket to communicate with the app.

huangapple
  • 本文由 发表于 2023年4月17日 16:54:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76033338.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定