使用C#windows服务中的GetWindowText

时间:2014-06-25 13:49:34

标签: c# winapi windows-services

我有一个用C#(和Visual Studio 2013)编写的Windows服务应用程序。

服务每秒使用一个计时器检查当前活动窗口,如果它是某个具有焦点的应用程序,则会停止其他服务。

所以,这是我的代码的主要部分,它获取当前窗口名称:

[DllImport("user32.dll")]
static extern int GetForegroundWindow();

[DllImport("user32.dll")]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);

const int nChars = 256;
int handle = 0;
StringBuilder Buff = new StringBuilder(nChars);

string windowName = String.Empty;

handle = GetForegroundWindow();

if (GetWindowText(handle, Buff, nChars) > 0)
{
    windowName = Buff.ToString();
}

然后我检查当前窗口是否与我在app.config中保存的值匹配。

如果确实如此,我会停止服务,否则我会启动它。

ServiceController service = new ServiceController("SomeServiceName");

if (windowName.ToUpper() == ConfigurationManager.AppSettings["ApplicationTitle"].ToUpper())
{
    if (service.Status == ServiceControllerStatus.Running)
    {
        service.Stop();
    }
}
else
{
    if (service.Status == ServiceControllerStatus.Stopped)
    {
        service.Start();
    }
}

当我使用启动器应用程序从Visual Studio测试应用程序时,这一切都有效。但是一旦我安装了该服务,它就无法正常工作。

原因是因为windowName变量为空。我想这是因为该服务无法访问运行Windows的用户?

有谁知道我怎么能绕过这个?

由于

1 个答案:

答案 0 :(得分:2)

服务在用于交互式用户的会话中在不同的会话(会话0)中运行。 Windows句柄是隔离的,这意味着服务无法从交互式用户查询窗口句柄。

基本上,您无法从服务流程中查询此信息。您需要在与窗口相同的交互式桌面中运行查询窗口的过程。如果您需要将信息返回给服务,那么您将需要使用IPC机制。