ShellExecute是windows的API函數,功能是執行可執行文件(exe)或任何關聯文件(doc、 txt、xls等)。但 ShellExecute是異步執行的,也就是說,不管執行的程序是否成功運行,運 行的時間是長是短,ShellExecute函數都會立即返回。這樣雖然可以很好地完成執行程序的工 作,但卻會給後續的工作帶來麻煩。
例如,當調用bcp命令向sql server導入數據後,在DBGrid中顯示這些導入的數據。如果使 用ShellExecute來直接執行bcp命令,很可能會在數據未完全導入時顯示DBGrid。這樣就會造成 數據顯示不完整或根本顯示不出來數據。
要解決這個問題的方法就是使ShellExecute變成同步直接的,解決方法很多,例如,可以判 斷彈出的控制台窗口是否已關閉來確定bcp是否執行完。但這樣做還會有一些問題,例如,如果 執行根本沒有彈出窗口的程序,那這種方法就不起作用了。而本書給出了另一種比較通用的方 法。基本原理是利用了批處理文件的特性。雖然ShellExecute是異步執行的,但批處理是同步 執行的,也就是在.bat、.cmd、.sh(linux/unix)中的命令是一個接一個順序執行的。因此, 我們可以采用在批處理文件中調用bcp命令的方法來實現同步調用。也就是說,可以在調用bcp 之前,先中當前目錄中建立一個文件或空目錄,然後調用bcp,最後再刪除這個文件或目錄。這 樣可以通過判斷文件或目錄是否存在來確定bcp是否執行完成。為了確保在調用 ShellExecute 之前文件一定存在,可以在調用ShellExecute之前在程序中建立一個文件,在批處理中刪除這 個文件。下面是一個批處理文件的例子。
批處理文件名:bcp.cmd
set path = <bcp.exe的本地路徑>/bcp.exe
bcp %1 in %2 %3 %4 其他命令行參數
del temp.txt
假設我們使用delphi來通過ShellExecute函數來運行bcp命令,代碼如下:
FileCreate("temp.txt");
ShellExecute(,"bcp.cmd",,);
while true do
begin
if temp.txt不存在 then
begin
// bcp已成功執行
break;
end;
end;
// 後續的處理代碼