Inno Setup執行SQL指令碼的方法

2021-09-08 10:14:33 字數 4617 閱讀 6239

作為和nsis並立的、兩個最流行的免費windows應用程式安裝包製作工具之一,inno在學習難度上相對要低一些,非常適合對一些簡單的桌面程式打包。但對於較複雜的安裝過程,或者web應用程式來說,我個人覺得不是inno的強項。當然,既然inno內嵌了pascal語言用以擴充套件功能,理論上不是不可以應付複雜的安裝過程,但實現起來要複雜一些。

比如對於在安裝過程中連線資料庫並執行sql指令碼這樣的需求,使用installshield應該會簡單地多,而inno卻不支援直接運算元據庫,並且相關的資料說明少之又少,還不如nsis豐富,以至於我踏破鐵鞋無覓處,最終卻在nsis的資料中找到了思路。

主要的思路是,在安裝過程中,呼叫資料庫客戶端連線資料庫並執行sql指令碼,然後將執行結果或錯誤資訊輸出到檔案中,最後通過分析這個檔案來判斷命令執行的結果。但是,既然是呼叫特定的客戶端,那麼對不同資料庫的操作自然就有所區別,具體情況如下所述。

首先在打包指令碼的[files]段將必需的檔案包含進來:

在sql server中執行指令碼的**片斷:

function execscriptinmssql(dbhost, dblogin, dbpass, dbname: string): boolean;

varconnectexe: string;

connectparam: string;

begin

extracttemporaryfile('osql.exe');

extracttemporaryfile('script_mssql.sql');

connectexe := expandconstant('') + '/osql.exe';

connectparam := ' -s ' + dbhost

+ ' -u ' + dblogin

+ ' -p ' + dbpass

+ ' -d ' + dbname

+ ' -i script_mssql.sql -o '

+ expandconstant('') + '/dbstatus.txt';

if exec(connectexe, connectparam, '', sw_hide, ewwaituntilterminated, resultcode) then begin

result := resultcode = 0;

loadstringfromfile(expandconstant('') + '/dbstatus.txt', statusstring);

if statusstring <> '' then begin

msgbox(statusstring, mberror, mb_ok);

result := false;

end else begin

result := true;

end;

end else begin

msgbox('database update failed:'#10#10 + syserrormessage(resultcode), mberror, mb_ok);

result := false;

end;

end;

在mysql中執行指令碼的**片斷:

function execscriptinmysql(dbhost, dblogin, dbpass, dbname: string): boolean;

varconnectexe: string;

connectparam: string;

begin

extracttemporaryfile('mysql.exe');

extracttemporaryfile('script_mysql.sql');

connectexe := expandconstant('cmd');

connectparam := ' /c "' + expandconstant('') + '/mysql.exe'

+ ' -h' + dbhost

+ ' -u' + dblogin

+ ' -p' + dbpass

+ ' -d' + dbname

+ ' -e "source ' + expandconstant('') + '/script_mysql.sql""> ' + expandconstant('') + '/dbstatus.txt 2>&1';

if exec(connectexe, connectparam, '', sw_hide, ewwaituntilterminated, resultcode) then begin

result := resultcode = 0;

loadstringfromfile(expandconstant('') + '/dbstatus.txt', statusstring);

if statusstring <> '' then begin

msgbox(statusstring, mberror, mb_ok);

result := false;

end else begin

result := true;

end;

end else begin

msgbox('database update failed:'#10#10 + syserrormessage(resultcode), mberror, mb_ok);

result := false;

end;

end;

由於mysql.exe沒有輸出結果到檔案的引數,故需要使用cmd.exe來執行mysql.exe以便將其輸出重定向到檔案dbstatus.txt中。此外,在命令的最後加上引數2>&1,將標準錯誤輸出裝置也重定向到檔案上,否則命令執行的錯誤資訊不會輸出到檔案中。

在oracle中執行指令碼的**片斷:

function execscriptinoracle(clientpath, dbinstance, dblogin, dbpass: string): boolean;

begin

extracttemporaryfile('script_oracle.sql');

if exec(expandconstant('cmd'), ' /c "' + clientpath + ' -l -s ' + dblogin

+ '/' + dbpass

+ '@' + dbinstance

+ ' @' + expandconstant('') + '/script_oracle.sql> ' + expandconstant('') + '/dbstatus.txt 2>&1',

'',sw_hide, ewwaituntilterminated, resultcode)

then begin

result := resultcode = 0;

loadstringfromfile(expandconstant('') + '/dbstatus.txt', statusstring);

if pos('holytail', statusstring) <> 0 then begin

if pos('ora-', statusstring) <> 0 then begin

if msgbox('資料庫更新出錯,是否開啟日誌檔案?', mbconfirmation, mb_yesno) = idyes then begin

if not shellexec('', expandconstant('') + '/dbstatus.txt', '', '', sw_show, ewnowait, errorcode) then begin

msgbox('日誌檔案開啟錯誤!', mberror, mb_ok);

end;

end;

result := false;

end else begin

result := true;

end;

end else if statusstring <> '' then begin

msgbox(statusstring, mberror, mb_ok);

result := false;

end else begin

result := true;

end;

end else begin

msgbox('database update failed:'#10#10 + syserrormessage(resultcode), mberror, mb_ok);

result := false;

end;

end;

oracle的客戶端太大,不能整合到安裝包中,應使用乙個tinputfilewizardpage由使用者選擇sqlplus.exe的安裝位置。同時,由於sqlplus.exe也沒有輸出結果到檔案的引數,也須使用cmd.exe來執行它並重定向輸出到檔案。此外,由於sqlplus.exe執行指令碼時無論成功還是失敗,都會輸出資訊,故無法像使用sqlcmd.exe和mysql.exe那樣簡單地判斷指令碼是否執行成功,需要在指令碼的最後通過select語句輸出乙個特殊的字串到檔案中,然後通過判斷dbstatus.txt中是否存在該字串來判斷指令碼的執**況;且由於sqlplus.exe執行完指令碼後不會自動退出,還要在指令碼最後加上exit語句;故script_oracle.sql的最後必須是如下內容:

select 'holytail' from dual;

exit;

Inno Setup執行SQL指令碼的方法

作為和nsis並立的 兩個最流行的免費windows應用程式安裝包製作工具之一,inno在學習難度上相對要低一些,非常適合對一些簡單的桌面程式打包。但對於較複雜的安裝過程,或者web應用程式來說,我個人覺得不是inno的強項。當然,既然inno內嵌了pascal語言用以擴充套件功能,理論上不是不可以...

Inno Setup執行SQL指令碼的方法

作為和nsis並立的 兩個最流行的免費windows應用程式安裝包製作工具之一,inno在學習難度上相對要低一些,非常適合對一些簡單的桌面程式打包。但對於較複雜的安裝過程,或者web應用程式來說,我個人覺得不是inno的強項。當然,既然inno內嵌了pascal語言用以擴充套件功能,理論上不是不可以...

Inno Setup執行SQL指令碼的方法

作為和nsis並立的 兩個最流行的免費windows應用程式安裝包製作工具之一,inno在學習難度上相對要低一些,非常適合對一些簡單的桌面程式打包。但對於較複雜的安裝過程,或者web應用程式來說,我個人覺得不是inno的強項。當然,既然inno內嵌了pascal語言用以擴充套件功能,理論上不是不可以...