簡體   English   中英

Inno Setup IIS 安裝和配置

[英]Inno Setup IIS Installation and Configuration

我一直在嘗試弄清楚如何使用 Inno 安裝腳本安裝和注冊 IIS,但到目前為止我還沒有成功。

我需要使用 .Net 版本 4 和虛擬目錄創建一個應用程序、應用程序池,獲取機器的 IP 並繼續使用該 IP 編輯網站的綁定。

到目前為止,我安裝中的所有工作都是檢查是否安裝了 IIS。

如果有人以前做過這樣的事情,如果您能分享您的腳本,我將不勝感激。

謝謝你。

這是我使用 Inno Setup 處理 IIS(Internet 信息服務)的完整代碼。 它包含:

  • 安裝 .NET Framework 4
  • IIS+ASP.NET 4 安裝/卸載
  • 網站/應用程序的注冊和刪除
  • 獲取運行應用程序池的用戶帳戶的幫助程序
  • 幫助獲取網站的物理路徑

它已經過以下 Windows 版本的測試:XP Pro SP3 x86、2003 R2 x86、2003 R2 x64、Vista Ultimate x64、7 Home Premium x64、2008 R2 x64、2011 x64、8.1 Pro x86、10 Pro x64

一切都盡可能被動地完成,以免破壞任何現有的網站。

重要的

這可能需要 Inno-Setup 的Unicode 版本(我使用的是 5.5.6(u))。 還需要在 x64 機器上強制使用 64 位模式(否則注冊表和文件訪問將重定向到 32 位內容):

[Setup]
ArchitecturesInstallIn64BitMode=x64

需要幫手

#ifdef UNICODE
#define AW "W"
#else
#define AW "A"
#endif

const
  // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx
  ERROR_SUCCESS = 0;
  ERROR_INVALID_FUNCTION = 1;
  ERROR_NOT_SUPPORTED = 50;
  ERROR_NOT_FOUND = 1168;
  ERROR_SUCCESS_REBOOT_REQUIRED = 3010;

function ExpandEnvironmentStrings(lpSrc: String; lpDst: String; nSize: DWORD): DWORD;
  external 'ExpandEnvironmentStrings{#AW}@kernel32.dll stdcall';
function ExpandEnvVars(const Input: String): String;
var
  Buf: String;
  BufSize: DWORD;
begin
  BufSize := ExpandEnvironmentStrings(Input, #0, 0);
  if BufSize > 0 then
  begin
    SetLength(Buf, BufSize);
    if ExpandEnvironmentStrings(Input, Buf, BufSize) = 0 then
      RaiseException(Format('Expanding env. strings failed. %s', [SysErrorMessage(DLLGetLastError)]));
#if AW == "A"
    Result := Copy(Buf, 1, BufSize - 2);
#else
    Result := Copy(Buf, 1, BufSize - 1);
#endif
  end
  else
    RaiseException(Format('Expanding env. strings failed. %s', [SysErrorMessage(DLLGetLastError)]));
end;

// Exec with output stored in result. ResultString will only be altered if True is returned.
function ExecWithResult(const Filename, Params, WorkingDir: String; const ShowCmd: Integer; const Wait: TExecWait; var ResultCode: Integer; var ResultString: String): Boolean;
var
  TempFilename: String;
  TempAnsiStr: AnsiString;
  Command: String;
begin
  TempFilename := ExpandConstant('{tmp}\~execwithresult.txt');
  // Exec via cmd and redirect output to file. Must use special string-behavior to work.
  Command := Format('"%s" /S /C ""%s" %s > "%s""', [ExpandConstant('{cmd}'), Filename, Params, TempFilename]);
  Result := Exec(ExpandConstant('{cmd}'), Command, WorkingDir, ShowCmd, Wait, ResultCode);
  if not Result then
    Exit;
  LoadStringFromFile(TempFilename, TempAnsiStr);  // Cannot fail
  ResultString := String(TempAnsiStr);
  DeleteFile(TempFilename);
  // Remove new-line at the end
  if (Length(ResultString) >= 2) and (ResultString[Length(ResultString) - 1] = #13) and (ResultString[Length(ResultString)] = #10) then
    Delete(ResultString, Length(ResultString) - 1, 2);
end;

function IIs7ExecAppCmd(Params: String; var ResultString: String; var ResultCode: Integer): Boolean;
var
  AppCmdFilePath: String;
  Command: String;
begin
  AppCmdFilePath := ExpandConstant('{sys}\inetsrv\appcmd.exe');
  Result := ExecWithResult(AppCmdFilePath, Params, '', SW_HIDE, ewWaitUntilTerminated, ResultCode, ResultString);
end;

.NET 4 安裝

將為 Win XP/2003 安裝 .NET 4.0。 .NET 4.6 適用於 Vista/2008 及更高版本。 如果 .NET 4 已包含在系統中 (Win 8/2012/10),將不執行任何操作。 以下文件是必需的,並且必須包含在設置中:

-

[Files]
Source: "dotNetFx40_Full_setup.exe"; DestDir: "{tmp}"; Flags: ignoreversion dontcopy
Source: "NDP46-KB3045560-Web.exe"; DestDir: "{tmp}"; Flags: ignoreversion dontcopy
Source: "wic_x64_enu.exe"; DestDir: "{tmp}"; Flags: ignoreversion dontcopy
Source: "wic_x86_enu.exe"; DestDir: "{tmp}"; Flags: ignoreversion dontcopy

由於我使用的是 Web 安裝程序,因此在安裝過程中可能需要 Internet 連接。

// Checks if .NET 4 "Full" is installed
function IsDotNet4FullInstalled(): Boolean;
var
  Success: Boolean;
  Install: Cardinal;
begin
  try
    ExpandConstant('{dotnet40}');  // This will throw an exception if .NET 4 is not installed at all
    Success := RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Install', Install);  // Check for "Full" version
    Result := Success and (Install = 1);
  except
    Result := False;
  end;
end;

// Returns True if a restart is required.
function InstallDotNet4(): Boolean;
var
  Version: TWindowsVersion;
  ResultCode: Integer;
  Success: Boolean;
begin
  GetWindowsVersionEx(Version);
  if (Version.Major <= 5) then  // 4.0 for XP, 2003
    ExtractTemporaryFile('dotNetFx40_Full_setup.exe')
  else  // 4.6
    ExtractTemporaryFile('NDP46-KB3045560-Web.exe');
  if (Version.Major <= 5) then  // XP, 2003: Install .NET 4.0
  begin
    Success := Exec(ExpandConstant('{tmp}\dotNetFx40_Full_setup.exe'), '/passive', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
    if Success and (ResultCode = 5100) then  // Indicates that "Windows Imaging Component" is missing (probably 2003)
    begin
      if IsWin64 then
      begin
        ExtractTemporaryFile('wic_x64_enu.exe');
        if not Exec(ExpandConstant('{tmp}\wic_x64_enu.exe'), '/passive', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or (ResultCode <> ERROR_SUCCESS) then
          RaiseException('Failed to install "Windows Imaging Component": ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
        // Retry .NET
        Success := Exec(ExpandConstant('{tmp}\dotNetFx40_Full_setup.exe'), '/passive', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
      end
      else
      begin
        ExtractTemporaryFile('wic_x86_enu.exe');
        if not Exec(ExpandConstant('{tmp}\wic_x86_enu.exe'), '/passive', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or (ResultCode <> ERROR_SUCCESS) then
          RaiseException('Failed to install "Windows Imaging Component": ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
        // Retry .NET
        Success := Exec(ExpandConstant('{tmp}\dotNetFx40_Full_setup.exe'), '/passive', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
      end;
    end
  end
  else  // Vista / 2008 or later: Install .NET 4.6
    Success := Exec(ExpandConstant('{tmp}\NDP46-KB3045560-Web.exe'), '/passive', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  // Check for errors
  if not Success or ((ResultCode <> ERROR_SUCCESS) and (ResultCode <> ERROR_SUCCESS_REBOOT_REQUIRED)) then
    RaiseException('Failed to install .NET: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
  Result := ResultCode = ERROR_SUCCESS_REBOOT_REQUIRED;
end;

IIS 安裝/卸載

使用 ASP.NET 4 安裝 IIS。將激活與通過 GUI 激活相同的(默認)功能。 安裝完成后,ASP.NET 將(重新)注冊到 IIS。

注意:對於 Win XP/2003,需要“Windows 安裝光盤”。

// Returns True if a restart is required. Throws exceptions.
function InstallIIs(): Boolean;
var
  Version: TWindowsVersion;
  Success: Boolean;
  ResultCode: Integer;
  IIS56IniFile: String;
begin
  GetWindowsVersionEx(Version);
  if (Version.Major <= 5) then  // XP / 2003: Use "sysocmgr"
  begin
    IIS56IniFile := ExpandConstant('{tmp}\~iis56.ini');
    SaveStringToFile(IIS56IniFile, '[Components]' + #13#10 + 'iis_common = ON' + #13#10 + 'iis_www = ON' + #13#10 + 'iis_inetmgr = ON', False);
    Success := Exec('sysocmgr', ExpandConstant('/i:"{win}\inf\sysoc.inf" /u:"' + IIS56IniFile + '"'), '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
    DeleteFile(IIS56IniFile);
  end
  else if (Version.Major = 6) and (Version.Minor = 0) then  // Vista / 2008: Use "pkgmgr"
  begin
    Success := Exec('pkgmgr', '/iu:' +
      // Enables everything a fresh install would also (implicitly) enable.
      // This is important in case IIS was already installed and some features manually disabled.
      'WAS-WindowsActivationService;WAS-ProcessModel;WAS-NetFxEnvironment;WAS-ConfigurationAPI' +
      ';IIS-WebServerRole' +
      ';IIS-WebServerManagementTools;IIS-ManagementConsole' +
      ';IIS-WebServer' +
      ';IIS-ApplicationDevelopment;IIS-NetFxExtensibility;IIS-ASPNET;IIS-ISAPIExtensions;IIS-ISAPIFilter' +
      ';IIS-CommonHttpFeatures;IIS-HttpErrors;IIS-DefaultDocument;IIS-StaticContent;IIS-DirectoryBrowsing' +
      ';IIS-Performance;IIS-HttpCompressionStatic' +
      ';IIS-Security;IIS-RequestFiltering' +
      ';IIS-HealthAndDiagnostics;IIS-RequestMonitor;IIS-HttpLogging',
      '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end
  else if (Version.Major = 6) and (Version.Minor = 1) then  // 7 / 2008 R2 / 2011: Use "Dism"
  begin
    Success := Exec('Dism', '/Online /Enable-Feature' +
      // Enables everything a fresh install would also (implicitly) enable.
      // This is important in case IIS was already installed and some features manually disabled.
      // "Parent fetaures" are NOT automatically enabled by "Dism".
      ' /FeatureName:WAS-WindowsActivationService /FeatureName:WAS-ProcessModel /FeatureName:WAS-NetFxEnvironment /FeatureName:WAS-ConfigurationAPI' +
      ' /FeatureName:IIS-WebServerRole' +
      ' /FeatureName:IIS-WebServerManagementTools /FeatureName:IIS-ManagementConsole' +
      ' /FeatureName:IIS-WebServer' +
      ' /FeatureName:IIS-ApplicationDevelopment /FeatureName:IIS-NetFxExtensibility /FeatureName:IIS-ASPNET /FeatureName:IIS-ISAPIExtensions /FeatureName:IIS-ISAPIFilter' +
      ' /FeatureName:IIS-CommonHttpFeatures /FeatureName:IIS-HttpErrors /FeatureName:IIS-DefaultDocument /FeatureName:IIS-StaticContent /FeatureName:IIS-DirectoryBrowsing' +
      ' /FeatureName:IIS-Performance /FeatureName:IIS-HttpCompressionStatic' +
      ' /FeatureName:IIS-Security /FeatureName:IIS-RequestFiltering' +
      ' /FeatureName:IIS-HealthAndDiagnostics /FeatureName:IIS-RequestMonitor /FeatureName:IIS-HttpLogging',
      '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end
  else  // 8 / 2012 and later: Use "Dism"
  begin
    Success := Exec('Dism', '/Online /Enable-Feature' +
      // Enables everything a fresh install would also (implicitly) enable.
      // This is important in case IIS was already installed and some features manually disabled.
      ' /FeatureName:WAS-WindowsActivationService /FeatureName:WAS-ProcessModel /FeatureName:WAS-NetFxEnvironment /FeatureName:WAS-ConfigurationAPI' +
      ' /FeatureName:IIS-ManagementConsole' +
      ' /FeatureName:IIS-HttpErrors /FeatureName:IIS-DefaultDocument /FeatureName:IIS-StaticContent /FeatureName:IIS-DirectoryBrowsing' +
      ' /FeatureName:IIS-ASPNET45' +
      ' /FeatureName:IIS-HttpCompressionStatic' +
      ' /FeatureName:IIS-RequestFiltering' +
      ' /FeatureName:IIS-HttpLogging' +
      ' /All',  // Implicitly enables dependent features
      '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
  if not Success or ((ResultCode <> ERROR_SUCCESS) and (ResultCode <> ERROR_SUCCESS_REBOOT_REQUIRED)) then
    RaiseException('Cannot install IIS: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
  Result := ResultCode = ERROR_SUCCESS_REBOOT_REQUIRED;
  // Register ASP.NET 4 with IIS. This is required since .NET 4 was probably installed before IIS.
  // This will NOT change existing web-sites (which might be using other ASP.NET versions already)
  if not Exec(ExpandConstant('{dotnet40}') + '\aspnet_regiis.exe', '-iru -enable', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or
    (ResultCode <> ERROR_SUCCESS) then
    RaiseException('Cannot register ASP.NET: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
end;

// Returns True if a restart is required. Throws exceptions.
function UninstallIIs(): Boolean;
var
  Version: TWindowsVersion;
  Success: Boolean;
  ResultCode: Integer;
  IIS56IniFile: String;
begin
  GetWindowsVersionEx(Version);
  if (Version.Major <= 5) then  // XP / 2003: Use "sysocmgr"
  begin
    IIS56IniFile := ExpandConstant('{tmp}\~iis56.ini');
    SaveStringToFile(IIS56IniFile, '[Components]' + #13#10 + 'iis_common = OFF' + #13#10 + 'iis_www = OFF' + #13#10 + 'iis_inetmgr = OFF', False);
    Success := Exec('sysocmgr', ExpandConstant('/i:"{win}\inf\sysoc.inf" /u:"' + IIS56IniFile + '"'), '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
    DeleteFile(IIS56IniFile);
  end
  else if (Version.Major = 6) and (Version.Minor = 0) then  // Vista / 2008: Use "pkgmgr"
    Success := Exec('pkgmgr', '/norestart /uu:IIS-WebServerRole', '', SW_HIDE, ewWaitUntilTerminated, ResultCode)
  else  // 7 / 2008 R2 and later: Use "Dism"
    Success := Exec('Dism', '/NoRestart /Online /Disable-Feature /FeatureName:IIS-WebServerRole', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  if not Success or ((ResultCode <> ERROR_SUCCESS) and (ResultCode <> ERROR_SUCCESS_REBOOT_REQUIRED)) then
    RaiseException('Cannot uninstall IIS: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
  Result := ResultCode = ERROR_SUCCESS_REBOOT_REQUIRED;
end;

網站/應用程序注冊和刪除

創建虛擬目錄和 ASP.NET 4 應用程序池。

注意:IIsServerNumber 是實際的網站,通常默認為 1(=>“默認網站”)。

用法:

RegisterAppAtIIs('MyAppName', 1, 'MyAppAppPoolName');
DeleteAppFromIIs('MyAppName', 1, 'MyAppAppPoolName');
// Throws exceptions.
procedure RegisterAppAtIIs(const IIsAppName: String; const IIsServerNumber: Integer; const IIsApplicationPoolName: String);
var
  Version: TWindowsVersion;
  // IIS 5.1 - 6.0
  IIS, WebService, WebSite, WebRoot, vDir, AppPools, AppPool: Variant;
  // IIS 7 and later
  ResultCode: Integer;
  ExecResult: String;
  WebSiteName: String;
begin
  GetWindowsVersionEx(Version);
  if (Version.Major = 5) and (Version.Minor <= 2) then  // XP, 2003: IIS 5.1 - 6.0
  begin
    try
      // Create the main IIS COM Automation object
      IIS := CreateOleObject('IISNamespace');
      WebService := IIS.GetObject('IIsWebService', 'localhost/W3SVC');
      // Get web site
      WebSite := WebService.GetObject('IIsWebServer', IntToStr(IIsServerNumber));
      WebRoot := WebSite.GetObject('IIsWebVirtualDir', 'Root');
    except
      RaiseException(Format('Web-site #%d not found: ', [IIsServerNumber]) + GetExceptionMessage());
    end;
    // Delete the virtual dir if it already exists
    try
      WebRoot.Delete('IIsWebVirtualDir', IIsAppName);
      WebRoot.SetInfo();
    except
    end;
    if (Version.Minor = 1) then  // XP: IIS 5.1
    begin
      // Create the virtual directory
      try
        vDir := WebRoot.Create('IIsWebVirtualDir', IIsAppName);
        vDir.AccessRead := True;
        vDir.AccessScript := True;
        vDir.AppFriendlyName := IIsAppName;
        vDir.Path := ExpandConstant('{app}');
        vDir.AppCreate(True);  // Create in "InProc" mode (don't really know why though)
        vDir.SetInfo();
      except
        RaiseException('Cannot create virtual directory: ' + GetExceptionMessage());
      end;
    end
    else if (Version.Minor = 2) then  // 2003: IIS 6.0
    begin
      // Application pool stuff
      AppPools := WebService.GetObject('IIsApplicationPools', 'AppPools');
      try
        // Check if the application pool already exists
        AppPool := AppPools.GetObject('IIsApplicationPool', IIsApplicationPoolName);
      except
        AppPool := Null;
      end;
      if VarIsNull(AppPool) then
      begin
        // Create the application pool
        try
          AppPool := AppPools.Create('IIsApplicationPool', IIsApplicationPoolName);
          AppPool.SetInfo();
        except
          RaiseException('Cannot add application pool: ' + GetExceptionMessage());
        end;
      end;
      // Create the virtual directory
      try
        vDir := WebRoot.Create('IIsWebVirtualDir', IIsAppName);
        vDir.AccessRead := True;
        vDir.AccessScript := True;
        vDir.AppFriendlyName := IIsAppName;
        vDir.Path := ExpandConstant('{app}');
        vDir.AppCreate(True);  // Create in "InProc" mode
        vDir.AppPoolId := IIsApplicationPoolName;
        vDir.SetInfo();
      except
        RaiseException('Cannot create virtual directory: ' + GetExceptionMessage());
      end;
    end;
    // Register handlers for ASP.NET 4 (important if other ASP.NET versions are present)
    if not ExecWithResult(ExpandConstant('{dotnet40}') + '\aspnet_regiis.exe',Format('-s "W3SVC/%d/ROOT/%s"', [IIsServerNumber, IIsAppName]),'',SW_HIDE,ewWaitUntilTerminated, ResultCode, ExecResult) or (ResultCode <> ERROR_SUCCESS) then
      RaiseException('Cannot set ASP.NET version: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
  end
  else if (Version.Major >= 6) then  // Vista / 2008 or later : IIS 7 or later
  begin
    // Get name of web-site
    if not IIs7ExecAppCmd(Format('list site /id:%d /text:name', [IIsServerNumber]), ExecResult, ResultCode) then
      RaiseException(Format('Cannot get name of web-site #%d: ', [IIsServerNumber]) + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    if (Length(Trim(ExecResult)) = 0) then
      RaiseException(Format('Web-site #%d not found.', [IIsServerNumber]));
    WebSiteName := ExecResult;
    // Delete the application if it already exists
    if not IIs7ExecAppCmd(Format('delete app "%s/%s"', [WebSiteName, IIsAppName]), ExecResult, ResultCode) or
      ((ResultCode <> ERROR_SUCCESS) and (ResultCode <> ERROR_NOT_FOUND) and (ResultCode <> ERROR_NOT_SUPPORTED)) then
      RaiseException('Cannot delete application: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    // Check if the application pool already exists (we don't delete it, since another GVS instance might be using it too)
    if not IIs7ExecAppCmd(Format('list apppool "%s" /text:name', [IIsApplicationPoolName]), ExecResult, ResultCode) or
      ((ResultCode <> ERROR_SUCCESS) and (ResultCode <> ERROR_INVALID_FUNCTION)) then
      RaiseException('Cannot list application pools: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    // Create the application pool
    if (ExecResult <> IIsApplicationPoolName) then
    begin
      if not IIs7ExecAppCmd(Format('add apppool /name:"%s" /managedRuntimeVersion:v4.0', [IIsApplicationPoolName]), ExecResult, ResultCode) or (ResultCode <> ERROR_SUCCESS) then
        RaiseException('Cannot add application pool: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    end;
    // Create the application
    if not IIs7ExecAppCmd(Format('add app /site.name:"%s" /path:"/%s" /physicalPath:"%s" /applicationPool:"%s"', [WebSiteName, IIsAppName, ExpandConstant('{app}'), IIsApplicationPoolName]), ExecResult, ResultCode) or
      (ResultCode <> ERROR_SUCCESS) then
      RaiseException('Cannot add application: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
  end
  else
    RaiseException('Cannot register web-site: Unknown OS version.');
end;

// Throws exceptions.
procedure DeleteAppFromIIs(const IIsAppName: String; const IIsServerNumber: Integer; const IIsApplicationPoolName: String);
var
  Version: TWindowsVersion;
  // IIS 5.1 - 6.0
  IIS, WebService, WebSite, WebRoot, AppPools: Variant;
  // IIS 7 and later
  ResultCode: Integer;
  ExecResult: String;
  WebSiteName: String;
begin
  GetWindowsVersionEx(Version);
  if (Version.Major = 5) and (Version.Minor <= 2) then  // XP, 2003: IIS 5.1 - 6.0
  begin
    try
      // Create the main IIS COM Automation object
      IIS := CreateOleObject('IISNamespace');
      WebService := IIS.GetObject('IIsWebService', 'localhost/W3SVC');
      // Get web site
      WebSite := WebService.GetObject('IIsWebServer', IntToStr(IIsServerNumber));
      WebRoot := WebSite.GetObject('IIsWebVirtualDir', 'Root');
    except
      RaiseException(Format('Web-site #%d not found: ', [IIsServerNumber]) + GetExceptionMessage());
    end;
    // Delete the virtual dir
    try
      WebRoot.Delete('IIsWebVirtualDir', IIsAppName);
      WebRoot.SetInfo();
    except
    end;
    if (Version.Minor = 2) then  // 2003: IIS 6.0
    begin
      // Application pool stuff
      AppPools := WebService.GetObject('IIsApplicationPools', 'AppPools');
      try
        // Delete the application pool
        AppPools.Delete('IIsApplicationPool', IIsApplicationPoolName);
      except
      end;
    end;
  end
  else if (Version.Major >= 6) then  // Vista / 2008 or later : IIS 7 or later
  begin
    // Get name of web-site
    if not IIs7ExecAppCmd(Format('list site /id:%d /text:name', [IIsServerNumber]), ExecResult, ResultCode) then
      RaiseException(Format('Cannot get name of web-site #%d: ', [IIsServerNumber]) + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    if (Length(Trim(ExecResult)) = 0) then
      RaiseException(Format('Web-site #%d not found.', [IIsServerNumber]));
    WebSiteName := ExecResult;
    // Delete the application
    if not IIs7ExecAppCmd(Format('delete app "%s/%s"', [WebSiteName, IIsAppName]), ExecResult, ResultCode) or
      ((ResultCode <> ERROR_SUCCESS) and (ResultCode <> ERROR_NOT_FOUND) and (ResultCode <> ERROR_NOT_SUPPORTED)) then
      RaiseException('Cannot delete application: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    // Delete the application pool
    if not IIs7ExecAppCmd(Format('delete apppool "%s"', [IIsApplicationPoolName]), ExecResult, ResultCode) or
      ((ResultCode <> ERROR_SUCCESS) and (ResultCode <> ERROR_NOT_FOUND)) then
      RaiseException('Cannot delete application pool: ' + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
  end
  else
    RaiseException('Cannot delete web-site: Unknown OS version.');
end;

有用的幫手

查找 ASP.NET 用於讀取/寫入虛擬目錄中的文件的 Windows 用戶帳戶。 用於設置“App_Data”的權限。

// Throws exceptions.
function GetIIsAppPoolIdentity(const IIsApplicationPoolName: String): String;
var
  Version: TWindowsVersion;
  ResultCode: Integer;
  ExecResult: String;
  IIS, AppPool: Variant;
begin
  GetWindowsVersionEx(Version);
  if (Version.Major = 5) and (Version.Minor = 1) then  // XP: IIS 5.1
  begin
    // TODO: Should be read from "[.NET 4]\Config\machine.config" -> system.web.processModel.userName
    // - "System"
    // - "Machine" -> "ASPNET" (default)
    // - A custom user account
    // See https://msdn.microsoft.com/en-us/library/dwc1xthy.aspx
    Result := 'ASPNET';
  end
  else if (Version.Major = 5) and (Version.Minor = 2) then  // 2003: IIS 6.0
  begin
    try
      IIS := CreateOleObject('IISNamespace');
      AppPool := IIS.GetObject('IIsApplicationPool', 'localhost/W3SVC/AppPools/' + IIsApplicationPoolName);
      if (AppPool.AppPoolIdentityType = 0) then
        Result := 'NT AUTHORITY\SYSTEM'
      else if (AppPool.AppPoolIdentityType = 1) then
        Result := 'NT AUTHORITY\LOCAL SERVICE'
      else if (AppPool.AppPoolIdentityType = 2) then
        Result := 'NT AUTHORITY\NETWORKSERVICE'
      else if (AppPool.AppPoolIdentityType = 3) then
        Result := AppPool.WAMUserName
      else
        RaiseException('Cannot get application pool identity: Unknown identity type (' + IntToStr(AppPool.AppPoolIdentityType) + ')');
    except
      RaiseException('Cannot get application pool identity: Unable to get object');
    end;
  end
  else if (Version.Major >= 6) then  // Vista / 2008 or later
  begin
    if not IIs7ExecAppCmd(Format('list apppool "%s" /text:processModel.identityType', [IIsApplicationPoolName]), ExecResult, ResultCode) or
      (ResultCode <> ERROR_SUCCESS) then
      RaiseException('Cannot get application pool identity.');
    if (ExecResult = 'LocalSystem') then
      Result := 'NT AUTHORITY\SYSTEM'
    else if (ExecResult = 'LocalService') then
      Result := 'NT AUTHORITY\LOCAL SERVICE'
    else if (ExecResult = 'NetworkService') then
      Result := 'NT AUTHORITY\NETWORKSERVICE'
    else if (ExecResult = 'ApplicationPoolIdentity') then
      Result := 'IIS AppPool\' + IIsApplicationPoolName
    else
      RaiseException('Cannot get application pool identity: Unknown identity type "' + ExecResult + '"');
  end
  else
    RaiseException('Cannot get application pool identity: Unknown OS version: ' + IntToStr(Version.Major) + '.' + IntToStr(Version.Minor));
end;

返回網站的物理路徑。 有助於找到安裝文件的正確位置。

// Throws exceptions.
function IIsGetPhysicalPath(const IIsServerNumber: Integer): String;
var
  Version: TWindowsVersion;
  IIS, WebService, WebSite, WebRoot: Variant;
  ResultCode: Integer;
  ExecResult: String;
  WebSiteName: String;
  PhysPath: String;
begin
  GetWindowsVersionEx(Version);
  if (Version.Major = 5) then
  begin
    try
      // Create the main IIS COM Automation object
      IIS := CreateOleObject('IISNamespace');
      WebService := IIS.GetObject('IIsWebService', 'localhost/W3SVC');
      // Get web site
      WebSite := WebService.GetObject('IIsWebServer', IntToStr(IIsServerNumber));
      WebRoot := WebSite.GetObject('IIsWebVirtualDir', 'Root');
    except
      RaiseException(Format('Web-site #%d not found: ', [IIsServerNumber]) + GetExceptionMessage());
    end;
    PhysPath := WebRoot.Path;
  end
  else if (Version.Major >= 6) then  // Vista / 2008 or later
  begin
    // Get name of web-site
    if not IIs7ExecAppCmd(Format('list site /id:%d /text:name', [IIsServerNumber]), ExecResult, ResultCode) then
      RaiseException(Format('Cannot get name of web-site #%d: ', [IIsServerNumber]) + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    if (Length(Trim(ExecResult)) = 0) then
      RaiseException(Format('Web-site #%d not found.', [IIsServerNumber]));
    WebSiteName := ExecResult;
    // Get physical path
    if not IIs7ExecAppCmd(Format('list vdir /app.name:"%s"/ /text:physicalPath', [WebSiteName]), ExecResult, ResultCode) or
      (ResultCode <> ERROR_SUCCESS) then
      RaiseException(Format('Cannot get physical path to web-site "%s": ', [WebSiteName]) + SysErrorMessage(ResultCode) + ' (' + IntToStr(ResultCode) + ')');
    PhysPath := ExecResult;
  end
  else
    RaiseException('Cannot get physical path to web-site root: Unknown OS version: ' + IntToStr(Version.Major) + '.' + IntToStr(Version.Minor));
  // Expand environment variables in path (e.g. "%SystemDrive%")
  Result := ExpandEnvVars(PhysPath);
end;

所以,最后我所做的是創建一個用 C# 編碼的單獨的可執行文件,它將在安裝前通過命令行安裝 IIS,然后在安裝后將 IIS 注冊到適當的應用程序池等。 然后,我繼續通過 PrepareToInstall 中的 Inno Setup 調用可執行文件來安裝 IIS,並在 CurStepChanged 中調用可執行文件來注冊 IIS。

我們也在使用 IIS 並考慮自動化 IIS 安裝。 據我所知,是否可以通過命令行工具完成所有工作。 因此,您可以創建自己的 Inno 自定義頁面以從用戶那里檢索必要的數據。 (您可以為此使用 Inno Setup Form Designer)。 一旦你收集了所有的東西,你就可以創建並填充你准備好的模板批處理文件,並且在安裝后將執行批處理。

我會這樣嘗試:

  • 嘗試使用有關 IIS 安裝的批處理文件完成所有操作(查看此存檔頁面
  • 當您可以對 IIS 配置的批處理文件執行任何操作時,您需要為 Inno 設置制作模板批處理文件
  • 為 Inno 創建自定義頁面以檢索必要的數據
  • 在 Inno 中,用變量替換模板批次
  • 在 Inno 中執行批處理

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM