如何解决在桌面上获取所有进程
我已经使用CreateDesktop创建了一个新的桌面,希望能够枚举该桌面中的所有进程。
我已经尝试过了:
foreach (Process process in Process.GetProcesses())
{
foreach (ProcessThread processThread in process.Threads)
{
IntPtr hDesk = GetThreadDesktop((uint)processThread.Id);
if (hDesk == desk)
{
// Do something
}
}
}
但是,我得到Access被拒绝例外。我也可以使用
EnumDesktopWindows
但是,这不适用于命令行应用程序。 (我正在尝试防止键盘记录程序)
有什么办法可以在桌面上获取所有进程? 谢谢
解决方法
我花了最后一个小时来玩这个游戏,并且可以在控制台窗口中正常运行。代码很杂乱,但是您应该可以通过它来完成自己的工作:
class Program
{
private static class Win32Native
{
[Flags]
public enum CreateDesktopFlags : uint
{
DF_NONE = 0,DF_ALLOWOTHERACCOUNTHOOK = 1
}
[Flags]
public enum CreateWindowAccessMask : uint
{
DESKTOP_READOBJECTS = 0x0001,DESKTOP_CREATEWINDOW = 0x0002,DESKTOP_CREATEMENU = 0x0004,DESKTOP_HOOKCONTROL = 0x0008,DESKTOP_JOURNALRECORD = 0x0010,DESKTOP_JOURNALPLAYBACK = 0x0020,DESKTOP_ENUMERATE = 0x0040,DESKTOP_WRITEOBJECTS = 0x0080,DESKTOP_SWITCHDESKTOP = 0x0100,DESKTOP_ALL_ACCESS = 0x01FF
}
[Flags]
public enum CreateProcessFlags : uint
{
CREATE_NEW_CONSOLE = 0x00000010,CREATE_NEW_PROCESS_GROUP = 0x00000200
}
[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Unicode)]
public struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[DllImport("user32.dll")]
public static extern IntPtr GetProcessWindowStation();
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool EnumWindowsProc(IntPtr hWnd,IntPtr lParam);
[return: MarshalAs(UnmanagedType.Bool)]
public delegate bool EnumDesktopProc([MarshalAs(UnmanagedType.LPWStr)] string lpszDesktop,IntPtr lParam);
[DllImport("user32.dll",SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumDesktopWindows(IntPtr hDesktop,EnumWindowsProc lpfn,EntryPoint = "GetWindowTextW",CharSet = CharSet.Unicode)]
public static extern int GetWindowText(IntPtr hWnd,StringBuilder lpString,int nMaxCount);
[DllImport("user32.dll",EntryPoint = "GetClassNameW",CharSet = CharSet.Unicode)]
public static extern int GetClassName(IntPtr hWnd,SetLastError = true,EntryPoint = "CreateDesktopW",CharSet = CharSet.Unicode)]
public static extern IntPtr CreateDesktop(
string lpszDesktop,IntPtr lpszDevice,IntPtr pDevMode,CreateDesktopFlags dwFlags,CreateWindowAccessMask dwDesiredAccess,IntPtr lpsa);
[DllImport("user32.dll",EntryPoint = "EnumDesktopsW",CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumDesktops(IntPtr hwinsta,EnumDesktopProc lpEnumFunc,IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseDesktop(IntPtr hDesktop);
[DllImport("kernel32.dll",EntryPoint = "CreateProcessW",CharSet = CharSet.Unicode)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateProcess(
string lpApplicationName,string lpCommandLine,IntPtr lpProcessAttributes,IntPtr lpThreadAttributes,bool bInheritHandles,CreateProcessFlags dwCreationFlags,IntPtr lpEnvironment,string lpCurrentDirectory,ref STARTUPINFO lpStartupInfo,out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll")]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll")]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool TerminateProcess(IntPtr hProcess,uint uExitCode);
}
static int Main(string[] args)
{
StringBuilder sbWndText = new StringBuilder(512),sbWndClass = new StringBuilder(512);
Console.WriteLine("Trying current desktop:");
if(!Win32Native.EnumDesktopWindows(IntPtr.Zero,(hWnd,lParam) =>
{
Win32Native.GetWindowText(hWnd,sbWndText,sbWndText.Capacity);
Win32Native.GetClassName(hWnd,sbWndClass,sbWndClass.Capacity);
Console.WriteLine($"Found Window: {hWnd} with title \"{sbWndText}\" and class name \"{sbWndClass}\"");
return true;
},IntPtr.Zero))
{
var error = Marshal.GetLastWin32Error();
Console.WriteLine($"EnumDesktopWindows for current desktop failed with error {error}");
}
Console.WriteLine("Current desktops: ");
Win32Native.EnumDesktops(Win32Native.GetProcessWindowStation(),(desktopName,lParam) =>
{
Console.WriteLine($"Found desktop: {desktopName}");
return true;
},IntPtr.Zero);
Console.WriteLine("Trying new desktop:");
const string DesktopName = "ANDY DESKTOP NEATO 2";
var hDesktop = Win32Native.CreateDesktop(
DesktopName,IntPtr.Zero,Win32Native.CreateDesktopFlags.DF_ALLOWOTHERACCOUNTHOOK,Win32Native.CreateWindowAccessMask.DESKTOP_ALL_ACCESS,IntPtr.Zero);
if(hDesktop != IntPtr.Zero)
{
Win32Native.EnumDesktops(Win32Native.GetProcessWindowStation(),lParam) =>
{
Console.WriteLine($"Found desktop: {desktopName}");
return true;
},IntPtr.Zero);
var si = new Win32Native.STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = DesktopName;
var pi = new Win32Native.PROCESS_INFORMATION();
if(!Win32Native.CreateProcess(
null,"cmd.exe",false,Win32Native.CreateProcessFlags.CREATE_NEW_CONSOLE |
Win32Native.CreateProcessFlags.CREATE_NEW_PROCESS_GROUP,null,ref si,out pi))
{
var error = Marshal.GetLastWin32Error();
Console.WriteLine($"Unable to create process on new desktop: {error}");
}
Console.WriteLine("WAITING 2 SECONDS FOR PROCESS TO START...");
Thread.Sleep(2000); // breath so the process starts
if (!Win32Native.EnumDesktopWindows(hDesktop,lParam) =>
{
Win32Native.GetWindowText(hWnd,sbWndText.Capacity);
Win32Native.GetClassName(hWnd,sbWndClass.Capacity);
Console.WriteLine($"Found Window: {hWnd} with title \"{sbWndText}\" and class name \"{sbWndClass}\"");
return true;
},IntPtr.Zero))
{
var error = Marshal.GetLastWin32Error();
Console.WriteLine($"EnumDesktopWindows for new desktop failed with error {error}");
}
// IMPORTANT: close the processes you start,otherwise you desktop won't self-destruct.
Win32Native.TerminateProcess(pi.hProcess,42);
Win32Native.CloseHandle(pi.hProcess);
Win32Native.CloseHandle(pi.hThread);
Win32Native.CloseDesktop(hDesktop);
}
else
{
Console.WriteLine($"Unable to create desktop: {Marshal.GetLastWin32Error()}");
}
return 0;
}
}
所以我认为您在使用EnumDesktopWindows
时遇到的问题是,当您致电CreateDesktop
时,您并没有要求足够的特权。我将所有特权设置为(0x1FF
的值),然后EnumDesktopWindows
为我工作。
请记住,如果您调用EnumDesktopWindows
并且没有要枚举的窗口,则在您调用false
时它将返回0
,其值为GetLastError
。
因此,为了证明其确实有效,我在新桌面中创建了一个进程(cmd.exe
),然后将其命名为EnumDesktopWindows
。
还请记住,如果您不破坏新桌面中的所有进程,则桌面将不会“自毁”,并且在所有进程被破坏或注销/重新启动之前它将一直处于活动状态。
我也以普通用户身份运行它。我不需要提升管理员即可完成这项工作。
,但是,这不适用于命令行应用程序。 (我在尝试 以防止键盘记录程序)
假设您要阻止桌面hooking keyboard的输入。
由于钩子需要一个消息循环来接收键盘消息,因此需要创建一个窗口。因此,限制其他用户创建与您的桌面关联的窗口应用程序可以阻止他们记录键盘输入。
如果您要检查给定进程的桌面名称,以查看它是否与您的桌面名称(适用于窗口应用程序)相同,则可以按照以下步骤操作:
- 调用OpenProcess()从目标进程ID中获取
HANDLE
。 - 调用NtQueryInformationProcess()来检索进程的
PEB
结构的地址。 - 致电ReadProcessMemory()以阅读
PEB
。ProcessParams.DesktopName
字段包含当前与该流程关联的工作站/桌面的名称(PEB.ProcessParams中还有更多字段,然后MSDN显示)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。