如何在 Inno Setup 中使用数据库制作 .NET 应用程序的安装文件?

发布于 2024-11-26 16:24:16 字数 423 浏览 1 评论 0原文

我找不到任何例子,所以我不确定这是否可能。我想做的是:

我想安装带有数据库的.NET C# windows 服务。所以我的要求是客户端计算机上安装 .NET Framework 和 SQL Server 2008。

因此,它必须看起来像这样:

  1. 检查是否有 .NET Framework 4.0 和 SQL Server 2008
  2. 如果找不到 SQL Server - 则要求客户端选择路径或离开。
  3. 最终安装 .NET Framework 4.0
  4. 登录 SQL Server,并(从脚本)创建表、过程等。
  5. 从 cmd 行安装 wnd 服务。在这一点上,我还必须在我的 app.config 中设置连接字符串 - 这可能吗?)

我想在 Inno 设置中执行此操作。这可能吗?

I can't find any example, so I'm not sure if that is possible. What I want to do is:

I want to install .NET C# windows service with database. So my requirements will be .NET Framework and SQL Server 2008 on the clients machine.

So, it has to look like that:

  1. check if there is .NET Framework 4.0 and SQL Server 2008
  2. If cant find SQL Server - than ask client to choose the path or leave.
  3. Eventually install .NET Framework 4.0
  4. Log into SQL Server, and (from script) create tables, procs etc..
  5. Install wnd service from cmd line. In this point I also have to setup the connectionstring in my app.config - is that possible?)

I want to do that in Inno setup. Is that possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

断舍离 2024-12-03 16:24:16

好吧,我可以帮助解决 1 和 3 问题。

要检查 .NET 框架,您可以使用以下方法(如果需要,该方法还将安装 .NET 框架)。我目前使用它来检查 .NET 2.0,但您只需更改它查找的版本即可检查 4.0。

[Files]
Source: Files\dotnetfx.exe; DestDir: {tmp}; Flags: ignoreversion; Check: NeedsFramework

[Run]
Filename: {tmp}\dotnetfx.exe; Parameters: "/q:a /c:""install /l /q"""; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: Installing .NET Framework if needed. This may take several minutes.

[Code]

// .NET install helpers

// Indicates whether .NET Framework 2.0 is installed.
function IsDotNET20Detected(): boolean;
var
    success: boolean;
    install: cardinal;
begin
    success := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'Install', install);
    Result := success and (install = 1);
end;

//RETURNS OPPOSITE OF IsDotNet20Detected FUNCTION
//Remember this method from the Files section above
function NeedsFramework(): Boolean;
begin
  Result := (IsDotNET20Detected = false);
end;

//IF SETUP FINISHES WITH EXIT CODE OF 0, MEANING ALL WENT WELL
//THEN CHECK FOR THE PRESENCE OF THE REGISTRY FLAG TO INDICATE THE
//.NET FRAMEWORK WAS INSTALLED CORRECTLY
//IT CAN FAIL WHEN CUST DOESN'T HAVE CORRECT WINDOWS INSTALLER VERSION
function GetCustomSetupExitCode(): Integer;
begin
  if (IsDotNET20Detected = false) then
    begin
      MsgBox('.NET Framework was NOT installed successfully!',mbError, MB_OK);
      result := -1
    end
end;

请注意,此解决方案源自 本文。您可以从 microsoft 网站下载 .NET 4.0 的 dotnetfx。

至于步骤 4,我建议您创建一个安装在用户计算机上的工具/脚本,然后根据需要从“运行”部分调用它。

第 2 步会很棘手,但显然并非不可能。经过一番阅读后,您似乎可以将自定义 UI 页面添加到 InnoSetup。有关方法,请参阅此处的帮助。我不确定您在实际的 UI 页面中可以做多少工作。

值得注意的是,在 InnoSetup 中使用 Pascal 脚本,您或多或少可以完全访问 Win32 函数,并且能够实例化 COM 对象,这可能是公开 COM 接口的 .NET 库......?

Well, I can help with 1 and 3.

To check for the .NET framework, you can use the following method (which will also install the .NET framework, if needed). I currently use it to check for .NET 2.0, but you can just change the version it looks for to check for 4.0.

[Files]
Source: Files\dotnetfx.exe; DestDir: {tmp}; Flags: ignoreversion; Check: NeedsFramework

[Run]
Filename: {tmp}\dotnetfx.exe; Parameters: "/q:a /c:""install /l /q"""; WorkingDir: {tmp}; Flags: skipifdoesntexist; StatusMsg: Installing .NET Framework if needed. This may take several minutes.

[Code]

// .NET install helpers

// Indicates whether .NET Framework 2.0 is installed.
function IsDotNET20Detected(): boolean;
var
    success: boolean;
    install: cardinal;
begin
    success := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v2.0.50727', 'Install', install);
    Result := success and (install = 1);
end;

//RETURNS OPPOSITE OF IsDotNet20Detected FUNCTION
//Remember this method from the Files section above
function NeedsFramework(): Boolean;
begin
  Result := (IsDotNET20Detected = false);
end;

//IF SETUP FINISHES WITH EXIT CODE OF 0, MEANING ALL WENT WELL
//THEN CHECK FOR THE PRESENCE OF THE REGISTRY FLAG TO INDICATE THE
//.NET FRAMEWORK WAS INSTALLED CORRECTLY
//IT CAN FAIL WHEN CUST DOESN'T HAVE CORRECT WINDOWS INSTALLER VERSION
function GetCustomSetupExitCode(): Integer;
begin
  if (IsDotNET20Detected = false) then
    begin
      MsgBox('.NET Framework was NOT installed successfully!',mbError, MB_OK);
      result := -1
    end
end;

Note that this solution was derived from this article. You can download dotnetfx for .NET 4.0 from the microsoft website.

As for step 4, I would suggest that you create a tool/script which gets installed on the user's machine, which you then call from the Run section as needed.

Step 2 is going to be tricky, but apparently not impossible. After some reading it appears as though you can add custom UI pages to InnoSetup. See the help here for the method. How much work you can do in the actual UI page I'm not sure.

It's worth noting that using the Pascal scripting in InnoSetup you more or less have complete access to Win32 functions, plus the ability to instantiate COM objects, which could conceivably be .NET librarys exposing a COM interface....?

逆蝶 2024-12-03 16:24:16

Inno 安装程序将所有安装文件合并并压缩为单个可执行文件。当您运行此可执行文件时,它会提取您包含在 inno setup 中的所有文件。我认为它不会自动运行您在 setup.exe 中包含的可执行文件。

或者,您也可以使用 wix 创建设置。 Wix 安装程序也可以针对 .net Framework 4.0 构建。

Inno setup clubs all setup files and compressed into a single executable. when you run this executable it extract all the file which you have included in inno setup. I don't think it automatically run the executables which you have included in your setup.exe.

Alternatively you can also create the setup using wix. Wix setup can be build for .net framework 4.0 as well.

深海夜未眠 2024-12-03 16:24:16

这是我使用命令行 oracle sqlplus 执行 sql 脚本的示例代码
1. 示例代码

[Dirs]
; Create folders at user side 
Name: {app}\ScriptLog;

[Code]
///////////////////////////////////////////////////////////
//// Modify Sql function 
//// TagName: the script line you want to modify tag name, 
//// OldString: the old string, 
//// NewString: the new string, 
//// StringArr: the script strings array 
///////////////////////////////////////////////////////////
function ModifySql(var TagStr, OldStr, NewStr: String; const StringArr: array of String): Boolean;
var 
  batPath: String;
  tmpStr: String;
  ResultCode: Integer;
  i: Integer; 

begin
  result := false;

  for i:= 0 to GetArrayLength(StringArr)-1 do
    // if TagStr and OldStr are in the same line
    if ( (StringArr[i] <> '') and (Pos(TagStr, StringArr[i]) > 0) and (Pos(OldStr, StringArr[i]) > 0) ) then
      //replace OldStr with NewStr
      StringChange(StringArr[i], OldStr, NewStr);
end;

///////////////////////////////////////////////////////////
//// Search ORA- Error function 
//// the script exec result, for example : Error or ORA-xxxxx
///////////////////////////////////////////////////////////
function Check_Exec_Script_Result(var ErrStr, LogFile: String): Boolean;
var
  LogFileLines: TArrayOfString;
  ResultCode: Integer;
  i: Integer; 

begin
  //assign sql file 
  //load strings and store to SqlFileLines 
  LoadStringsFromFile(LogFile, LogFileLines); 
  result := false;

  for i:= 0 to GetArrayLength(LogFileLines)-1 do 
    // if TagStr and OldStr are in the same line
    if ( (LogFileLines[i] <> '') and (Pos(ErrStr, LogFileLines[i]) > 0) ) then
      MsgBox('Err' + LogFileLines[i] , mbError, MB_OK);

end;


///////////////////////////////////////////////////////////
//// execute Script with Sqlplus
///////////////////////////////////////////////////////////
procedure Exec_Script_Sqlplus(var dbTns, dbUser, dbPwd, scriptPath, batFileName: String);
var 
  batPath: String;
  tmpStr: String;
  ResultCode: Integer;
  LogFileName: String;
  ErrStr: String;

begin

  // generate bat file
  batPath := ExpandConstant('{tmp}\' + batFileName + '.bat');
  tmpStr := 'cd \' + ''#13''#10;
  SaveStringToFile(batPath, tmpStr, False);
  //tmpStr :=  'quit | sqlplus ' + dbUser + '/' + dbPwd + '@' + dbTns + ' @' + scriptPath + ''#13''#10;;
  tmpStr :=  'echo quit | sqlplus ' + dbUser + '/' + dbPwd + '@' + dbTns + ' @' +'"'+ scriptPath +'"'+ ''#13''#10;
  SaveStringToFile(batPath, tmpStr, True);

  // set log file path
  LogFileName := ExpandConstant('E:\123\' + batFileName + '.txt');

  //MsgBox(batPath, mbError, MB_OK);
  if Exec(batPath, ' > "' + LogFileName + '"', '', 1, ewWaitUntilTerminated, ResultCode) then
  begin
    // handle success if necessary; ResultCode contains the exit code
    if (ResultCode = 0) then begin
      ErrStr := 'ORA';
      Check_Exec_Script_Result(ErrStr, LogFileName);
      // open ScriptLog file
      ShellExec('', ExpandConstant(LogFileName),'', '', SW_SHOW, ewNoWait, ErrorCode)

      //MsgBox('OK', mbError, MB_OK);
      //result := true;
    end;
  end
  else begin
      MsgBox('Exec:' + scriptPath + 'fail,please check parameters setting', mbError, MB_OK);
      //handle failure if necessary; ResultCode contains the error code
  end;

end;

///////////////////////////////////////////////////////////
//// 1. Set Sql Script Parameters ,ex: DB TNS,Account,PWD
//// 2. Call function ModifySql, to modify Sql Script 
//// 3. Call function Exec_Script_Sqlplus, to exec Sql Script with sqlplus
///////////////////////////////////////////////////////////
procedure SetSql_ExecSqlScript();
var
  SqlFile: String; 
  OldString: String; 
  NewString: String;
  TagName: String;
  batFileName: String;
  SqlFileLines: TArrayOfString;

  LocalInfoPath: String;
  LocalInfoLines: TArrayOfString;
  LocalInfoStr: String;
  i: Integer;

begin

  //assign sql file 
  //========================start of 1_Sample_system.sql========================
  SqlFile := WizardDirValue() + '\SQL\1_Sample_system.sql';
  //create bat file
  batFileName :=  '1_Sample_system';
  //load strings and store to SqlFileLines 
  LoadStringsFromFile(SqlFile, SqlFileLines); 

  //set modify parameters
  TagName := 'CREATE USER';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'GRANT CREATE';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'GRANT CONNECT';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'ALTER USER';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'IDENTIFIED';
  OldString := '1234abcd';
  NewString := DBAppPwd;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  //save modified strings to file
  SaveStringsToFile(SqlFile, SqlFileLines, False);

  //Exec Script with Sqlplus
  Exec_Script_Sqlplus(DBSystemTNS, DBSystemUser, DBSystemPwd, SqlFile , batFileName);
  //========================end of 1_Sample_system.sql========================

  //========================start of 2_Sample_create_schema.sql========================
  SqlFile := WizardDirValue() + '\SQL\2_Sample_create_schema.sql';
  //create bat file
  batFileName :=  '2_Sample_create_schema';

  //Exec Script with Sqlplus
  Exec_Script_Sqlplus(DBAppTNS, DBAppUser, DBAppPwd, SqlFile , batFileName);
  //========================end of 2_Sample_create_schema.sql========================

  //========================start of 3_Sample_insert_data.sql========================
  SqlFile := WizardDirValue() + '\SQL\3_Sample_insert_data.sql'; 
  //create bat file
  batFileName :=  '3_Sample_insert_data';

  //Exec Script with Sqlplus
  Exec_Script_Sqlplus(DBAppTNS, DBAppUser, DBAppPwd, SqlFile , batFileName);
  //========================end of 3_Sample_insert_data.sql========================

 //========================start of 4_Sample_drop_schema.sql========================
  SqlFile := WizardDirValue() + '\SQL\4_Sample_drop_schema.sql'; 
  //create bat file
  batFileName :=  '4_Sample_drop_schema';

  //load strings form file        
  LoadStringsFromFile(SqlFile, SqlFileLines); 

  //set modify parameters
  TagName := 'DROP USER';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  //save modified strings to file
  SaveStringsToFile(SqlFile, SqlFileLines, False);

  //Exec Script with Sqlplus
  //Exec_Script_Sqlplus(DBSystemTNS, DBSystemUser, DBSystemPwd, SqlFile , batFileName);
  //========================end of 4_Sample_drop_schema.sql========================
end;

this is my sample code to exec sql script with commandline oracle sqlplus
1. sample code

[Dirs]
; Create folders at user side 
Name: {app}\ScriptLog;

[Code]
///////////////////////////////////////////////////////////
//// Modify Sql function 
//// TagName: the script line you want to modify tag name, 
//// OldString: the old string, 
//// NewString: the new string, 
//// StringArr: the script strings array 
///////////////////////////////////////////////////////////
function ModifySql(var TagStr, OldStr, NewStr: String; const StringArr: array of String): Boolean;
var 
  batPath: String;
  tmpStr: String;
  ResultCode: Integer;
  i: Integer; 

begin
  result := false;

  for i:= 0 to GetArrayLength(StringArr)-1 do
    // if TagStr and OldStr are in the same line
    if ( (StringArr[i] <> '') and (Pos(TagStr, StringArr[i]) > 0) and (Pos(OldStr, StringArr[i]) > 0) ) then
      //replace OldStr with NewStr
      StringChange(StringArr[i], OldStr, NewStr);
end;

///////////////////////////////////////////////////////////
//// Search ORA- Error function 
//// the script exec result, for example : Error or ORA-xxxxx
///////////////////////////////////////////////////////////
function Check_Exec_Script_Result(var ErrStr, LogFile: String): Boolean;
var
  LogFileLines: TArrayOfString;
  ResultCode: Integer;
  i: Integer; 

begin
  //assign sql file 
  //load strings and store to SqlFileLines 
  LoadStringsFromFile(LogFile, LogFileLines); 
  result := false;

  for i:= 0 to GetArrayLength(LogFileLines)-1 do 
    // if TagStr and OldStr are in the same line
    if ( (LogFileLines[i] <> '') and (Pos(ErrStr, LogFileLines[i]) > 0) ) then
      MsgBox('Err' + LogFileLines[i] , mbError, MB_OK);

end;


///////////////////////////////////////////////////////////
//// execute Script with Sqlplus
///////////////////////////////////////////////////////////
procedure Exec_Script_Sqlplus(var dbTns, dbUser, dbPwd, scriptPath, batFileName: String);
var 
  batPath: String;
  tmpStr: String;
  ResultCode: Integer;
  LogFileName: String;
  ErrStr: String;

begin

  // generate bat file
  batPath := ExpandConstant('{tmp}\' + batFileName + '.bat');
  tmpStr := 'cd \' + ''#13''#10;
  SaveStringToFile(batPath, tmpStr, False);
  //tmpStr :=  'quit | sqlplus ' + dbUser + '/' + dbPwd + '@' + dbTns + ' @' + scriptPath + ''#13''#10;;
  tmpStr :=  'echo quit | sqlplus ' + dbUser + '/' + dbPwd + '@' + dbTns + ' @' +'"'+ scriptPath +'"'+ ''#13''#10;
  SaveStringToFile(batPath, tmpStr, True);

  // set log file path
  LogFileName := ExpandConstant('E:\123\' + batFileName + '.txt');

  //MsgBox(batPath, mbError, MB_OK);
  if Exec(batPath, ' > "' + LogFileName + '"', '', 1, ewWaitUntilTerminated, ResultCode) then
  begin
    // handle success if necessary; ResultCode contains the exit code
    if (ResultCode = 0) then begin
      ErrStr := 'ORA';
      Check_Exec_Script_Result(ErrStr, LogFileName);
      // open ScriptLog file
      ShellExec('', ExpandConstant(LogFileName),'', '', SW_SHOW, ewNoWait, ErrorCode)

      //MsgBox('OK', mbError, MB_OK);
      //result := true;
    end;
  end
  else begin
      MsgBox('Exec:' + scriptPath + 'fail,please check parameters setting', mbError, MB_OK);
      //handle failure if necessary; ResultCode contains the error code
  end;

end;

///////////////////////////////////////////////////////////
//// 1. Set Sql Script Parameters ,ex: DB TNS,Account,PWD
//// 2. Call function ModifySql, to modify Sql Script 
//// 3. Call function Exec_Script_Sqlplus, to exec Sql Script with sqlplus
///////////////////////////////////////////////////////////
procedure SetSql_ExecSqlScript();
var
  SqlFile: String; 
  OldString: String; 
  NewString: String;
  TagName: String;
  batFileName: String;
  SqlFileLines: TArrayOfString;

  LocalInfoPath: String;
  LocalInfoLines: TArrayOfString;
  LocalInfoStr: String;
  i: Integer;

begin

  //assign sql file 
  //========================start of 1_Sample_system.sql========================
  SqlFile := WizardDirValue() + '\SQL\1_Sample_system.sql';
  //create bat file
  batFileName :=  '1_Sample_system';
  //load strings and store to SqlFileLines 
  LoadStringsFromFile(SqlFile, SqlFileLines); 

  //set modify parameters
  TagName := 'CREATE USER';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'GRANT CREATE';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'GRANT CONNECT';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'ALTER USER';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  TagName := 'IDENTIFIED';
  OldString := '1234abcd';
  NewString := DBAppPwd;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  //save modified strings to file
  SaveStringsToFile(SqlFile, SqlFileLines, False);

  //Exec Script with Sqlplus
  Exec_Script_Sqlplus(DBSystemTNS, DBSystemUser, DBSystemPwd, SqlFile , batFileName);
  //========================end of 1_Sample_system.sql========================

  //========================start of 2_Sample_create_schema.sql========================
  SqlFile := WizardDirValue() + '\SQL\2_Sample_create_schema.sql';
  //create bat file
  batFileName :=  '2_Sample_create_schema';

  //Exec Script with Sqlplus
  Exec_Script_Sqlplus(DBAppTNS, DBAppUser, DBAppPwd, SqlFile , batFileName);
  //========================end of 2_Sample_create_schema.sql========================

  //========================start of 3_Sample_insert_data.sql========================
  SqlFile := WizardDirValue() + '\SQL\3_Sample_insert_data.sql'; 
  //create bat file
  batFileName :=  '3_Sample_insert_data';

  //Exec Script with Sqlplus
  Exec_Script_Sqlplus(DBAppTNS, DBAppUser, DBAppPwd, SqlFile , batFileName);
  //========================end of 3_Sample_insert_data.sql========================

 //========================start of 4_Sample_drop_schema.sql========================
  SqlFile := WizardDirValue() + '\SQL\4_Sample_drop_schema.sql'; 
  //create bat file
  batFileName :=  '4_Sample_drop_schema';

  //load strings form file        
  LoadStringsFromFile(SqlFile, SqlFileLines); 

  //set modify parameters
  TagName := 'DROP USER';
  OldString := 'Sample';
  NewString := DBAppUser;
  ModifySql(TagName, OldString, NewString, SqlFileLines);

  //save modified strings to file
  SaveStringsToFile(SqlFile, SqlFileLines, False);

  //Exec Script with Sqlplus
  //Exec_Script_Sqlplus(DBSystemTNS, DBSystemUser, DBSystemPwd, SqlFile , batFileName);
  //========================end of 4_Sample_drop_schema.sql========================
end;
一世旳自豪 2024-12-03 16:24:16

这是我使用命令行 oracle sqlplus 2 执行 sql 脚本的示例代码

。有四个基本 sql 脚本

this is my sample code to exec sql script with commandline oracle sqlplus

2.there four basis sql script

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文