代码之家  ›  专栏  ›  技术社区  ›  Paul Nathan

从windows服务加载gui应用

  •  2
  • Paul Nathan  · 技术社区  · 16 年前

    我正在编写一个.net windows服务,其角色是启动一个gui应用程序(其源不可用)。 该操作是一个火和忘记,除了最初的命令行参数没有通信。

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

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

    注:这是系统的规格和设计。服务/应用程序通信和安全方面的典型问题 不适用 在这种情况下。

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

    edit2:操作系统是windows 2003服务器,没有升级的计划。

    5 回复  |  直到 9 年前
        1
  •  4
  •   Reed Copsey    16 年前

    不幸的是,自从vista…关于为什么张贴在 this blog post.

    那篇文章提到了一些可能的解决办法。 Here is a thread on MSDN 这详细说明了整个过程,以及你可能面临的一些潜在的打嗝。

    不过,我强烈建议尝试看看是否可以切换到用户模式应用程序作为启动应用程序运行(当用户登录时),并且您的服务的任何通信都由该应用程序处理。它更可靠,特别是在vista、终端服务和其他情况下。

        2
  •  0
  •   Joshua Belden    16 年前

    这是在黑暗中捅了一刀,但希望能引导你找到某种解决方法。

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

    作为一个测试,也许可以将服务的凭据更改为当前登录的用户,以查看发生了什么。

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

        3
  •  0
  •   Dmitri Kouminov    16 年前

    你可以免费使用 Autologon 效用 http://technet.microsoft.com/en-us/sysinternals/bb963905.aspx 从Sysinternals/Microsoft启动应用程序以自动登录用户配置文件。之后,您可以配置屏幕服务器启动几分钟,并检查“在简历,显示登录屏幕”复选框。

        4
  •  0
  •   Larry Osterman    16 年前

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

    原因是,您可能在任何时候都有多个用户连接到机器,而且无法知道哪个用户在“控制台”—事实上,控制台上可能根本没有人。

        5
  •  0
  •   Bob Moore    9 年前

    这是我过去在任务管理服务中使用的代码,有时需要在交互会话中运行一些东西。用应用程序替换wibble.exe。它应该可以在服务器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.
       }
    }
    

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

    推荐文章