【问题标题】:Why does GetWindowThreadProcessId return 0 when called from a service?为什么 GetWindowThreadProcessId 从服务调用时返回 0?
【发布时间】:2010-03-17 09:46:00
【问题描述】:

当在控制台应用程序中使用以下类并至少运行一个记事本实例时,GetWindowThreadProcessId 正确返回非零线程 ID。但是,如果 Windows 服务中包含相同的代码,GetWindowThreadProcessId 总是返回 0 并且不会引发异常。将启动服务的用户更改为与运行控制台应用程序的用户相同并不会改变结果。是什么导致GetWindowThreadProcessId 返回0,即使它提供了有效的hwnd?为什么它在控制台应用程序和服务中的功能不同?注意:我正在运行 Windows 7 32 位并针对 .NET 3.5。

public class TestClass
{
    [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

    public void AttachToNotepad()
    {
        var processesToAttachTo = Process.GetProcessesByName("Notepad")

        foreach (var process in processesToAttachTo)
        {
            var threadID = GetWindowThreadProcessId(process.MainWindowHandle, 
                IntPtr.Zero);

            ....
        }
    }
}

控制台代码:

class Program
{
    static void Main(string[] args)
    {
        var testClass = new TestClass();

        testClass.AttachToNotepad();
    }
}

服务代码:

public class TestService : ServiceBase
{
    private TestClass testClass = new TestClass();

    static void Main()
    {
        ServiceBase.Run(new TestService());
    }

    protected override void OnStart(string[] args)
    {
        testClass.AttachToNotepad();

        base.OnStart(args);
    }

    protected override void OnStop()
    {
        ...
    }
}

【问题讨论】:

    标签: c# winapi pinvoke


    【解决方案1】:

    服务在其自己的会话中运行,即在 Vista 和 Win7 中臭名昭著的会话 0。该会话将服务与用户桌面隔离,它在另一个会话中运行。特别是为了防止通常使用特权帐户(如 LocalSystem)运行的服务与用户交互。一个安全漏洞。

    因此,服务无法看到另一个会话拥有的窗口句柄。

    不知道为什么要这样做,但通常需要一个帮助程序来呈现用户界面并通过 IPC 机制(如命名管道、套接字、.NET 远程处理或 WCF)与服务进行通信。如果您使用命名管道,请在管道名称前加上 "Global\",以便所有会话都可以看到它。

    【讨论】:

    • 感谢您的详细回答。经过进一步审查,在应用程序而不是服务中运行我的代码可能是一个更好的设计决策。
    【解决方案2】:

    您还可以启用“允许服务与桌面交互”选项,看看是否有效。否则我将不得不同意上面的 onbugz 评论。

    【讨论】:

    • 感谢您的建议。我在发布之前确实尝试过,它似乎并没有影响我的场景。
    【解决方案3】:

    Windows 服务没有 UI,因此它没有窗口。

    【讨论】:

    • 但是我查询的是notepad.exe实例的线程ID,而不是服务本身。
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2023-03-21
    相关资源
    最近更新 更多