Как справиться с предварительным условием DotNet с системой Inno Setup Install / DswinDs?

Теперь я понимаю, как использовать этот DswinsHs для загрузки файла (поскольку он работает для моей справочной документации).

Но теперь мне нужно мигрировать некоторый старый код, который необязательно скачал и установил Dot Net Framework.

Старый код

У меня есть этот код (используется ISTool DLL):

const
  // Changed to 4.6.2 download link (see: http://msdn.microsoft.com/en-us/library/ee942965%28v=vs.110%29.aspx#redist)
  dotnetRedistURL = 'http://go.microsoft.com/fwlink/?LinkId=780600';

function PrepareToInstall(var NeedsRestart: Boolean): String;
var
 IsInstalled: Cardinal;
begin
  Result := '';
  dotNetNeeded := true;

  // Check for required netfx installation
  // http://msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx#net_b
  if(Is64BitInstallMode()) then begin
    if (RegValueExists(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
        downloadNeeded := false;
      end;
    end;
  end
  else begin
    if (RegValueExists(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
        downloadNeeded := false;
      end;
    end;
  end;

  if(dotNetNeeded) then begin
    if (not IsAdminLoggedOn()) then begin
      Result := ExpandConstant('{cm:DotNet_NeedAdminRights}');
    end
    else begin
      dotnetRedistPath := ExpandConstant('{src}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
      if not FileExists(dotnetRedistPath) then begin
        dotnetRedistPath := ExpandConstant('{tmp}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
        if not FileExists(dotnetRedistPath) then begin
          isxdl_AddFile(dotnetRedistURL, dotnetRedistPath);
          downloadNeeded := true;
        end;
      end;

      if (downloadNeeded) then begin
        if (MsgBox(ExpandConstant('{cm:DotNet_NeedToDownload}'), mbConfirmation, MB_OKCANCEL) = IDCANCEL) then begin
          Result := ExpandConstant('{cm:DotNet_InstallAborted}');
        end;
      end;
    end;
  end;

  // AJT v19.0.0 We always delete the existing local help file if it exists.
  // The new version will be downloaded on the next wizard form if
  // the user still wants the local help. ("downloadhelp" task selected).
  if (bDownloadHelpDocSetup) then DoDeleteFile(ExpandConstant('{app}\CommunityTalks.chm'));

 end;

Тогда у меня есть:

procedure CurStepChanged(CurStep: TSetupStep);
var
  hWnd: Integer;
  ResultCode: Integer;
begin
  if (CurStep = ssInstall) then
  begin
    hWnd := StrToInt(ExpandConstant('{wizardhwnd}'));

    // Don't try to init isxdl if it's not needed because it will error on < ie 3
    if (downloadNeeded) then begin
      isxdl_SetOption('label', ExpandConstant('{cm:Downloading}'));
      isxdl_SetOption('description', ExpandConstant('{cm:DownloadingInfo}'));
      if (isxdl_DownloadFiles(hWnd) = 1) then begin
        if (dotNetNeeded = true) then begin
          if Exec(ExpandConstant(dotnetRedistPath), '/quiet', '',
                 SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
            // handle success if necessary; ResultCode contains the exit code
            if not (ResultCode = 0) then begin
              // Microsoft present an array of options for this. But since
              // The interface was visible I think it is safe to just say
              // that the installation was not completed.
              MsgBox(ExpandConstant('{cm:DotNet_InstallFailed}'), mbInformation, MB_OK);
              Abort();
            end;
          end
          else begin
            // The execution failed for some reason
            MsgBox(SysErrorMessage(ResultCode), mbInformation, MB_OK);
            Abort();
          end;
        end;
      end
      else begin
        // The user most likely cancelled the download of the file
        MsgBox(ExpandConstant('{cm:DotNet_DownloadFailed}'), mbInformation, MB_OK);
        Abort();
      end;
    end;
    end;
end;

Это нужно изменить.


Как это делается с DswinsHs

Для моей загрузки, которая работает с DwinsHs, у меня в основном есть два бита следующим образом:

  • [Files] раздел:
    ; AJT v19.0.0 Download Help Documentation Setup file.
    ; This is associated with the "downloadhelp" task.
    ; It will be downloaded from the internet and deleted after install.
    Source: "{tmp}\HelpDocSetup.exe"; \
        DestDir: "{app}"; \
        Flags: external deleteafterinstall; \
        Tasks: downloadhelp; \
        Check: DwinsHs_Check( ExpandConstant('{tmp}\HelpDocSetup.exe'), '{#HelpDocSetupURL}', \
                'My_Setup', 'Get', {#HelpDocSetupFileSize}, 0 )
  • [Run] раздел:
    ; AJT v19.0.0 Installed the downloaded help documentation.
    ; This is only done if the "downloadhelp" task was selected.
    Filename: "{app}\HelpDocSetup.exe"; \
        Parameters: "/SP- /VERYSILENT /InstallPath=""{app}"""; \
        WorkingDir: "{app}"; \
        Flags: waituntilterminated runhidden; \
        Description: "{cm:InstallingHelpDescription}"; \
        StatusMsg: "{cm:InstallingHelpStatusMessage}"; \
        Tasks: downloadhelp

Проблема

Мне нужно преобразовать мой предыдущий код (предварительное условие DotNet) в подходящие строки файла/запуска сценария (за исключением того, что на этот раз мне нужно передать 0 для размера файла, поскольку я не знаю размер).

Короче говоря, для моей установки требуются права администратора, и технически нам нужно загрузить и установить dotnet (если его там нет) перед продолжением установки. Причина в том, что у нас есть эти записи run:

Filename: "{dotnet40}\regasm.exe"; \
    Parameters: "PTSTools_x86.dll /codebase"; \
    WorkingDir: "{app}"; \
    Flags: runhidden

Filename: "{dotnet4064}\regasm.exe"; \
    Parameters: "PTSTools_x64.dll /codebase"; \
    WorkingDir: "{app}"; \
    Flags: runhidden; \
    Check: IsWin64

Filename: "{dotnet40}\regasm.exe"; \
    Parameters: "/u PTSTools_x86.dll"; \
    WorkingDir: "{app}"; \
    Flags: runhidden; \
    Check: FileExists(ExpandConstant('{app}\PTSTools.dll')); \
    AfterInstall: DoDeleteFile(ExpandConstant('{app}\PTSTools.dll'))

Filename: "{dotnet4064}\regasm.exe"; \
    Parameters: "/u PTSTools.dll"; \
    WorkingDir: "{app}"; \
    Flags: runhidden; \
    Check: IsWin64 and FileExists(ExpandConstant('{app}\PTSTools.dll')); \
    AfterInstall: DoDeleteFile(ExpandConstant('{app}\PTSTools.dll'))

Таким образом, наличие DotNet является необходимым условием для работы установщика. Должен ли я относиться к этому по-другому?


Я делаю это правильно?

Основываясь на предоставленном ответе и моем понимании документации...

Шаг 1

В PrepareToInstall проверяем, нужен ли DotNet, и кэшируем результат:

function PrepareToInstall(var NeedsRestart: Boolean): String;
var
 IsInstalled: Cardinal;
begin
  Result := '';
  dotNetNeeded := true;

  // Check for required netfx installation
  // http://msdn.microsoft.com/en-us/library/hh925568%28v=vs.110%29.aspx#net_b
  if(Is64BitInstallMode()) then begin
    if (RegValueExists(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Wow6432Node\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
      end;
    end;
  end
  else begin
    if (RegValueExists(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release')) then begin
      RegQueryDWordValue(HKLM, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', IsInstalled);
      if(IsInstalled >= 378675) then begin
        dotNetNeeded := false;
      end;
    end;
  end;

  if(dotNetNeeded) then begin
    if (MsgBox(ExpandConstant('{cm:DotNet_NeedToDownload}'), mbConfirmation, MB_OKCANCEL) = IDCANCEL) then begin
      Result := ExpandConstant('{cm:DotNet_InstallAborted}');
    end;
  end;

 end;

Шаг 2

Мы добавляем обработчик BeforeDownload. Здесь у нас есть возможность добавить файл, который нам нужно загрузить, в список:

function BeforeDownload(): Boolean;
 begin
  if(dotNetNeeded) then
  begin
    dotNetRedistPath := ExpandConstant('{tmp}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
    DwinsHs_AppendRemoteFile( dotNetRedistPath, \
                  dotnetRedistURL, 'My_Setup', rmGet, FILESIZE_QUERY_SERVER );
  end;

  Result := True;
end;

Шаг 3

Мы добавляем обработчик AfterDownload. Здесь мы выполняем установку DotNet.

procedure AfterDownload(State: Integer);
var
  hWnd: Integer;
  ResultCode: Integer;
begin
  if (State = READ_OK) then
  begin
    if(dotNetNeeded) then
    begin
      if Exec(ExpandConstant(dotnetRedistPath), '/quiet', '',
          SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
        // handle success if necessary; ResultCode contains the exit code
        if not (ResultCode = 0) then begin
          // Microsoft present an array of options for this. But since
          // The interface was visible I think it is safe to just say
          // that the installation was not completed.
          MsgBox(ExpandConstant('{cm:DotNet_InstallFailed}'), mbInformation, MB_OK);
          Abort();
        end;
      end
      else begin
        // The execution failed for some reason
        MsgBox(SysErrorMessage(ResultCode), mbInformation, MB_OK);
        Abort();
      end;
    end;
  end;
end;

Я не уверен, что "тихий" - правильный путь сейчас...

Шаг 4

Настраиваем обработчик CurPageChanged:

procedure CurPageChanged(CurPage: Integer);
begin
  DwinsHs_CurPageChanged(CurPage, @BeforeDownload, @AfterDownload);
end;

person Andrew Truckle    schedule 03.06.2019    source источник
comment
А проблема в том?   -  person Martin Prikryl    schedule 03.06.2019
comment
@MartinPrikryl Моя справочная документация не является обязательным условием. Таким образом, он загружается как часть установки, если пользователь хочет, чтобы он был включен. Но Dot Net, как вы знаете, является обязательным условием. Это означает, что я должен проверить, нужно ли это, и если да, то сначала установить его, а затем продолжить настройку. Я не знаю, как впихнуть код, который у меня уже есть, в это уравнение, совместимое с DswinDs.   -  person Andrew Truckle    schedule 03.06.2019
comment
Почему вы не можете установить .NET как часть установки? Он нужен для самой установки?   -  person Martin Prikryl    schedule 03.06.2019
comment
@MartinPrikryl Да, посмотрите на «Проблему» внизу, где мы используем dotnet regasm для некоторых моих файлов, чтобы зарегистрировать их.   -  person Andrew Truckle    schedule 03.06.2019
comment
@MartinPrikryl Я вижу похожий вопрос stackoverflow.com/questions/20752882/, но логика для меня другая. Поскольку мы используем {dotnet4064}\regasm.exe, мы должны установить его (при необходимости) до того, как запустится остальная часть нашего скрипта.   -  person Andrew Truckle    schedule 03.06.2019


Ответы (1)


Просто позвоните DwinsHs_AppendRemoteFile, когда dotNetNeeded.

DwinsHs_AppendRemoteFile имеет в основном те же аргументы, что и DwinsHs_Check (DwinsHs_Check на самом деле является только Check-совместимой оболочкой вокруг DwinsHs_AppendRemoteFile).

Я считаю, что это все, что вам нужно. [Run] происходит только после загрузки.

person Martin Prikryl    schedule 03.06.2019
comment
Я понимаю. Это означает, что у нас будет это как запись первого запуска... Так что она будет установлена ​​первой... - person Andrew Truckle; 03.06.2019
comment
Я собираюсь принять это, потому что моя проблема с фактической установкой фреймворка - это другой вопрос. Спасибо. - person Andrew Truckle; 03.06.2019