3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Inno SetupでXCopyFile()を実装する

Last updated at Posted at 2019-02-02

Inno Setupのスクリプトでファイルを配置する

Inno Setupでファイルやフォルダをインストールする際、[Files]セクションを利用するのが基本です。しかし、いろいろな事情で、スクリプトを使ってファイルをインストールしたいこともあります。こういった場合、インストーラー本体とインストールするファイルをユーザーの環境の一時的な場所に展開しておき、インストーラーで適切な場所にファイルをコピーすることになります。こういった用途には、CreateDir()CopyFile()などの関数を利用できます。しかし、ファイル数が多いとコーディングも大変ですし、ファイル構成が変わるとせっかく書いたコードを編集することになり大変です。

そこでXCopy()関数

Windowsのコマンドプロンプトでは、フォルダ構造を保ったまま複数のファイルをコピーするXCOPYコマンドがあります。この機能がInno Setupのスクリプトで使えれば便利なのですが、残念ながら用意されていません。そこで、独自に実装してみたのですが、思ったより簡単にできたので紹介します。手順的には、コピー元のフォルダとファイルを列挙して順次コピーしていくだけなので、列挙方法をInno Setupのヘルプで調べます。まずは、FindFirst()とFindNext()を組み合わせて・・・と思いFindFirst()のヘルプを見ると、下記のサンプルのコードが載っています。

var
  FilesFound: Integer;
  FindRec: TFindRec;
begin
  FilesFound := 0;
  if FindFirst(ExpandConstant('{sys}\*'), FindRec) then begin
    try
      repeat
        // Don't count directories
        if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
          FilesFound := FilesFound + 1;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
  MsgBox(IntToStr(FilesFound) + ' files found in the System directory.',
    mbInformation, MB_OK);
end;

ん! 再帰を使えば「このコードそのまま使えるじゃん!」ということに気づき、ちょっとの改造でXCopy()関数を実装しました。

//---------------------------------------------------------------------------
// sourcePathフォルダをdestPathフォルダ以下にファオルダ構造を保ってコピーする
//---------------------------------------------------------------------------
procedure XCopyFile(sourcePath, destPath: String);
var
  FindRec: TFindRec;
begin
  if FindFirst(sourcePath+'\*', FindRec) then begin
    try
      repeat
        if (FindRec.Name<>'.') and (FindRec.Name<>'..') then begin  // フォルダ自身と親フォルダは処理しない
          if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then begin
            // ファイルのとき
            CopyFile(sourcePath + '\' + FindRec.Name, destPath + '\' + FindRec.Name, False);
          end else begin
            // ディレクトリのとき
            CreateDir(destPath + '\' + FindRec.Name);
            XCopyFile(sourcePath + '\' + FindRec.Name, destPath + '\' + FindRec.Name);
          end;
        end;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end;
end;

FindFirst()とFindNext()は、カレントディレクトリ「.」と親ディレクトリ「..」も返すので、これらを処理しないようにする必要がありました。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?