我的公司正在使用一个不幸的第三方产品,该产品要求用户登录到运行其产品的两个实例的XP工作站。
我试图使用this ...从Windows服务中获取每个打开窗口的标题以进行监视,但它们始终返回null或空。但是,我可以获得进程名称。我对标题而不是进程名称感兴趣的原因是进程名称是相同的(同一应用程序的两个实例),但标题是唯一的。我也可以为任何打开的窗口获得相同的结果,例如打开记事本的实例。
该服务正在以运行第三方应用程序的两个实例的用户身份运行。
所以我只是好奇,为什么我能够获得进程名称,但不能获得标题?是否需要指定SERVICE_INTERACTIVE_PROCESS
出于某种原因查看标题,而不是名称? (当然我不会使用那面旗帜:http://blogs.msdn.com/b/larryosterman/archive/2005/09/14/466175.aspx)
我的代码:
static void check_Clients()
{
Process[] processList = Process.GetProcesses();
TextWriter t = new StreamWriter(@"C:\temp\svctesting.txt", true);
foreach (Process process in processList)
{
if (!String.IsNullOrEmpty(process.MainWindowTitle))
{
// I never get to this point, titles are always null or empty
t.WriteLine("Process Title: " + process.MainWindowTitle);
}
else
{
// this works fine
t.WriteLine("Process Name: " + process.ProcessName);
}
}
t.Close();
t = null;
}
修改
我尝试根据一些提供的答案更改我的代码:
using System.Runtime.InteropServices;
...
[DllImport("user32.dll")]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);
...
static void check_Clients()
{
Process[] processList = Process.GetProcesses();
TextWriter t = new StreamWriter(@"C:\temp\svctesting.txt", true);
foreach (Process process in processList)
{
StringBuilder Buff = new StringBuilder(256);
if (GetWindowText(process.MainWindowHandle.ToInt32(), Buff, 256) > 0)
{
t.WriteLine("Window Text: " + Buff.ToString());
}
else
{
t.WriteLine("Process Name: " + process.ProcessName);
}
}
t.Close();
t = null;
}
但我仍然得到相同的结果,所有进程名称,没有窗口文本。
编辑2
我也尝试过:
static void check_Clients()
{
TextWriter t = new StreamWriter(@"C:\temp\svctesting.txt", true);
IntPtr hWnd = WndSearcher.SearchForWindow("IEFrame", "pinvoke.net: EnumWindows");
t.WriteLine(hWnd.ToString());
t.Close();
t = null;
}
使用下面提供的pinvoke页面中的WndSearcher类,并尝试了仅比较标题的另一个版本。尽管在IE中有pinvoke页面,但我得到0。我很丢失。
答案 0 :(得分:4)
服务在会话0中运行,这是服务的非交互式会话。桌面应用程序在不同的会话中运第一个交互式用户的会话1,第二个的会话2,等等。会话内部是窗口站,内部窗口站是桌面。
窗户站是安全和隔离的。这意味着一个窗口站中的进程无法访问另一个窗口站的对象。这意味着您的服务无法使用GetWindowText
或任何功能或消息与其他窗口站中的窗口进行交互。
如果您需要在交互式桌面和服务之间传输此信息,则需要:
简而言之,您需要构建更多脚手架才能使其正常工作。
答案 1 :(得分:1)
我认为你不能用.net框架做到这一点......
但您可以使用WinAPI: http://msdn.microsoft.com/en-us/library/ms633497%28v=vs.85%29.aspx
你可以像这样从C#调用它: http://www.pinvoke.net/default.aspx/user32/enumwindows.html
重要提示:您的流程需要拥有此权限......
你也可能需要这个: http://msdn.microsoft.com/en-us/library/ms633520(v=vs.85).aspx http://www.pinvoke.net/default.aspx/user32.getwindowtext
答案 2 :(得分:0)
using System.Runtime.InteropServices;
using System.Text;
...
[DllImport("user32.dll")]
static extern int GetWindowText(int hWnd, StringBuilder text, int count);
...
Process[] processList = Process.GetProcesses();
List<string> windowTitles = new List<string>();
foreach (Process proc in processList)
{
StringBuilder Buff = new StringBuilder(256);
if (GetWindowText(proc.MainWindowHandle.ToInt32(), Buff, 256) > 0 )
{
windowTitles.Add(Buff.ToString());
}
}