作为项目的一部分,我正在使用CreateDesktop
,SwitchDesktop
,SetThreadDesktop
等等创建和使用新桌面。
创建新桌面并切换到进程后,通过CreateProcess
创建进程并存储句柄,以便在桌面关闭时我可以使用TerminateProcess
终止进程,以便Windows可以删除/关闭桌面,因为必须终止桌面上的所有进程才能关闭桌面。
但是,使用文件对话框的程序会打开用户在桌面上执行任意进程,例如,如果我要为此桌面创建notepad.exe进程,则用户可以单击File > Open
导航到{{ 1}}然后执行%windir%
,它实际上会在桌面上打开,为它提供任务栏,开始按钮,当然还有能够做任何他们想做的事情。
问题是当这样的事情发生并且桌面切换回主桌面时,我的程序只知道并且可以终止它已经启动的进程,留下explorer.exe
和桌面上剩下的任何其他进程处于不稳定状态,防止桌面被关闭。
我正在考虑使用EnumProcesses
,然后获取每个的句柄,并希望找到一种方法来检索其桌面名称,以便我可以将它与我的进行比较并终止该过程。
这是解决这个问题的正确方法吗?如果是这样,我可以使用什么WinAPI函数来检索进程的桌面名称?但是,如果不正确的方法,我该怎么做才能修复,预防或缓解这个问题?
答案 0 :(得分:0)
有几种方法可以解决您的问题。
EnumDesktopWindows
获取所有顶级窗口并将其作为WM_CLOSE
消息发送。之后,您可以使用WaitForSingleObject
或WaitForMultipleObjects
超时,以便在超时后终止它们。您可以使用WAIT_TIMEOUT
检查超时。这是python中的一个例子: 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)
File > Open
中以notepad.exe
开始的每个流程也将终止。在python: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
CreateProcessWithLogonW
或CreateProcessAsUser
作为"限制用户"启动流程。但请注意,由于winstations和桌面是安全对象,因此您必须将用户sid
添加到桌面和winstation的DACL
。