所有用户正在运行的应用程序的窗口标题/前景检测

假设应用程序将由Windows上的administrator用户执行; 有没有办法使用Windows API来检索窗口标题,并检测应用程序是否在所有login用户的前台?

尝试下面的代码,我们无法检索其他login用户正在运行的应用程序的标题。

 // to get the processes Process[] processlist = Process.GetProcesses(); // and this to get the title: process.MainWindowTitle 

Solutions Collecting From Web of "所有用户正在运行的应用程序的窗口标题/前景检测"

你需要使用winapi的getforegroundwindow函数。 但这只是一个问题。 它必须在用户会话的上下文中执行。 这意味着您必须枚举计算机中的所有用户会话,获取用户令牌后,使用此用户令牌,通过CreateProcessAsUser在用户会话中执行辅助进程。 这个辅助进程可以执行getforegroundwindow,并且你必须实现任何ipc方法来将信息返回给你的主应用程序。 我在windows服务中使用这个代码,在用户会话的上下文中执行小程序:

 [StructLayout(LayoutKind.Sequential)] public struct SECURITY_ATTRIBUTES { public int nLength; public IntPtr lpSecurityDescriptor; public int bInheritHandle; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] struct STARTUPINFO { public Int32 cb; public string lpReserved; public string lpDesktop; public string lpTitle; public Int32 dwX; public Int32 dwY; public Int32 dwXSize; public Int32 dwYSize; public Int32 dwXCountChars; public Int32 dwYCountChars; public Int32 dwFillAttribute; public Int32 dwFlags; public Int16 wShowWindow; public Int16 cbReserved2; public IntPtr lpReserved2; public IntPtr hStdInput; public IntPtr hStdOutput; public IntPtr hStdError; } [StructLayout(LayoutKind.Sequential)] internal struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; } [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUserW", SetLastError = true, CharSet = CharSet.Auto)] static extern bool CreateProcessAsUser( IntPtr hToken, string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, UInt32 dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("wtsapi32.dll", SetLastError = true)] static extern int WTSQueryUserToken(UInt32 sessionId, out IntPtr Token); [DllImport("wtsapi32.dll", SetLastError = true)] static extern IntPtr WTSOpenserver([MarshalAs(UnmanagedType.LPStr)] String pserverName); [DllImport("wtsapi32.dll")] static extern void WTSCloseserver(IntPtr hserver); [DllImport("wtsapi32.dll", SetLastError = true)] static extern Int32 WTSEnumerateSessions( IntPtr hserver, [MarshalAs(UnmanagedType.U4)] Int32 Reserved, [MarshalAs(UnmanagedType.U4)] Int32 Version, ref IntPtr ppSessionInfo, [MarshalAs(UnmanagedType.U4)] ref Int32 pCount); [DllImport("wtsapi32.dll")] static extern void WTSFreeMemory(IntPtr pMemory); [StructLayout(LayoutKind.Sequential)] private struct WTS_SESSION_INFO { public Int32 SessionID; [MarshalAs(UnmanagedType.LPStr)] public String pWinStationName; public WTS_CONNECTSTATE_CLASS State; } public enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSlistn, WTSReset, WTSDown, WTSInit } public static IntPtr Openserver(String Name) { IntPtr server = WTSOpenserver(Name); return server; } public static void Closeserver(IntPtr serverHandle) { WTSCloseserver(serverHandle); } public static List<uint> ListSessions(String serverName) { IntPtr server = IntPtr.Zero; List<uint> ret = new List<uint>(); server = Openserver(serverName); try { IntPtr ppSessionInfo = IntPtr.Zero; Int32 count = 0; Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count); Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); Int64 current = (int)ppSessionInfo; if (retval != 0) { for (int i = 0; i < count; i++) { WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); current += dataSize; ret.Add((uint)si.SessionID); } WTSFreeMemory(ppSessionInfo); } } finally { Closeserver(server); } return ret; } protected override void OnStart(string[] args) { List<uint> retVal = ListSessions("COMPUTER_NAME"); for (int i = 0; i < retVal.Count; i++) { IntPtr userToken = new IntPtr(); WTSQueryUserToken(retVal[i], out userToken); STARTUPINFO info = new STARTUPINFO(); PROCESS_INFORMATION procInfo = new PROCESS_INFORMATION(); CreateProcessAsUser(userToken, null, @"c:\windows\notepad.exe", IntPtr.Zero, IntPtr.Zero, false, (UInt32)0, IntPtr.Zero, null, ref info, out procInfo); } 

}

此代码用于Windows服务,入口点是OnStart()函数。 在Windows中,SYSTEM帐户具有执行此代码所需的全部权限。 我没有在管理环境中检查它,但可能它也会工作。

这段代码将在所有用户会话中执行notepad.exe。 你必须让你编程,使用getforegroundwindow和某种进程间通信