我有一个用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的用户?
有谁知道我怎么能绕过这个?
由于
答案 0 :(得分:2)
服务在用于交互式用户的会话中在不同的会话(会话0)中运行。 Windows句柄是隔离的,这意味着服务无法从交互式用户查询窗口句柄。
基本上,您无法从服务流程中查询此信息。您需要在与窗口相同的交互式桌面中运行查询窗口的过程。如果您需要将信息返回给服务,那么您将需要使用IPC机制。