首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法获取所有窗口的顶部窗口或列表

无法获取所有窗口的顶部窗口或列表
EN

Stack Overflow用户
提问于 2015-04-29 09:52:47
回答 1查看 153关注 0票数 1

下面的代码在window Service中,它应该输出到文本文件中,首先是顶部窗口的名称,然后是所有可见窗口的列表。此过程在服务第一次启动时发生。

不幸的是,它没有吐出任何东西,OutputTopWindow没有输出任何东西,我本来以为“计算机管理”是最好的窗口,因为我必须从计算机管理开始这项服务。

ListAllVisibleWindows也不返回任何内容。在调用OutputWindowInfo时,有几个窗口是可见的,在Win7 64位上本地运行此服务。

为什么会发生这种事?

代码语言:javascript
运行
复制
public void OutputWindowInfo()
{
    OutputTopWindow();
    ListAllVisibleWindows();
}

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

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

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);

[DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);


private void OutputTopWindow()
{
    const int nChars = 256;
    StringBuilder Buff = new StringBuilder(nChars);
    IntPtr handle = GetForegroundWindow();

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

public delegate bool EnumDelegate(IntPtr hWnd, int lParam);

public static void ListAllVisibleWindows()
{
    List<string> collection = new List<string>();
    EnumDelegate filter = delegate(IntPtr hWnd, int lParam)
    {
        StringBuilder strbTitle = new StringBuilder(255);
        int nLength = GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
        string strTitle = strbTitle.ToString();

        bool winvis = IsWindowVisible(hWnd);
        bool emptyTitle = string.IsNullOrEmpty(strTitle);
        WriteMessageLog(winvis + " " + emptyTitle + " " + strTitle);
        if (winvis && emptyTitle == false)
        {
            collection.Add(strTitle);
        }
        return true;
    };

    if (EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero))
    {
        foreach (var item in collection)
        {
            WriteMessageLog(item);
        }
    }
}
public static void WriteMessageLog(String message)
{
    StreamWriter sw = null;
    try
    {
        sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\LogFile.txt", true);
        sw.WriteLine(DateTime.Now.ToString() + ": " + message + ": ");
        sw.Flush();
        sw.Close();
    }
    catch { }
}

在ListAllVisibleWindows()中,我输出了它在WriteMessageLog(winvis + " " + emptyTitle + " " + strTitle);中发现的所有内容,结果如下:

代码语言:javascript
运行
复制
False False .NET-BroadcastEventWindow.4.0.0.0.bf7771.0: 
False False HID Input Service: 
False False BMonBRW1C3E84B6FE08: 
False False internal window: 
False True : 
False False Wmi Provider Host: 
False True : 
False False pdfsvc: 
False True : 
False True : 
False False PnPWindow: 
False False VCS Event Handler:900: 
False True : 
False False VCS Event Handler:1632:

这些是我实际上打开的窗口:2 windows Explorer、回收站、Firefox、计算机管理、Visual、VS命令提示符、记事本

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-30 10:17:47

它无法工作,因为默认情况下,自Windows以来,服务在单独的会话中运行:

在Windows XP、Windows Server 2003和早期版本的Windows操作系统中,所有服务都与登录到控制台的第一个用户在同一会话中运行。此会话称为会话0。在会话0中一起运行服务和用户应用程序会带来安全风险,因为服务以较高的权限运行,因此是恶意代理的目标,这些代理正在寻找提高自己权限级别的方法。 在Windows、Windows 2008和更高版本的Windows中,操作系统通过隔离会话0中的服务和使会话0非交互式来减轻这种安全风险。只有系统进程和服务在会话0中运行。第一个用户登录到会话1,随后的用户登录到随后的会话。这意味着服务永远不会在与用户的应用程序相同的会话中运行,因此受到保护,不受源自应用程序代码[来源]的攻击。

对于遗留兼容性,可以更改设置,以便服务可以与桌面进行交互。 --但这是来自安全观点的一个坏主意--如果您可以重构它,使它根本不必是一个服务,那将是最好的选择。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29940196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档