获取流程桌面

时间:2015-05-13 21:41:01

标签: windows winapi process desktop

作为项目的一部分,我正在使用CreateDesktopSwitchDesktopSetThreadDesktop等等创建和使用新桌面。

创建新桌面并切换到进程后,通过CreateProcess创建进程并存储句柄,以便在桌面关闭时我可以使用TerminateProcess终止进程,以便Windows可以删除/关闭桌面,因为必须终止桌面上的所有进程才能关闭桌面。

但是,使用文件对话框的程序会打开用户在桌面上执行任意进程,例如,如果我要为此桌面创建notepad.exe进程,则用户可以单击File > Open导航到{{ 1}}然后执行%windir%,它实际上会在桌面上打开,为它提供任务栏,开始按钮,当然还有能够做任何他们想做的事情。

问题是当这样的事情发生并且桌面切换回主桌面时,我的程序只知道并且可以终止它已经启动的进程,留下explorer.exe和桌面上剩下的任何其他进程处于不稳定状态,防止桌面被关闭。

我正在考虑使用EnumProcesses,然后获取每个的句柄,并希望找到一种方法来检索其桌面名称,以便我可以将它与我的进行比较并终止该过程。

这是解决这个问题的正确方法吗?如果是这样,我可以使用什么WinAPI函数来检索进程的桌面名称?但是,如果正确的方法,我该怎么做才能修复,预防或缓解这个问题?

1 个答案:

答案 0 :(得分:0)

有几种方法可以解决您的问题。

  1. 与@eryksun一样,您可以使用EnumDesktopWindows获取所有顶级窗口并将其作为WM_CLOSE消息发送。之后,您可以使用WaitForSingleObjectWaitForMultipleObjects超时,以便在超时后终止它们。您可以使用WAIT_TIMEOUT检查超时。这是python中的一个例子:
  2.     import win32api
        import win32con
        import win32event
        import win32gui
        import win32process
        import win32service
    
    
        def closeProcessesOnDesk(deskName,timeout):
            print("try to close Processes on given Desktop")
            hwndlist=[]
            try:
                hdesk = win32service.OpenDesktop(deskName,0,False,0)
                hwndlist = hdesk.EnumDesktopWindows()
            except Exception as ex:
                print("Desktop wasn't found. {}".format(ex))
            processlist =[]
            #try to close nicely processes"
            for hwnd in hwndlist:
                # Get the window's process id's
                if win32gui.IsWindowVisible(hwnd) and win32gui.IsWindowEnabled(hwnd):
                    tid, pid = win32process.GetWindowThreadProcessId(hwnd)
                    handle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
                    processlist.append(handle)
                # Ask window nicely to close
                    try:
                        win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
                    except:
                        pass
                # Allow some time for app to close
            print("Start waiting for processes to close")
            try:
                state = win32event.WaitForMultipleObjects(processlist, True, timeout)
    
                if state == win32con.WAIT_TIMEOUT:
                    print("processes didn't close nicely, terminate them")
            except Exception as ex:
                print("Error on closing Process. {}".format(ex))
            finally:
                for hproc in processlist:
                    if hproc:
                        win32api.TerminateProcess(hproc,0)
                        win32api.CloseHandle(hproc)  
    
        closeProcessesOnDesk('test',2000)
    
    1. 由于您已经处理了创建的Process,因此可以使用它来终止此过程的整个PROCESSreeree。在您的情况下,将在File > Open中以notepad.exe开始的每个流程也将终止。在python:
    2. import subprocess
      
      
      def killProcessTree(parent_pid):
          try:
              subprocess.call(['taskkill', '/F', '/T', '/PID', str(parent_pid)])
              print("Process killed: %s " % str(parent_pid))
          except Exception as ex:
              print("Process was not killed %s" % ex
      
      1. 您还可以创建具有受限权限的新用户,这样他甚至无法启动其他进程。使用CreateProcessWithLogonWCreateProcessAsUser作为"限制用户"启动流程。但请注意,由于winstations和桌面是安全对象,因此您必须将用户sid添加到桌面和winstation的DACL