3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Delphi】インターネットから DL したファイルを開こうとすると出る警告を消す

3
Last updated at Posted at 2026-05-04

はじめに

最近の (?) Windows はインターネットから DL したファイルを開こうとすると警告が出てウザい事があります。

詳細は以下に譲るとして、

つまりはファイルにゾーン情報が付加されているために実行 (やオープン) がブロックされてしまうという事です。

インターネットから DL したファイルのブロック

NTFS のストリームについては以下が詳しいです。

例えば NONAME.TXT というファイルをインターネットから DL したら、Zone.Identifier というストリームが付与されるという事です。

この Zone.IdentifierNONAME.TXT:Zone.Identifier という感じでアクセスする事が可能で、コマンドプロンプトなら MORE コマンドが対応しています。

試しにやってみよう

以下のページから tead_229_full.exe を DL して実行してみます。中身はただのテキストエディタですのでご心配なく 1

image.png

ファイルのプロパティを見るとセキュリティ情報が付いています。

image.png

more コマンドでも確認できました。ZoneID3 (インターネット) になっています。

image.png

実行すると見事にブロックされました。

image.png

Delphi で Zone.Identifier を削除する?

ググってみたら、NTFS ファイルストリームの Zone.Identifier削除するのはコマンドプロンプトでも Power Shell でも可能で、なんなら専用のツールもありました。

これらを紹介するだけだと面白くないのと、Zone.IdentifierReferenceUrl とか HostURL とかの情報は後々残しておくと便利そうだと思ったので、ZoneID0 (マイコンピュータ) に設定して回避するツールを Delphi で作る事にしました。

ソースコード

コンソールアプリケーションとして作ってみました。Community Edition でもコンパイルできます。

StripZoneID.dpr
program StripZoneID;

{$APPTYPE CONSOLE}

uses
  System.Classes, System.SysUtils, System.IOUtils;

const
  ZI_FILENAME = 'Zone.Identifier';

var
  FileName: string;

  function Check: Integer;
  begin
    // 正常終了にセット
    Result := 0;
    // パラメータなしで実行されたらエラー
    if ParamCount = 0 then
      Exit(1);
    // ファイルのパラメータ位置を特定
    var FileIdx := -1;
    for var i:=1 to ParamCount do
    begin
      var s := ParamStr(i);
      if not CharInSet(s[1], ['-', '/']) then
      begin
        FileIdx := i;
        Break;
      end;
    end;
    // ファイルが指定されていなかったらエラー
    if FileIdx < 1 then
    begin
      Writeln('No file has been specified.');
      Exit(2);
    end;
    // ファイルが存在しなかったらエラー
    FileName := ParamStr(FileIdx);
    if not TFile.Exists(FileName) then
    begin
      Writeln('File not found.');
      Exit(3);
    end;
    // Zone.Identifier が存在しなかったらエラー
    FileName := FileName + ':' + ZI_FILENAME;
    if not TFile.Exists(FileName) then
    begin
      Writeln(ZI_FILENAME + ' not found.');
      Exit(4);
    end;
  end; { Check }

begin
  // エラーチェック
  ExitCode := Check();

  // ExitCode が 0 でなかったら USAGE を表示して終了
  if ExitCode > 0 then
  begin
    var s := '''

    USAGE: StripZoneID [[/d] [/v] [/z:<id>]] FileName

      /d        Delete Zone.Identifier
      /v        View Zone.Identifier
      /z:<id>   Set ZoneID (0..4)
    ''';
    Writeln(s);
    Exit;
  end;

  if FindCmdLineSwitch('v', True) then
  begin
    // /v スイッチが指定されていたら Zone.Identifier を表示
    var SL := TStringList.Create;
    try
      SL.LoadFromFile(FileName);
      Writeln(SL.Text);
    finally
      SL.Free;
    end;
  end
  else if FindCmdLineSwitch('d', True) then
  begin
    // /d スイッチが指定されていたら Zone.Identifier を削除
    DeleteFile(FileName);
  end
  else
  begin
    // /z スイッチが指定されていたらその値を ZoneID に設定
    // /z スイッチが指定されていなかったら 0 を ZoneID に設定
    var v: string;
    var HasValue := FindCmdLineSwitch('z', v, True, [clstValueAppended]);
    if not HasValue or (Length(v) <> 1) or not CharInSet(v[1], ['0'..'4']) then
      v := '0';
    var SL := TStringList.Create;
    try
      SL.LoadFromFile(FileName);
      SL.Values['ZoneID'] := v;
      SL.SaveToFile(FileName);
    finally
      SL.Free;
    end;
  end;
end.

コマンドラインスイッチは次の通りです:

  • ファイルしか指定しなかったら、Zone.IdentifierZoneID を 0 に設定
  • /v スイッチが指定されていたら Zone.Identifier の中身を表示
  • /d スイッチが指定されていたら Zone.Identifier を削除
  • /z:<id> (または /z<id>) スイッチが指定されていたら、Zone.IdentifierZoneID を id に設定 (id=0..4)

設定可能な ZoneID の値は次の通りです:

ZoneId 内容
0 マイコンピュータ (ローカルマシン)
1 ローカルイントラネット
2 信頼済みサイト
3 インターネット (保護ビューや警告の対象)
4 制限付きサイト

Delphi のルーチンやメソッドがすべて NTFS ファイルストリーム対応という訳ではないので、対応しているものを使っています。

実行

あら、便利!!

通常 (スイッチなし):

image.png

/Z (ZoneID 設定):

image.png

/D (Zone.Identifier 削除):

image.png

嫌な予感

さて、ここまで記事を書いた段階で「こういうの Mr.XRAY さんがやってそうだよなぁ?」と不安になって来た訳ですよ...

image.png

ヤッパリカー!!

おわりに

身も蓋もない事を言うと、最初から curl でダウンロードすりゃいいんですよ

image.png

現在の所、curl で DL するとゾーン情報が付加されません。

  1. 実は NTFS ファイルストリームを読み書きする機能があります。

3
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?