Java 如何在inno安装程序中静默安装mysql?

Java 如何在inno安装程序中静默安装mysql?,java,mysql,inno-setup,Java,Mysql,Inno Setup,我将为我的java应用程序创建一个安装程序。它使用mysql数据库,因此我的程序的安装必须包括mysql server 5.5的安装、服务器的配置和数据库的加载。我使用Inno设置来执行此操作,但我发现了一些问题。我找到了这个代码,但它有点旧 Filename: msiexec; Parameters: "/i mysql-5.5.11-win32.msi /qn INSTALLDIR=""C:\mysql"""; WorkingDir: C:\Users\Gabriele\Desktop\se

我将为我的java应用程序创建一个安装程序。它使用mysql数据库,因此我的程序的安装必须包括mysql server 5.5的安装、服务器的配置和数据库的加载。我使用Inno设置来执行此操作,但我发现了一些问题。我找到了这个代码,但它有点旧

Filename: msiexec; Parameters: "/i mysql-5.5.11-win32.msi /qn INSTALLDIR=""C:\mysql"""; WorkingDir: C:\Users\Gabriele\Desktop\setup; StatusMsg: Sto installando Mysql 5.5.11;  Flags: runhidden

Filename: C:\mysql\bin\mysqld-nt.exe; Parameters: --install; WorkingDir: C:\mysql\bin; StatusMsg: Sto installando il Servizio MySQL; Description: Installing MySQL Service; Flags: runhidden

Filename: net.exe; Parameters: start mysql; StatusMsg: Sto Avviando il Servizio MySQL; Description: Avvio Servizio MySQL; Flags: runhidden


Filename: C:\mysql\bin\mysql.exe; Parameters: "-e ""insert into mysql.user(host,user,password) values ('localhost','root', PASSWORD('emmaus');"" -u root"; WorkingDir: {tmp}; StatusMsg: Configurazione del Server della Base di Dati; Flags: runhidden

Filename: C:\mysql\bin\mysql.exe; Parameters: "-u root -h localhost -e ""create database ata";

Filename: C:\mysql\bin\mysql.exe; Parameters: "-e ""grant all privileges on ata.* to ata;"" -u root"; WorkingDir: {tmp}; StatusMsg: Configurazione Server Base di Dati; Flags: runhidden


Filename: C:\mysql\bin\mysql.exe; Parameters: "-e ""flush privileges;"" -u root"; WorkingDir: {tmp}; StatusMsg: Configurazione Server Base di Dati; Flags: runhidden


Filename: C:\mysql\bin\mysql.exe; Parameters: "-u root -h localhost -e ""use ata; source ata.sql;"; WorkingDir: {tmp}; StatusMsg: Caricamento base di dati; Flags: runhidden  
当我调试时,它会在第一条语句之后生成一个错误。在第二条指令中找不到指定的程序。我尝试使用mysqld而不是mysqld-nt,但没有任何改变


有人能帮我吗???

我把我的mysql安装版本留在这里,使用inno安装程序,您可以使用customPage自定义5.6版的端口和服务名称。我没有在其他版本中尝试过。多亏了其他方面的贡献,才找到了这个解决方案

[Files]
Source: "J:\mysql-5.5.11-win32.msi"; DestDir: "{tmp}"; Flags: nocompression dontcopy

[Run]
Filename: "{reg:HKLM\SOFTWARE\MySQL AB\MySQL Server 5.5,Location}\bin\mysqld.exe"; 
  Parameters: "--install"; WorkingDir: "{reg:HKLM\SOFTWARE\MySQL AB\MySQL Server 5.5,Location}\bin"; 
  StatusMsg: "Sto installando il Servizio MySQL"; 
  Description: "Installing MySQL Service"; 
  Flags: runhidden; Check: MySQL_Is
;//and the rest of commands

[Code]
function MySQL_Is(): Boolean;
var
iResultCode: Integer;
begin
  Result := true;
  if (not RegKeyExists(HKLM, 'SOFTWARE\MySQL AB\MySQL Server 5.5')) or 
   (not FileExists(ExpandConstant('{reg:HKLM\SOFTWARE\MySQL AB\MySQL Server 5.5,Location}\bin\mysql.exe'))) 
  then begin
     ExtractTemporaryFile('mysql-5.5.11-win32.msi');
     Exec('msiexec.exe', '/i mysql-5.5.11-win32.msi /qn INSTALLDIR="C:\mysql"', 
      ExpandConstant('{tmp}'), SW_HIDE, ewWaitUntilTerminated, iResultCode);
         if not FileExists(ExpandConstant('{reg:HKLM\SOFTWARE\MySQL AB\MySQL Server 5.5,Location}\bin\mysql.exe')) then begin
            MsgBox('Something went wrong! Installation should be terminated', 
              mbInformation, MB_OK);
            Result := false;
         end;
  end;
end;
[Registry]


Root: HKLM; Subkey: "SOFTWARE\MySoftware\G2Database"; ValueType: string; ValueName: Port; ValueData: {code:GetPort}; Flags: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue
Root: HKLM; Subkey: "SOFTWARE\MySoftware\G2Database"; ValueType: string; ValueName: ServiceName; ValueData: {code:GetServiceName}; Flags: createvalueifdoesntexist uninsdeletekeyifempty uninsdeletevalue

We create 2 registers to save the data of Port and service name

[文件]
来源:“{#InstallersDir}MysqlServer\server_5631_win32.msi”;DestDir:“{tmp}”;标志:ignoreversion nocompression;任务:Mysql
来源:“{#InstallersDir}MysqlServer\script.txt”;DestDir:“{app}\mysql\bin”;标志:ignoreversion nocompression;任务:Mysql
来源:“{#InstallersDir}MysqlServer\users.bat”;DestDir:“{app}\mysql\bin”;标志:ignoreversion nocompression;任务:Mysql
[守则]
变量
lblPort:TLabel;
lblServiceName:TLabel;
报告:TEdit;
电子服务名称:TEdit;
程序frmDBSettingsReg_激活(第页:TWizardPage);
开始
结束;
函数frmDBSettingsReg_应跳过页面(页面:TWizardPage):布尔值;
开始
结果:=假;
结束;
函数frmDBSettingsReg_BackButtonClick(页面:TWizardPage):布尔值;
开始
结果:=真;
结束;
函数frmDBSettingsReg_NextButtonClick(第页:TWizardPage):布尔值;
开始
结果:=真;
结束;
程序frmDBSettingsReg_CancelButton单击(页面:TWizardPage;变量取消,确认:布尔值);
开始
结束;
函数frmDBSettingsReg_CreatePage(PreviousPageId:Integer):整数;
变量
页面:TWizardPage;
开始
页面:=创建自定义页面(
前页ID,
ExpandConstant({cm:AdvancedSettings}'),
ExpandConstant(“{cm:AdvancedDescription}”)
);
{lblPort}
lblPort:=TLabel.Create(第页);
用lblPort做
开始
父项:=页面表面;
左:=ScaleX(24);
顶部:=ScaleY(30);
宽度:=ScaleX(35);
高度:=ScaleY(13);
标题:=ExpandConstant({cm:Port}');
结束;
{lblServiceName}
lblServiceName:=TLabel.Create(第页);
使用lblServiceName do
开始
父项:=页面表面;
左:=ScaleX(24);
顶部:=ScaleY(60);
宽度:=ScaleX(52);
高度:=ScaleY(13);
标题:=ExpandConstant({cm:ServiceName}');
结束;
{ePort}
ePort:=TEdit.Create(第页);
用ePort do
开始
父项:=页面表面;
左:=ScaleX(130);
顶部:=ScaleY(27);
宽度:=ScaleX(185);
高度:=ScaleY(21);
正文:='3306';
TabOrder:=0;
结束;
{eServiceName}
eServiceName:=TEdit.Create(第页);
使用电子服务名称do
开始
父项:=页面表面;
左:=ScaleX(130);
顶部:=ScaleY(56);
宽度:=ScaleX(185);
高度:=ScaleY(21);
文本:='G2Database';
TabOrder:=1;
结束;
用Page do
开始
OnActivate:=@frmDBSettingsReg_激活;
OnShouldSkipPage:=@frmDBSettingsReg_ShouldSkipPage;
OnBackButtonClick:=@frmDBSettingsReg_BackButtonClick;
OnNextButtonClick:=@frmDBSettingsReg_NextButtonClick;
OnCancelButtonClick:=@frmDBSettingsReg\u CancelButtonClick;
结束;
结果:=Page.ID;
结束;
函数GetPort(param:String):String;
开始
结果:=修剪(ePort.Text);
结束;
函数GetServiceName(参数:String):String;
开始
结果:=Trim(eServiceName.Text);
结束;
```
我们创建一个新的CustomPage,让用户设置端口和Servicename
{cm:X}意味着CustomMessage只需放入您自己的文本并删除ExpandConstant
在我的例子中,我想跳过MySQL配置,以防您没有标记任务
```
函数ShouldSkipPage(curPageId:Integer):布尔值;
开始
如果curPageID为100,则//需要检查您的情况中的ID是否相同
结果:=假
否则如果选择了((curPageID=100)而不是WizardIsTaskSelected('Mysql'),则
结果:=真
结束;
[运行]
;安装MySQL
文件名:msiexec.exe;参数:“/i”“{tmp}\server\u 5631\u win32.msi”“/qn INSTALLDIR=”“YOUR RUTE”“DATADIR=”“YOUR RUTE”“PORT=”“{code:GetPort}”“;工作目录:{app};StatusMsg:“{cm:waitDatabase}”;旗帜:runhidden;任务:Mysql
;安装服务
文件名:您的RUTE\mysqld.exe;参数:“--install{code:GetServiceName}--port=”“{code:GetPort}”“;工作目录:{app};旗帜:runhidden;任务:Mysql
;启动服务
文件名:net.exe;参数:start{code:GetServiceName};工作目录:{app};StatusMsg:{cm:startDatabase};旗帜:runhidden;任务:Mysql
;打开防火墙端口
文件名:netsh;参数:防火墙添加端口打开TCP{code:GetPort}{code:GetServiceName};旗帜:runhidden;StatusMsg:{cm:configureDatabase};任务:Mysql
;创建自定义用户
文件名:{app}\mysql\bin\users.bat;参数:“{code:MySQLPath}{code:FormatRute}{code:GetPort}”;StatusMsg:{cm:configureDatabase};旗帜:runhidden;任务:Mysql
```
下面是Script.txt和Users.bat以及它们的辅助函数
```
Script.txt
使用mysql;
更新user set password=password(“root”),其中user='root';
创建由“myUser”标识的用户“myUser”@“%”;
授予**上的所有特权“我的用户”@“%”;
创建由“myUser”标识的用户“myUser”@“localhost”;
授予**上的所有特权到“myUser”@“localhost”;
同花顺特权;
用户.bat
::移动到mysql目录
cd%1
::使用用户根端口启动会话并执行脚本
调用“mysql.exe”-u root-P%3<%2/script.txt
//所有这些函数都将在代码部分执行
函数MySQLPath(Param:String):String;
变量
路径:字符串;
开始
路径:=ExpandConstant('{pf}\MySQL\MySQLServer5.6\bin');
结果:=FileSearch('mysqld.exe',Path);
StringChangeEx(结果'mysqld.exe','',True);
结果:='“'+结果+'”;
结束;
函数FormatRute(参数:String):String;
开始
结果:=ExpandConstant('{app}\mysql\bin');
结果:='“'+结果+'”
结束;

您似乎没有在第一行中显示
waituntiltermined
标志。第二行是在第一个进程之后,但在第一个进程结束之前的进程
[FILES]
Source: "{#InstallersDir}MysqlServer\server_5631_win32.msi"; DestDir: "{tmp}"; Flags: ignoreversion nocompression; Tasks: Mysql
Source: "{#InstallersDir}MysqlServer\script.txt"; DestDir: "{app}\mysql\bin"; Flags: ignoreversion nocompression ; Tasks: Mysql
Source: "{#InstallersDir}MysqlServer\users.bat"; DestDir: "{app}\mysql\bin"; Flags: ignoreversion nocompression ; Tasks: Mysql


[CODE]

var

lblPort: TLabel;
lblServiceName: TLabel;
ePort: TEdit;
eServiceName: TEdit;

procedure frmDBSettingsReg_Activate(Page: TWizardPage);
begin
end;

function frmDBSettingsReg_ShouldSkipPage(Page: TWizardPage): Boolean;
begin
Result := False;
end;

function frmDBSettingsReg_BackButtonClick(Page: TWizardPage): Boolean;
begin
Result := True;
end;

function frmDBSettingsReg_NextButtonClick(Page: TWizardPage): Boolean;
begin
Result := True;
end;

procedure frmDBSettingsReg_CancelButtonClick(Page: TWizardPage; var Cancel, Confirm: Boolean);
begin
end;

function frmDBSettingsReg_CreatePage(PreviousPageId: Integer): Integer;
var
Page: TWizardPage;
begin
Page := CreateCustomPage(
PreviousPageId,
ExpandConstant('{cm:AdvancedSettings}'),
ExpandConstant('{cm:AdvancedDescription}')
);

{ lblPort }
lblPort := TLabel.Create(Page);
with lblPort do
begin
Parent := Page.Surface;
Left := ScaleX(24);
Top := ScaleY(30);
Width := ScaleX(35);
Height := ScaleY(13);
Caption := ExpandConstant('{cm:Port}');
end;

{ lblServiceName }
lblServiceName := TLabel.Create(Page);
with lblServiceName do
begin
Parent := Page.Surface;
Left := ScaleX(24);
Top := ScaleY(60);
Width := ScaleX(52);
Height := ScaleY(13);
Caption := ExpandConstant('{cm:ServiceName}') ;
end;


{ ePort }
ePort := TEdit.Create(Page);
with ePort do
begin
Parent := Page.Surface;
Left := ScaleX(130);
Top := ScaleY(27);
Width := ScaleX(185);
Height := ScaleY(21);
Text := '3306';
TabOrder := 0;
end;

{ eServiceName }
eServiceName := TEdit.Create(Page);
with eServiceName do
begin
Parent := Page.Surface;
Left := ScaleX(130);
Top := ScaleY(56);
Width := ScaleX(185);
Height := ScaleY(21);
Text := 'G2Database';
TabOrder := 1;
end;



with Page do
begin
OnActivate := @frmDBSettingsReg_Activate;
OnShouldSkipPage := @frmDBSettingsReg_ShouldSkipPage;
OnBackButtonClick := @frmDBSettingsReg_BackButtonClick;
OnNextButtonClick := @frmDBSettingsReg_NextButtonClick;
OnCancelButtonClick := @frmDBSettingsReg_CancelButtonClick;
end;

Result := Page.ID;
end;

function GetPort(param: String): String;
begin
  Result := Trim(ePort.Text);
end;
function GetServiceName(param: String): String;
begin
  Result := Trim(eServiceName.Text);
end;

```
We create a new CustomPage to let user set Port and Servicename

{cm:X} means CustomMessage just has to put your own text and remove ExpandConstant 

In my case I wanted to skip the MySQL configuration in case you don't mark the task

```
function ShouldSkipPage(curPageId:Integer):Boolean;
begin
      if curPageID <> 100 then //Need to check if in your case is same ID
          Result := false
      else if ((curPageID = 100) and not WizardIsTaskSelected('Mysql')) then
          Result := true
end;


[RUN]

;Install MySQL
Filename: msiexec.exe; Parameters:"/i""{tmp}\server_5631_win32.msi"" /qn INSTALLDIR=""YOUR RUTE"" DATADIR=""YOUR RUTE"" PORT=""{code:GetPort}"" "; WorkingDir:{app}; StatusMsg:"{cm:waitDatabase}"; Flags: runhidden; Tasks: Mysql
;Install Service
Filename: YOUR RUTE\mysqld.exe; Parameters:"--install {code:GetServiceName} --port=""{code:GetPort}"""; WorkingDir:{app}; Flags: runhidden; Tasks: Mysql
;Start Service
Filename: net.exe;  Parameters: start {code:GetServiceName}; WorkingDir:{app}; StatusMsg:{cm:startDatabase}; Flags: runhidden; Tasks: Mysql
;Open Firewall Port
Filename: netsh; Parameters: firewall add portopening TCP {code:GetPort} {code:GetServiceName};  Flags: runhidden; StatusMsg:{cm:configureDatabase}; Tasks: Mysql
;Create Custom users
 Filename: {app}\mysql\bin\users.bat; Parameters:" {code:MySQLPath} {code:FormatRute} {code:GetPort}"; StatusMsg:{cm:configureDatabase};Flags: runhidden;Tasks: Mysql

```
Here comes Script.txt and Users.bat and Aux Functions for them

```
Script.txt

use mysql;
update user set password=PASSWORD("root") where user='root';
CREATE USER 'myUser'@'%' IDENTIFIED BY 'myUser';
GRANT ALL PRIVILEGES ON * . * TO 'myUser'@'%';
CREATE USER 'myUser'@'localhost' IDENTIFIED BY 'myUser';
GRANT ALL PRIVILEGES ON * . * TO 'myUser'@'localhost';
FLUSH PRIVILEGES;

Users.bat

:: Move to mysql dir
cd %1

:: Start session with user root -Port and execute script
call "mysql.exe" -u root -P %3 < %2/script.txt

//All this functions will go at CODE section
function MySQLPath(Param:String):String;
var
  Path: string; 
begin

  Path := ExpandConstant('{pf}\MySQL\MySQLServer5.6\bin');
  Result :=  FileSearch ('mysqld.exe',Path );
  StringChangeEx(Result, 'mysqld.exe', '', True);
  Result :=  '"' + Result + '"';

end;

function FormatRute(Param:String):String;
begin

  Result := ExpandConstant('{app}\mysql\bin');
  Result :=  '"' + Result + '"'

end;