2

我正在编写一个 .NET Windows 服务,其作用是启动一个 GUI 应用程序(其源代码不可用)。该操作是一劳永逸的,除了初始命令行参数之外没有任何通信。

该服务应该作为给定的 Windows 帐户运行。

问题:服务启动的应用程序没有显示在桌面上。它需要,因为它是一个交互式应用程序。解决办法是什么?

注意:这是系统的规格和设计。服务/应用程序通信和安全性引起的典型问题不适用于这种特定情况。

编辑:以本地系统帐户登录时,GUI 元素正确显示,但是,由于 GUI 应用程序需要访问网络驱动器(它无法理解 UNC 映射),它需要以指定的用户帐户运行,并且没有“显示交互元素”设置。

edit2:操作系统是Windows 2003 Server,没有升级计划。

4

5 回答 5

4

不幸的是,自 Vista 以来,这更成问题......关于为什么在这篇博文上发布的一些细节。

那篇文章提到了一些潜在的解决方法。 这是 MSDN 上的一个线程,详细说明了整个过程,以及您可能面临的一些潜在问题。

但是,我强烈建议您尝试查看是否可以切换到让用户模式应用程序作为启动应用程序运行(当用户登录时),并且与您的服务的任何通信都由该应用程序处理。可靠多了,尤其是在vista、终端服务等情况下。

于 2009-04-30T16:09:26.873 回答
0

您可以使用来自 Sysinternals/Microsoft 的免费自动登录实用程序http://technet.microsoft.com/en-us/sysinternals/bb963905.aspx并将您的应用程序放入启动以获取自动登录用户配置文件。之后,您可以将屏幕服务器配置为在几分钟内启动并选中“在恢复时,显示登录屏幕”复选框。

于 2009-04-30T18:56:03.680 回答
0

这是黑暗中的一次尝试,但希望能引导您找到某种解决方案。

即使安全不是问题,也可能是问题所在。该服务正在使用与当前登录用户不同的凭据集启动应用程序。这就像远程桌面到用户机器并启动他们会看到的应用程序。

作为测试,也许将服务的凭据更改为当前登录的用户只是为了看看会发生什么。

由于即使用户未登录服务也会运行,如果它启动应用程序会发生什么?您的业​​务规则或功能可能会阻止这种情况发生,但也许 Windows 正在做一些事情来阻止它工作。

于 2009-04-30T16:06:30.937 回答
0

您是否希望您的应用程序/服务在启用终端服务器角色时工作?如果是这样,您确实需要执行“轮询服务的应用程序”模型,而不是“启动应用程序的服务”模型。

这样做的原因是,您可能随时有多个用户连接到机器,并且无法知道“控制台”上的用户是谁——事实上,控制台上可能根本没有人。

于 2009-05-01T05:59:11.590 回答
0

这是我过去在任务管理服务中使用的代码,有时需要在交互式会话中运行一些东西。将 wibble.exe 替换为您的应用程序。它应该在 Server 2003(即 NT5)上运行良好。我们没有费心尝试在 NT6 上运行交互模式(太麻烦了),我们让我们的应用程序在服务会话中运行,并编写了我们自己的调试实用程序通过管道与它们对话。

STARTUPINFO  sui ;
PROCESS_INFORMATION pi;

ZeroMemory (&sui, sizeof(STARTUPINFO));
sui.cb = sizeof (STARTUPINFO);
sui.wShowWindow = pTask->GetWinStartState();
sui.dwFlags     = STARTF_USESHOWWINDOW;
ZeroMemory (&pi,sizeof(pi));

if (InteractiveMode)
{
   HANDLE  hToken = NULL;
   DWORD dwSessionId = GetCurrentUserSession();

   if (dwSessionId != (DWORD)-1)
   {
      if (WTSQueryUserToken (dwSessionId, &hToken))
      {
         sui.lpDesktop = TEXT("winsta0\\default");
         LPVOID  pEnv = NULL;
         dwCreateFlags |= CREATE_NEW_CONSOLE;
         HMODULE hModu = LoadLibrary(TEXT("Userenv.dll"));

         if (hModu)
         {
            if (CreateEnvironmentBlock (&pEnv, hToken, FALSE))
            {
               dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT;    
            }
            else
            {
               pEnv = NULL;
            }
         }

         bCreatedOk = CreateProcessAsUser (hToken,
                                           NULL,
                                           TEXT("wibble.exe"),
                                           NULL,
                                           NULL,
                                           FALSE,
                                           dwCreateFlags,
                                           pEnv,
                                           NULL,
                                           &sui,
                                           &pi);
      }
      else
      {
         // error case
      }
   }
   else
   {
      // remote session? error case.
   }
}

我在想,您的“指定用户帐户”必须是这里的控制台会话。如果您需要它在指定帐户中运行而该帐户尚未登录,那么您将处于一个全新的伤害世界,加载注册表配置单元等。

于 2016-09-27T14:02:15.273 回答