确定进程何时完成初始化

2024-10-04 01:36:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个IronPython模块来初始化AutoCAD的一个实例,在AutoCAD完成初始化、进入消息循环并处于稳定(不加载依赖项/任何内容)状态后,我需要将1返回给调用它的模块。我尝试过使用System.Diagnostics.Process.WaitForInputIdle(),但没有成功。在

以下是我目前所掌握的情况:

import System.Diagnostics as sysdiag

def start_autocad(self):
    print("\"C:\\Program Files\\Autodesk\\Autodesk AutoCAD Civil 3D 2014\\acad.exe\" /b \"C:\\Temp\\C3DAutoScript.scr\"")
    for process in sysdiag.Process.GetProcessesByName("acad"):
        process.Kill()
    try:
        acad_process = sysdiag.Process.Start("C:\\Program Files\\Autodesk\\Autodesk AutoCAD Civil 3D 2014\\acad.exe", " /b \"C:\\Temp\\C3DAutoScript.scr\"")
        acad_process.WaitForInputIdle()
        return 1
    except:
        return 0

不幸的是,这个函数在进程开始打开时立即返回,而不是在它完成之后。有人知道在经典的cPython、IronPython或C#(不使用overkill sleep函数等待)中处理这个问题的方法吗?在


Tags: 模块filesprogramprocessexesystemironpythondiagnostics
2条回答

进程可以在启动后立即开始处理消息。不需要在完成此操作之前显示主窗口。这可以避免显示为挂起,以防加载缓慢。在

您可以在WaitForInputIdle返回后尝试与进程交互-它可能最终在“加载”时响应。如果它不工作,等待主窗口出现(使用FindWindow)。如果应用程序是COM服务器,则尝试建立COM连接。在

p.S.终止进程不是最好的主意,可能会导致数据或配置损坏。尝试正确关闭应用程序,并向其主窗口发送关闭事件。在

在你的问题的标题中,你要求“一个过程”。在您的问题文本中,您是专门针对Autocad提出的。在

我可以告诉您如何在一般的过程中执行此操作,而不是专门针对Autocad。在

我也遇到了同样的问题,于是找到了使用API的解决方案

GetModuleFileNameEx(HANDLE h_Process, ....)

MSDN说:

If the module list in the target process is corrupted or is not yet initialized, or if the module list changes during the function call as a result of DLLs being loaded or unloaded, GetModuleFileNameEx may fail or return incorrect information.

实际上,当您试图在进程仍在加载其DLL时使用此函数获取进程的可执行路径时,该函数将失败,GetLastError()返回{}。这并不意味着传递给函数的进程句柄无效。但这是进程仍在启动时得到的错误代码。在

我用几个应用程序测试了它。它工作得很好。在

^{pr2}$

为什么有用?GetModuleFileNameEx()在内部执行的操作是读取进程的内存(为此,必须使用访问权限process_VM_read打开进程)。但当进程处于加载器锁定状态时,这是不允许的。加载程序锁在进程加载DLL时处于活动状态

此代码是通用代码,适用于任何应用程序。它会等到应用程序准备好它的基本初始化。如果这对您来说还不够,我建议您等待应用程序的主窗口出现。在

相关问题 更多 >