innosetup下SQL靜默安裝有3個主要問題:
1.如何製作SQL靜默安裝的腳本
2.如何使用innosetup調用這個腳本
3.如何自動附加上數據庫
然而這3個問題噁心極了,主要是由於各種沙雕脫離了SQL安裝實際,傳來傳去都是辟邪劍譜殘章("欲練此功必先自宮"那部分)
我這裏也少放屁,直接上解決方案(如果各位看管姥爺解決不了,也可以給我私信或者去找微軟官方要一份靜默安裝腳本)
首先,要先把靜默安裝搞起。先看這位大兄弟的解決方案:
http://blog.csdn.net/andkylee/article/details/5813029
這裏有個風水問題:大兄弟和我用的斜槓是反的
我用的是SQL 2005 Express sp4
1.向一個批處理文件寫入下列內容
Start /wait setup.exe /qb INSTANCENAME=實例名 ADDLOCAL=SQL_Engine,Client_Components,Connectivity,SDK SAPWD=SA密碼 SQLACCOUNT="NT AUTHORITY\SYSTEM" SQLPASSWORD= AGTACCOUNT="NT AUTHORITY\Network Service" AGTPASSWORD=
SQLBROWSERACCOUNT="NT AUTHORITY\SYSTEM" SQLBROWSERPASSWORD= SECURITYMODE=SQL DISABLENETWORKPROTOCOLS=2 SQLCOLLATION=Chinese_PRC_CI_AS ASCOLLATION=Chinese_PRC_CI_AS
2.然後把微軟的SQL 2005 Express安裝包解壓了,弄出來這麼一個文件夾:
D:\SQLEXPR_CHS
把這個批處理丟進去,然後試着運行一下。如果成了,那麼說明靜默安裝已經成功實現。
如果失敗了,有以下這麼幾個原因:
1.SQL Server 2005 Express的版本不同,導致靜默安裝所使用的參數不同,具體的請花點功夫查一查、試一試
2.批處理位置沒有放對(基本不可能)
接下來要搞個大新聞,弄一弄innosetup的腳本。在此之前,奉勸各位先用一用innosetup
那麼假設各位已經有一些 innosetip的使用經驗了(細節問題懶得解釋)
直接把代碼放出來
; 腳本由 Inno Setup 腳本嚮導 生成!
; 有關創建 Inno Setup 腳本文件的詳細資料請查閱幫助文檔!
#define MyAppName 自己寫
#define MyAppVersion 自己寫
#define MyAppPublisher 自己寫
#define MyAppURL 自己寫
#define MyAppExeName 自己寫
[Setup]
; 注: AppId的值爲單獨標識該應用程序。
; 不要爲其他安裝程序使用相同的AppId值。
; (生成新的GUID,點擊 工具|在IDE中生成GUID。)
AppId={{68D14220-67BA-4556-9E35-5316E655EA03}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={code:GetDirName}
DefaultGroupName={#MyAppName}
DisableDirPage=yes
OutputDir=D:\打包項目
OutputBaseFilename=自己寫
Compression=lzma
SolidCompression=yesSetupIconFile=aa.ico更換了一下安裝文件的ICO,不必在意
;卸載文件目錄
Uninstallable=yes
UninstallFilesDir={app}\更換了卸載文件目錄,不必在意
[Languages]
Name: "chinesesimp"; MessagesFile: "compiler:Default.isl"
[Types]
Name:Full;Description:"程序組件";Flags:iscustom
[Components]愛怎麼玩怎麼玩吧
Name:main;Description:"主程序";Types:full ;Flags:fixed;
Name:sql;Description:"SQLServer Express2005";Types:full ;Flags:fixed;
Name:dotnet;Description:".Net Framework 2.0";Types:full ;Flags:fixed;
[Files]這裏的sqladd.sql是一個附加數據庫指令,大致內容:
exec sp_attach_db @dbname=N'Dentist' , @filename1=N'$CD\DATA_DATA.mdf',@filename2=N'$CD\DATA_Log.ldf'
$CD是傳入的參數
;安裝
Source: "D:\打包項目\軟件\軟件.exe"; DestDir: "{app}\"; Flags: ignoreversion;Components:main
Source: "D:\打包項目\SQLEXPR_CHS\*"; DestDir: "{tmp}\SQLEXPR_CHS"; Flags: ignoreversion recursesubdirs createallsubdirs;Components:sql
;Data
Source: "D:\打包項目\SQLEXPR_CHS\sqladd.sql"; DestDir: "{app}\Data"; Flags: ignoreversion recursesubdirs createallsubdirs;Components:sql
;Data
Source: "D:\打包項目\SQLEXPR_CHS\setup\program files\microsoft sql server\90\tools\binn\*"; DestDir: "{app}\Data"; Flags: ignoreversion recursesubdirs createallsubdirs;Components:sql
上面這行是從SQL安裝包裏扒出來的,如果用SQL2012及以上的安裝包,注意一下還要從另外的地方扒一個resources文件夾,放到一起(DestDir: "{app}\Data"),不然會缺少dll來支持sqlcmd.exe
;安裝
Source: "D:\打包項目\軟件\*"; DestDir: "{app}\安裝"; Flags: ignoreversion recursesubdirs createallsubdirs ;Components:main
Source: "D:\打包項目\系統工具\*"; DestDir: "{app}\系統工具"; Flags: ignoreversion recursesubdirs createallsubdirs ;Components:main
Source: "D:\打包項目\dotnetfx20.exe"; DestDir: "{tmp}"; Flags: ignoreversion ;Components:dotnet
加個.Net2.0框架助助興
;我需要的組件,當然你們也可以選擇不加。至於你們的選擇,相信你們是聰明的
Source: "D:\打包項目\ocx\ACRptEngineX.ocx"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
Source: "D:\打包項目\ocx\FM20.DLL"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
Source: "D:\打包項目\ocx\GRABBM~1.OCX"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
Source: "D:\打包項目\ocx\grdes50.dll"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
Source: "D:\打包項目\ocx\gregn50.dll"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
Source: "D:\打包項目\ocx\MSCOMM32.OCX"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
Source: "D:\打包項目\ocx\Msflxgrd.ocx"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
Source: "D:\打包項目\ocx\proChameleonButton.ocx"; DestDir: "{sys}"; Flags: overwritereadonly restartreplace uninsneveruninstall sharedfile
; 注意: 不要在任何共享系統文件上使用“Flags: ignoreversion”
[Dirs]
Name:"{app}\Data Bak";加了個空文件夾進去,不必在意
[Code]
var
Page: TWizardPage;
RadioButton1, RadioButton2: TRadioButton;
Lbl1, Lbl2: TNewStaticText;
freespacelabel:TLabel;
FreeSpace,TotalSpace:Cardinal;
procedure ShowFreeSpaceOnDisc(Sender:TObject);
begin
GetSpaceOnDisk(ExtractFileDrive(WizardForm.DirEdit.Text),True,FreeSpace,TotalSpace);
freespacelabel.Caption:='磁盤可用空間:'+IntToStr(FreeSpace)+'MB';
end;
procedure CreateAddonPage;加了個自定義頁面
begin
Page := CreateCustomPage(wpInfoBefore, '選擇安裝類型', '請根據您的需要選擇安裝的類型');
RadioButton1 := TRadioButton.Create(Page);
RadioButton1.Left := ScaleX(80);
RadioButton1.Top := ScaleY(40);
RadioButton1.Width := Page.SurfaceWidth;
RadioButton1.Height := ScaleY(17);
RadioButton1.Caption := '主機版安裝';
RadioButton1.Checked := True;
RadioButton1.Parent := Page.Surface;
Lbl1 := TNewStaticText.Create(Page);
Lbl1.Left := ScaleX(95);
Lbl1.Top := ScaleY(60);
Lbl1.Width := ScaleX(250);
Lbl1.Height := ScaleY(50);
Lbl1.Caption := '按照標準模式安裝軟件到您的電腦';
Lbl1.Parent := Page.Surface;
RadioButton2 := TRadioButton.Create(Page);
RadioButton2.Left := ScaleX(80);
RadioButton2.Top := RadioButton1.Top + ScaleY(60);
RadioButton2.Width := Page.SurfaceWidth;
RadioButton2.Height := ScaleY(17);
RadioButton2.Caption := '分機版安裝(不安裝數據庫)';
RadioButton2.Checked := false;
RadioButton2.Parent := Page.Surface;
Lbl2 := TNewStaticText.Create(Page);
Lbl2.Left := ScaleX(95);
Lbl2.Top := Lbl1.Top + ScaleY(60);
Lbl2.Width := ScaleX(250);
Lbl2.Height := ScaleY(50);
Lbl2.Caption := '不安裝SQLServer數據庫';
Lbl2.Parent := Page.Surface;
freespacelabel:= TLabel.Create(Page);
end;
//////////////////////////////////////
procedure InitializeWizard();讀取C、D盤的剩餘容量參考這位大兄弟http://download.csdn.net/detail/fangfeimeng/4855769
begin
CreateAddonPage;
////////////////
if GetSpaceOnDisk(ExtractFileDrive(WizardDirValue),True,FreeSpace,TotalSpace)then
begin
WizardForm.DirEdit.OnChange:=@ShowFreeSpaceOnDisc;
WizardForm.ComponentsDiskSpaceLabel.Caption:=WizardForm.ComponentsDiskSpaceLabel.Caption+'磁盤可用空間'+IntToStr(FreeSpace)+'MB'
end;
end;
//////////////////////////////////////
function GetDirName(Value: string): string;
var
InstallPath: string;
begin
// initialize default path, which will be returned when the following registry
// key queries fail due to missing keys or for some different reason
//;軟件
InstallPath:= 'D:\軟件';
GetSpaceOnDisk(ExtractFileDrive('D:'),True,FreeSpace,TotalSpace);
// query the first registry value; if this succeeds, return the obtained value
if FreeSpace<1000 then
begin
InstallPath:= 'C:\軟件'
end
// otherwise the first registry key query failed, so...
Result:=InstallPath;
end;
/////////////////////////////////////
function InitializeSetup: Boolean;檢測.Net2.0,網上很多大兄弟都知道
var
ResultCode: Integer;
begin
if RegKeyExists(HKLM, 'SOFTWARE\Microsoft\.NETFramework\policy\v2.0') then
begin
Result := true;
end
else
begin
if MsgBox('系統檢測到您沒有安裝.Net Framework2.0,是否立刻安裝?', mbConfirmation, MB_YESNO) = idYes then
begin
ExtractTemporaryFile('dotnetfx20.exe')
if not Exec(ExpandConstant('{tmp}\dotnetfx20.exe'),'','',SW_SHOWNORMAL,ewWaitUntilTerminated,ResultCode)then
begin
MsgBox('.NetFramework2.0.exe Install Error!'#13#13''+SysErrorMessage(ResultCode)+'.',mbError,MB_OK);
Result :=true;
end
Result:=true;
end
else
begin
MsgBox('缺少.Net Framework2.0環境,無法運行SQL程序,本安裝程序即將退出!',mbInformation,MB_OK);
Result := false;
end
end
end;
//檢測.netfx2.0環境並強制安裝///////////////////////////////////////////連最基本的.Net2.0都沒有玩個蛋SQL2005
procedure CurStepChanged (CurStep: TSetupStep );
var ResultCode: Integer;
Pathsql:String;
Path:String;
begin
//Data
Path:=ExpandConstant('{app}')+'\Data';
Pathsql:=ExpandConstant('{app}')+'\Data\sqladd.sql';
if CurStep=ssInstall then
begin
if(RadioButton1.Checked)then
begin
if not RegValueExists(HKEY_LOCAL_MACHINE,'SYSTEM\CurrentControlSet\services\eventlog\Application\MSSQL$實例名','CategoryMessageFile')then //MSSQL$____爲實例名,我把兩個版本實例名都命名爲
begin
ExtractTemporaryFiles('{tmp}\*')
Exec(ExpandConstant('{tmp}\SQLEXPR_CHS\SQL靜默安裝批處理.bat'),'','',SW_SHOWNORMAL,ewWaitUntilTerminated,ResultCode)
end
else
MsgBox('本地已存在SQL Server Express',mbError,MB_OK)
end
end;
if CurStep=ssPostInstall then附加數據庫,也是玄學,有時候1、2能附加;有時候3、4能附加;有時候1能附加,太神祕了。我不確定是由於系統權限還是CurrentDir參數,還是二者兼有
begin
Exec(ExpandConstant('{app}\Data\sqlcmd.exe'),' -S .\實例名 -U sa -P 密碼 -v CurrentDir="'+Path+'"'+' -i "'+Path+'\sqladd.sql"','',SW_SHOWNORMAL,ewWaitUntilTerminated,ResultCode)//在安裝完成後運行批處理和SQL安裝程序
Exec(ExpandConstant('{app}\Data\sqlcmd.exe'),' -S .\實例名 -U sa -P 密碼 -v CurrentDir="'+Path+'"'+' -i "'+Pathsql+'"','',SW_SHOWNORMAL,ewWaitUntilTerminated,ResultCode)//在安裝完成後運行批處理和SQL安裝程序
Exec(ExpandConstant('{app}\Data\sqlcmd.exe'),' -S .\實例名 -E -v CurrentDir="'+Path+'"'+' -i "'+Path+'\sqladd.sql"','',SW_SHOWNORMAL,ewWaitUntilTerminated,ResultCode)//在安裝完成後運行批處理和SQL安裝程序
Exec(ExpandConstant('{app}\Data\sqlcmd.exe'),' -S .\實例名 -E -v CurrentDir="'+Path+'"'+' -i "'+Pathsql+'"','',SW_SHOWNORMAL,ewWaitUntilTerminated,ResultCode)//在安裝完成後運行批處理和SQL安裝程序
end ;
[Icons]
;//安裝
Name: "{group}\{#MyAppName}"; Filename: "{app}\安裝\{#MyAppExeName}"
Name: "{userdesktop}\{#MyAppName}" ;Filename:"{app}\安裝\{#MyAppExeName}";WorkingDir:"{app}\安裝";Comment:"快捷方式"
Name: "{userdesktop}\AutoUpdater" ;Filename:"{app}\安裝\AutoUpdater.exe";WorkingDir:"{app}\安裝";Comment:"快捷方式"
[Run]
我只是做了一點微小的工作。