What is the best way to run an external program from excel. It might run for several minutes. What's the best-practice about how to to this. Ideally,
从excel运行外部程序的最佳方法是什么?它可能会运行几分钟。关于如何做到这一点的最佳实践是什么?理想的情况下,
- A model dialog box that let's the user know that the process is executing.
- If the executable fails, the user should receive a notification.
- A timeout should be enforced.
- A cancel button should be on the dialog box.
一个模型对话框,让用户知道进程正在执行。
如果可执行文件失败,则用户应收到通知。
应该强制执行超时。
取消按钮应位于对话框中。
But any best-practices are welcome. I'm interested in solutions with calling either a .dll or an .exe. Preferably something that works with Excel '03 or earlier, but I'd love to hear a reason to move to a later version as well.
但欢迎任何最佳做法。我对调用.dll或.exe的解决方案感兴趣。最好是与Excel '03或更早版本一起使用的东西,但我也很想听到移动到更高版本的原因。
1 个解决方案
#1
5
You should check out these two Microsoft KB articles
您应该查看这两篇Microsoft KB文章
How to launch a Win32 Application from Visual Basic and
如何从Visual Basic和Visual Basic启动Win32应用程序
How To Use a 32-Bit Application to Determine When a Shelled Process Ends
如何使用32位应用程序来确定外壳进程何时结束
They both quickly give you the framework to launch a process and then check on its completion. Each of the KB articles have some additional references that may be relevant.
他们都快速为您提供启动流程的框架,然后检查其完成情况。每篇知识库文章都有一些可能相关的其他参考文献。
The latter knowledgebase article assumes that you want to wait for an infinite amount of time for your shell process to end.
后一篇知识库文章假设您希望等待无限量的shell进程结束。
You can modify the ret& = WaitForSingleObject(proc.hProcess, INFINITE) function call to return after some finite amount of time in milliseconds--replace INFINITE with a positive value representing milliseconds and wrap the whole thing in a Do While loop. The return value tells you if the process completed or the timer ran out. The return value will be zero if the process ended.
你可以修改ret&= WaitForSingleObject(proc.hProcess,INFINITE)函数调用,在几毫秒的有限时间后返回 - 用表示毫秒的正值替换INFINITE并将整个事件包装在Do While循环中。返回值告诉您进程是否已完成或计时器是否已用完。如果过程结束,返回值将为零。
If the return value is non-zero then the process is still running, but control is given back to your application. During this time while you have positive control of your application, you can determine whether to update some sort of UI status, check on cancellation, etc. Or you can loop around again and wait some more.
如果返回值非零,则进程仍在运行,但控制权将返回给您的应用程序。在此期间,当您可以正确控制应用程序时,可以确定是否更新某种UI状态,检查取消等。或者您可以再次循环并等待一些。
There are even additional options if the program you are shelling to is something that you wrote. You could hook into one of its windows and have the program post messages that you can attach to and use as status feedback. This is probably best left for a separate item if you need to consider it.
如果你正在炮击的程序是你写的东西,甚至还有其他选项。您可以挂钩其中一个窗口并让程序发布消息,您可以将其附加到并用作状态反馈。如果您需要考虑它,最好留给单独的项目。
You can use the process structure to get a return value from the called process. Your process does need to return a value for this to be useful.
您可以使用流程结构从被调用的流程获取返回值。您的进程需要为此返回一个有用的值。
My general approach to this kind of need is to:
我对这种需求的一般方法是:
- give the user a non-modal status dialog at the start of the process with a cancel button, which when clicked will set a flag to be checked later. Providing the user with any status is most likely impossible, so giving them an elapsed time or one of those animated GIFs might be helpful in managing expectations.
- Start the process
- Wait for the process to complete, allowing cancellation check every 500ms
- If the process is complete close the dialog and continue along.
- If the process is not complete, see if the user hit cancel and if so send a close message to the process' window. This may not work and terminating the process might be required--careful if you do this. Your best bet may be to abandon the process if it won't close properly. You can also check for a timeout at this point and try to take the same path as if the user hit cancel.
使用取消按钮在进程开始时为用户提供非模态状态对话框,单击该按钮将设置稍后要检查的标志。向用户提供任何状态很可能是不可能的,因此给他们一个经过时间或其中一个动画GIF可能有助于管理期望。
开始这个过程
等待该过程完成,允许每500ms进行一次取消检查
如果该过程完成,请关闭对话框并继续。
如果进程未完成,请查看用户是否单击取消,如果是,则向进程窗口发送关闭消息。这可能不起作用,可能需要终止该过程 - 如果您这样做,请小心。如果不能正常关闭,您最好的选择可能是放弃该过程。您还可以检查此时的超时,并尝试采用与用户点击取消相同的路径。
Hope this helps, Bill.
比尔希望这有帮助。
#1
5
You should check out these two Microsoft KB articles
您应该查看这两篇Microsoft KB文章
How to launch a Win32 Application from Visual Basic and
如何从Visual Basic和Visual Basic启动Win32应用程序
How To Use a 32-Bit Application to Determine When a Shelled Process Ends
如何使用32位应用程序来确定外壳进程何时结束
They both quickly give you the framework to launch a process and then check on its completion. Each of the KB articles have some additional references that may be relevant.
他们都快速为您提供启动流程的框架,然后检查其完成情况。每篇知识库文章都有一些可能相关的其他参考文献。
The latter knowledgebase article assumes that you want to wait for an infinite amount of time for your shell process to end.
后一篇知识库文章假设您希望等待无限量的shell进程结束。
You can modify the ret& = WaitForSingleObject(proc.hProcess, INFINITE) function call to return after some finite amount of time in milliseconds--replace INFINITE with a positive value representing milliseconds and wrap the whole thing in a Do While loop. The return value tells you if the process completed or the timer ran out. The return value will be zero if the process ended.
你可以修改ret&= WaitForSingleObject(proc.hProcess,INFINITE)函数调用,在几毫秒的有限时间后返回 - 用表示毫秒的正值替换INFINITE并将整个事件包装在Do While循环中。返回值告诉您进程是否已完成或计时器是否已用完。如果过程结束,返回值将为零。
If the return value is non-zero then the process is still running, but control is given back to your application. During this time while you have positive control of your application, you can determine whether to update some sort of UI status, check on cancellation, etc. Or you can loop around again and wait some more.
如果返回值非零,则进程仍在运行,但控制权将返回给您的应用程序。在此期间,当您可以正确控制应用程序时,可以确定是否更新某种UI状态,检查取消等。或者您可以再次循环并等待一些。
There are even additional options if the program you are shelling to is something that you wrote. You could hook into one of its windows and have the program post messages that you can attach to and use as status feedback. This is probably best left for a separate item if you need to consider it.
如果你正在炮击的程序是你写的东西,甚至还有其他选项。您可以挂钩其中一个窗口并让程序发布消息,您可以将其附加到并用作状态反馈。如果您需要考虑它,最好留给单独的项目。
You can use the process structure to get a return value from the called process. Your process does need to return a value for this to be useful.
您可以使用流程结构从被调用的流程获取返回值。您的进程需要为此返回一个有用的值。
My general approach to this kind of need is to:
我对这种需求的一般方法是:
- give the user a non-modal status dialog at the start of the process with a cancel button, which when clicked will set a flag to be checked later. Providing the user with any status is most likely impossible, so giving them an elapsed time or one of those animated GIFs might be helpful in managing expectations.
- Start the process
- Wait for the process to complete, allowing cancellation check every 500ms
- If the process is complete close the dialog and continue along.
- If the process is not complete, see if the user hit cancel and if so send a close message to the process' window. This may not work and terminating the process might be required--careful if you do this. Your best bet may be to abandon the process if it won't close properly. You can also check for a timeout at this point and try to take the same path as if the user hit cancel.
使用取消按钮在进程开始时为用户提供非模态状态对话框,单击该按钮将设置稍后要检查的标志。向用户提供任何状态很可能是不可能的,因此给他们一个经过时间或其中一个动画GIF可能有助于管理期望。
开始这个过程
等待该过程完成,允许每500ms进行一次取消检查
如果该过程完成,请关闭对话框并继续。
如果进程未完成,请查看用户是否单击取消,如果是,则向进程窗口发送关闭消息。这可能不起作用,可能需要终止该过程 - 如果您这样做,请小心。如果不能正常关闭,您最好的选择可能是放弃该过程。您还可以检查此时的超时,并尝试采用与用户点击取消相同的路径。
Hope this helps, Bill.
比尔希望这有帮助。