Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
642 views
in Technique[技术] by (71.8m points)

c# - Getting window titles from a windows service

My company is using an unfortunate third party product that requires a user to be left logged on to an XP workstation running two instances of it's product.

I was trying to use this ...from within a windows service to get the titles of each of these open windows for monitoring purposes, but they always return null or empty. I can get the process names, however, just fine. The reason I'm interested in the titles and not the process names is that the process names are the same (two instances of the same application) but the titles are unique. I also get the same result for any open window, an open instance of notepad for example.

The service is being run as the user running the two instances of the third party application.

So I'm just curious, why would I be able to get the process names, but not the titles? Does it need to have SERVICE_INTERACTIVE_PROCESS specified to see the titles for some reason, but not the names? (of course I wouldn't use that flag: http://blogs.msdn.com/b/larryosterman/archive/2005/09/14/466175.aspx)

My code:

static void check_Clients()
{
    Process[] processList = Process.GetProcesses();

    TextWriter t = new StreamWriter(@"C:empsvctesting.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;
}

EDIT

I tried changing my code to this per some of the offered answers:

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:empsvctesting.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;
}

But I still get the same result, all process names, no window text.

EDIT 2

I also tried:

static void check_Clients()
{

    TextWriter t = new StreamWriter(@"C:empsvctesting.txt", true);

    IntPtr hWnd = WndSearcher.SearchForWindow("IEFrame", "pinvoke.net: EnumWindows");

    t.WriteLine(hWnd.ToString());

    t.Close();
    t = null;
}

Using the WndSearcher class from the pinvoke page offered below, and tried another version of the same that only compared title. I get 0 despite having the pinvoke page up in IE. I'm pretty much lost.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Services run in session 0, the non-interactive session for services. Desktop applications run in different sessions. Session 1 for the first interactive user, session 2 for the second and so on. Inside the sessions are window stations, and inside window stations are desktops.

Window stations are secured and isolated. That means that a process in one window station cannot access the objects of another. This means that your service cannot use GetWindowText or indeed any function or message to interact with a window in a different window station.

If you need to transmit this information between the interactive desktops and your service, then you need:

  1. A process running in the interactive desktop, and
  2. An IPC channel to communicate between that desktop process and the service.

In short, you are going to need to build a bit more scaffolding to get this to work.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...