【发布时间】:2018-12-21 17:25:45
【问题描述】:
这是场景:
我使用ShellExecuteEx 来打开给定的.xlsx 文件。这工作正常,Excel 已启动并在 Excel 中打开 .xlsx 文件。
现在ShellExecuteEx 或多或少会在 Excel 完全启动并打开 .xlsx 文件之前立即返回。到目前为止一切顺利。
有没有办法等到 Excel 实际打开 .xlsx 文件?类似 BOOL FileIsOpenExclusively(LPCTSTR filename) 函数返回 TRUE 的东西是文件被独占打开吗?
然后我可以做这样的事情(简约、幼稚和无错误检查)伪代码:
ShellExecuteEx(... stuff for opening myfile.xlsx ...);
while (FileIsOpenExclusively("myfile.xlsx"))
{
Sleep(500);
}
// now "myfile.xlsx" is opened execusively
已编辑
实际稍微复杂一点的场景是这样的:
-
ShellExecuteEx启动 Excel 打开给定的 .xlsx 文件。 - 那么我需要以某种方式知道 .xlsx 文件何时关闭,要么是因为 Excel 用户关闭了该文件,要么是因为用户一起退出了 Excel。
这个伪代码说明了我现在正在做的事情:
ShellExecuteEx(... stuff for opening myfile.xlsx ...);
Sleep(5000); // wait that Excel has hopefully has opened the file
do
{
Sleep(500);
Open("myfile.xlsx");
} while (opening file is unsuccessful)
// file could be opened which means that Excel has closed it
Close("myfile.xlsx");
问题是Sleep(5000);:如果 Excel 无法在 5.5 秒内打开文件,下面的测试将失败,因为它会认为 Excel 甚至在文件打开之前就已经关闭了文件。因此,我需要知道 Excel 何时打开文件,而不是等待确定的时间。
也许还有另一种方法。一些 cmets 建议使用WaitForInputIdle,这听起来很有希望,但如果事先已经有一个打开的 Excel 实例(待测试),这可能不起作用。
另一条评论建议枚举顶级窗口并检查窗口标题的更改,但我不确定这是否适用于现代 Excel 版本(待检查),如果它有效,它可能会停止使用下一个主要 Excel 版本。
使用机会锁听起来很有希望,我将在下周进行测试。
最后使用重启管理器也可能是一个线索。
【问题讨论】:
-
可能是 CreateProcess 和 WaitForInputIdle?
-
为什么必须等待Excel打开文件?没有冒犯,但这闻起来像 XY 问题。无论如何,您可以通过 Excel 进程使用Restart Manager to check if the file has been opened。
-
另一个允许您在进程想要打开文件时接收通知的 API 是在文件上放置 Opportunistic Lock。当另一个进程想要打开同一个文件时,锁会被打破,你会收到一个通知。然而,缺点是,例如,打开对话框可能会在文件实际打开之前打破锁定。但至少它是值得研究的。
-
如果 Excel 根本不打开文件怎么办?与启动的应用程序通信没有标准;你必须做一些临时的事情。对于 Excel,您可以尝试使用 object model to open workbooks。
标签: winapi