代码之家  ›  专栏  ›  技术社区  ›  dcharles

为什么从服务调用GetWindowThreadProcessID时返回0?

  •  3
  • dcharles  · 技术社区  · 15 年前

    在控制台应用程序中使用以下类,并且至少运行一个记事本实例时, GetWindowThreadProcessId 正确返回非零线程ID。但是,如果Windows服务中包含相同的代码, 获取窗口线程进程ID 总是回报 0 不会抛出异常。将服务启动的用户更改为与运行控制台应用程序的用户相同,不会更改结果。什么原因 获取窗口线程进程ID 归来 0 即使提供了有效的硬件?为什么它在控制台应用程序和服务中的功能不同?注意:我运行的是32位Windows7,目标是.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()
        {
            ...
        }
    }
    
    3 回复  |  直到 13 年前
        1
  •  15
  •   Hans Passant    15 年前

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

    因此,服务无法看到其他会话拥有的窗口句柄。

    不知道为什么要这样做,但您通常需要一个助手程序,它提供用户界面,并通过名为pipes、sockets、net remoting或wcf的IPC机制与服务通信。如果使用命名管道,请在管道名称前面加上 "Global\" 所以所有的会话都可以看到它。

        2
  •  1
  •   Black Frog    15 年前

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

        3
  •  0
  •   John Saunders    15 年前

    Windows服务没有用户界面,因此没有窗口。