长话短说,我正在尝试向作为Windows服务运行的自定义更新程序添加一些功能。我遇到了一些问题,试图更新的应用程序可能正在运行,如果需要,我需要执行一些自定义操作。

我遇到的问题是EnumDesktopWindows api调用仅返回在本地系统上下文中运行的进程。

现在,这对于我为什么这样做是最有意义的(依此类推(我想-尽管会进一步解释))。

但是,如何通过一项服务来实现这一功能呢?

这是我正在使用的代码的基础:

        public static IntPtr[] EnumDesktopWindows()
        {
            WinAPI._desktopWindowHandles = new List<IntPtr>();
            WinAPI.EnumDelegate enumfunc = new WinAPI.EnumDelegate(EnumWindowsCallBack);
            IntPtr hDesktop = IntPtr.Zero; // current desktop
            bool success = WinAPI.EnumDesktopWindows(hDesktop, enumfunc, IntPtr.Zero);

            if (success)
            {
                IntPtr[] handles = new IntPtr[_desktopWindowHandles.Count];
                _desktopWindowHandles.CopyTo(handles);
                return handles;
            }
            else
            {
                int errorCode = Marshal.GetLastWin32Error();
                string errorMessage = String.Format("EnumDesktopWindows failed with code {0}.", errorCode);
                throw new Exception(errorMessage);
            }

        }


可能是我全都错了,问题就在这里吗?:

IntPtr hDesktop = IntPtr.Zero;

最佳答案

我不确定您列举的台式机方向是否正确。我不知道谁是服务内部EnumDesktopWindows调用之后的操作的发起者。如果用户触发了该操作,那么您可能可以模拟他的用户帐户,并且该问题将很容易解决。

如果您无法接收用户令牌,我建议您先阅读Impact of Session 0 Isolation on Services and Drivers in Windows文档,然后再继续。您遇到的主要问题是终端服务正在计算机上运行,​​而Windows服务在会话ID为0的会话中运行,但是所有用户进程在另一个会话中运行。如果您的服务在LocalSystem帐户下或在具有SE_TCB_NAME特权的任何其他帐户下运行,则可以将SetTokenInformation函数与TokenSessionId参数一起使用以更改为当前会话(有关更多详细信息,请参见here)。关于LsaEnumerateLogonSessions功能,您可以收到的所有可用会话。

最后,我可以再重复一遍,只有在无法使用其他更简单的方式(例如用户模拟)时,才应该更改服务会话。

关于c# - Windows Service中的EnumDesktopWindows,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5298351/

10-09 02:53