搜索Inno Setup DestDir的子目录 [英] Search subdirectories for Inno Setup DestDir

查看:99
本文介绍了搜索Inno Setup DestDir的子目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Inno Setup分发另一个应用程序用作插件的文件。如果找不到插件的目标位置,它仍应将其自身安装到Program Files目录中,为用户提供手动说明。

I am attempting to use Inno Setup to distribute a file used as a plug-in by another application. If it cannot find the plug-in destination, it should still install itself into the Program Files directory, providing the user with manual instructions.

退出Tlama 提供了类似问题中使用的一些代码: Inno Setup查找子文件夹

Hats off to Tlama for providing some code that was used in a similar problem: Inno Setup find subfolder.

跟随脚本列出了我希望实现的基本设置,并在脚本不完整的地方加了注释。我只是在头上。 :-)

The follow script lays out the basic setup I am hoping to achieve, with comment where the script is incomplete. I'm just in over my head. :-)


  1. 如何将找到的目录传递回 StampTargetDir (当前仅是一个MsgBox)

  1. How to pass the found directory back to StampTargetDir (currently just a MsgBox)

如何在指定目录名称(例如邮票)下搜索所有子目录

How to search all subdirectories under the specified directory name (i.e. 'Stamps')

如何将所有子目录(#2)的搜索限制为仅存在于 {pf} {localappdata} (即 Adob​​e和 Acrobat)

How to limit the search of all subdirectories (#2) to just a few named subdirectories living in {pf} or {localappdata} (i.e. "Adobe" and "Acrobat")

在<$ c下进行文件插件安装$ c> [文件] 以找到邮票目录为条件。

Make the file plug-in installation under [Files] conditional on finding the 'Stamps' directory.

PS我知道搜索有一些明显的缺点。但是, Stamps目录不太可能在其他区域中使用(请参阅#3)。

P.S. I know searching has some obvious disadvantages. However the "Stamps" directory is unlikely to be used in other areas (see #3).

[Files]
; Install all the files in a user specified location.
Source: "C:\mydir\readme.pdf"; DestDir: "{app}"; Flags: ignoreversion
Source: "C:\mydir\stamp.pdf"; DestDir: "{app}"; Flags: ignoreversion
; If found, install the stamp file in the Adobe Acrobat or Reader Stamp directory.
Source: "C:\mydir\stamp.pdf"; DestDir: "{code:StampTargetDir}"; Flags: ignoreversion


[Tasks]
Name: pf; Description: "&All users on this computer."; GroupDescription: "Configure Acrobat stamp plug-in:"; Flags: exclusive
Name: local;  Description: "&Only the current user (me)."; GroupDescription: "Configure Acrobat stamp plug-in:"; Flags: exclusive unchecked
Name: none;  Description: "&Do not configure stamps (manual setup)."; GroupDescription: "Configure Acrobat stamp plug-in:"; Flags: exclusive unchecked

[Code]
function GetFirstMatchingSubfolder(const Path: string; out Folder: string): Boolean;
var
  S: string;
  FindRec: TFindRec;
begin
  Result := False;
  if FindFirst(ExpandConstant(AddBackslash(Path) + '*'), FindRec) then
  try
    repeat
      // *** THIS DOES NOT SEARCH SUBDIRECTORIES ***
      if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) and
        (FindRec.Name <> '.') and (FindRec.Name <> '..') and
        (FindRec.Name = 'Stamps') then
      begin
        Result := True;
        Folder := AddBackslash(Path) + FindRec.Name;
      end;
    until
      not FindNext(FindRec);
  finally
    FindClose(FindRec);
  end;
end;

function StampTargetDir(Param: String): String;
begin
  if IsTaskSelected('pf') then
    // *** THIS NEEDS TO BE 'Stamps' DIRECTORY FOUND UNDER {pf}
    Result := ExpandConstant('{app}') + '\pf'
  else if IsTaskSelected('local') then
    // *** THIS NEEDS TO BE 'Stamps' DIRECTORY FOUND UNDER {localappdata}
    // Assuming {localappdata} is the user's Application Data Folder
    // Typically C:\Documents and Settings\username\Application Data.
    Result := ExpandConstant('{app}') + '\local'
  else
    Result := ExpandConstant('{app}') + '\none'
end;

// *** This procedure is just for testing. The results of
// GetFirstMatchingSubfolder should be used by StampTargetDir
procedure InitializeWizard;
var
  S: string;
begin
  // *** THIS DOES NOT LIMIT SEARCH TO {pf}\Adobe or {pf}\Acrobat ***    if GetFirstMatchingSubfolder(ExpandConstant('{pf}'), S) then
    MsgBox('An extra copy will go in here: ' + S, mbInformation, MB_OK);
end;


推荐答案


  1. 到将路径从 InitializeWizard 传递到 StampTargetDir ,请使用全局变量。尽管我建议您最好使用 CurStepChanged(ssInstall)代替 InitializeWizard ,除非您需要比实际安装更早的路径

  1. To pass the path from InitializeWizard to StampTargetDir, use a global variable. Though I suggest you better use CurStepChanged(ssInstall) instead of InitializeWizard, unless you need the path earlier than during the actual installation.

GetFirstMatchingSubfolder 中使用递归。

最干净的解决方案是使用特定的根目录多次运行 GetFirstMatchingSubfolder (即两次,对于Adobe和Acrobat)

The cleanest solution is to run GetFirstMatchingSubfolder multiple times with specific roots (i.e. twice, for Adobe and for Acrobat)

使用 检查参数

代码可以像这样:

[Files]
Source: "C:\mydir\stamp.pdf"; DestDir: "{code:GetStampsFolderPath}"; \
    Check: WasStampsFolderFound; Flags: ignoreversion

[Code]

const
  StampsFolderName = 'Stamps';

var
  StampsFolderPath: string;

function WasStampsFolderFound(): Boolean;
begin
  Result := (StampsFolderPath <> '');
end;

function GetStampsFolderPath(Params: string): string;
begin
  Result := StampsFolderPath;
end;

function GetFirstMatchingSubfolderRecursively(const Path: string; Name: string; out Folder: string): Boolean;
var
  FindRec: TFindRec;
  FolderPath: string;
begin
  Result := False;
  Log(Format('Searching in %s', [Path]));

  if FindFirst(AddBackslash(Path) + '*', FindRec) then
  try
    repeat
      if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY <> 0) then
      begin
        FolderPath := AddBackslash(Path) + FindRec.Name;
        if CompareText(FindRec.Name, Name) = 0 then
        begin
          Result := True;
          Folder := FolderPath;
          Log(Format('Match: %s', [Folder]));
        end
          else
        if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
        begin
          Result := GetFirstMatchingSubfolderRecursively(FolderPath, Name, Folder);
        end;
      end;
    until Result or (not FindNext(FindRec));
  finally
    FindClose(FindRec);
  end;
end;

procedure CurStepChanged(CurStep: TSetupStep);
var
  RootPath: string;
begin
  Log(Format('CurStepChanged %d', [CurStep]));

  if CurStep = ssInstall then
  begin
    if IsTaskSelected('pf') then
    begin
      // this should be pf32 or pf64 specifically,
      // depending on where Adobe installs the applications
      RootPath := ExpandConstant('{pf}\');
    end
      else
    if IsTaskSelected('local') then
    begin
      RootPath := ExpandConstant('{localappdata}\');
    end;

    if RootPath = '' then
    begin
      Log(Format('No task selected, will not search for %s', [StampsFolderName]));
    end
      else
    begin
      Log(Format('Searching for %s folder under %s', [StampsFolderName, RootPath]));

      if GetFirstMatchingSubfolderRecursively(RootPath + 'Adobe', StampsFolderName, StampsFolderPath) or
         GetFirstMatchingSubfolderRecursively(RootPath + 'Acrobat', StampsFolderName, StampsFolderPath) then
      begin
        Log(Format('Found %s folder at %s', [StampsFolderName, StampsFolderPath]));
      end
        else
      begin
        Log(Format('%s folder not found anywhere', [StampsFolderName]));
      end;
    end;
  end;
end;

这篇关于搜索Inno Setup DestDir的子目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆