首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定进程何时完成初始化

确定进程何时完成初始化
EN

Stack Overflow用户
提问于 2014-09-17 03:27:16
回答 2查看 725关注 0票数 1

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

到目前为止,我的情况如下:

代码语言:javascript
复制
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#中处理这个问题(而不需要使用过度的睡眠函数来等待)吗?

EN

回答 2

Stack Overflow用户

发布于 2014-09-17 03:58:04

进程几乎可以在启动后立即开始处理消息。在此之前不需要显示主窗口。这是可以做到的,以避免显示为悬挂,如果加载是缓慢的。

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

销毁过程不是最好的主意,可能会导致数据或配置的损坏。尝试正确关闭应用程序,将关闭事件发送到其主窗口。

票数 1
EN

Stack Overflow用户

发布于 2015-08-13 16:14:27

在你问题的标题中,你要求“一个过程”。在你的问题的文本中,你专门问了Autocad。

我可以告诉您如何在一般的过程中这样做,而不是专门针对Autocad。

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

代码语言:javascript
复制
GetModuleFileNameEx(HANDLE h_Process, ....)

MSDN说:

如果目标进程中的模块列表已损坏或尚未初始化,或者由于加载或卸载DLL而在函数调用期间更改模块列表,则GetModuleFileNameEx可能失败或返回不正确的信息。

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

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

代码语言:javascript
复制
int WaitForProcess(HANDLE h_Process, int Timeout)
{
    for (int T=0; T<=Timeout; T+=50)
    {
       if (GetModuleFileNameEx(h_Process, NULL, ...) > 0)
           return 0;

       int Err = GetLastError();
       if (Err != ERROR_INVALID_HANDLE) // = 6
           return Err;

       Sleep(50);
    }
    return ERROR_TIMEOUT;
}

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25881791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档