Установка и настройка IIS Inno Setup

Я пытался выяснить, как установить и зарегистрировать IIS с помощью сценария установки Inno, но до сих пор не удалось.

Мне нужно создать приложение, пул приложений с .Net версии 4 и виртуальный каталог, получить IP-адрес машины и приступить к редактированию Привязок веб-сайта с этим IP.

до сих пор все, что работает в моей установке, проверяет, установлен ли IIS.

Если кто-нибудь когда-либо делал что-то подобное раньше, Я был бы очень признателен, если бы вы поделились своим сценарием.

спасибо.

3 ответов


вот мой полный код для обработки IIS (Internet Information Services) с настройкой Inno. Он содержит:

  • установка .NET Framework 4
  • установка / удаление IIS+ASP.NET 4
  • регистрация и удаление веб-сайтов/приложения
  • Helper для получения учетной записи пользователя пул приложений работает на
  • Helper, чтобы получить физический путь к веб-сайту

он был протестирован со следующими окнами издания: 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

все делается как можно пассивнее, чтобы не сломать существующие веб-сайты.

важно

это может понадобится Unicode-Версия Inno-Setup(я использую 5.5.6 (u)). Также необходимо заставить 64-разрядный режим на машинах x64 (в противном случае доступ к реестру и файлу будет перенаправлен к 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 Установка

установит .NET 4.0 для Win XP / 2003. .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

поскольку я использую веб-установщики, может потребоваться подключение к интернету во время установка.

// 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

устанавливает IIS с ASP.NET 4. Активирует те же функции (по умолчанию), что и при активации через GUI. После завершения установки, ASP.NET is (re-)зарегистрирован в 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;

Полезные Помощники

находит учетную запись пользователя Windows, используемую ASP.NET чтение / запись файлов в виртуальном каталоге. Полезно установить разрешения для "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 в соответствующем пуле приложений и т. д. После установки. Затем я приступил к вызову исполняемого файла через Inno Setup в PrepareToInstall для установки IIS и в CurStepChanged для регистрации IIS.


мы также используем IIS и думаем об автоматизации установки IIS. Насколько я знаю, можно ли сделать все это с помощью инструментов командной строки. Таким образом, Вы можете создать свои собственные пользовательские страницы Inno для получения необходимых данных от пользователя. (Для этого можно использовать конструктор форм настройки Inno). После того, как вы собрали все свои вещи, вы можете создать, а затем заполнить подготовленные пакетные файлы шаблона, и в post install пакеты будут выполнены.

Я бы попробовал, как это:

  • попробуйте сделать все с помощью пакетного файла, касающегося установки IIS (взгляните на это http://myitforum.com/cs2/blogs/jgilbert/archive/2009/03/05/automating-iis-7-installation-to-support-configuration-manager-2007.aspx)
  • когда вы можете сделать что-нибудь с пакетными файлами для конфигурации IIS, вам нужно сделать пакетные файлы шаблонов для установки Inno
  • создайте пользовательские страницы для Inno, чтобы получить необходимые данные
  • в Inno замените пакеты шаблонов переменными
  • выполнить пакеты в Inno

надеюсь, что это помогает