Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2013年03月22日] [更新 2016年09月30日] Delphi 一般・その他
[ Windows セキュリティの重要な警告 ] ダイアログ
動作確認等 Windows 7 U64(SP1) + Delphi XE(UP1) Pro
[整理番号 - 0420]



  • 2016年06月30日
  • netsh コマンドによる操作のサンプルコードを追加
  • 2016年07月11日
  • 最終的なダイアログだけの画像とコマンドだけを掲載するようにして、中間の画像類を削除




01_[ Windows セキュリティの重要な警告 ] ダイアログ


当サイトの FTP 関係のサンプル、あるいはネットワーク関係のプログラムを実行すると、下図のようなダイアログが現れることがあります。これは、Windowsファイアウォールの機能によるものです。Windows XP の SP2 からはデフォルトで有効に設定されています。

このダイアログが現れたら、許可するネットワークの場所に応じたチェックをして、[アクセスを許可する] をクリックします。インターネット上のファイルの操作であれば [パブリックネットワーク] にチェックが必要です。

UAC を無効にしていると、FTP やネットワーク関係のサンプルが正常に動作しないことがあります。また、本ページで説明している設定関係も正常に機能しない場合があります。



[備考]
本ページはコンピュータ上のプログラムを実行する時に現れるダイアログについての記事です。ウェブブラウザ (インターネットブラウザ) で現れる警告ダイアログのことではありません。


図1
警告ダイアログ
  • 組織内のネットワークか、パブリック (インターネット接続) かによってチェックを入れる
  • [アクセスを許可する] をクリックする

上のダイアログで、[アクセスを許可する] あるいは [キャンセル] をクリックしても、サンプルによっては、プログラムが応答しなくなる場合があります。次項で説明しているセキュリティの設定に該当するプログラムがリストにあるかも知れません。それを削除して再度実行してみてください。
掲載しているサンプルで、対象のサンプルプログラムのファイアウォールを OFF にして、再度 ON にすると同じ操作になります。この時、LRuleName は拡張子を除いた exe 名とします。ほんどのサンプルプログラムは、この名前は Project1 です。

プログラムが応答しなくなるかどうかは、コーディングによります。サンプルプログラム集のサンプルは、あくまでもサンプルで、テスト用です。ご了承ください。
実際のアプリケーションでは、応答コード等を処理して、そうならないように工夫が必要です。



図2
プログラムが反応しなくなる
  • 一度、強制終了する




02_セキュリティの重要な警告ダイアログを表示するようにする
plSetAppFWState.zip [478 KB] 2016年10月05日版 (説明なし,ソースコードなし)
本項に掲載しているサンプルコードの EXE ファイル。再配布自由


上の説明にしたがって、[アクセスを許可する] にしてプログラムを実行すると、その後、警告のダイアログは現れなくなります。しかし、開発したアプリケーションを配布する際は、配布先のコンピュータと同じ状態で動作確認することも必要と思われます。
この警告ダイアログを再び表示するようにするには、システムに記録された内容を削除して、ファイアウォールを有効にします。

[ファイル名を指定して実行] のダイアログで以下のコマンドを実行します。

WF.msc


表示されたダイアログの左ペインの [受信の規則] をクリックすすると、プログラム毎にファイアウォールの設定内容が表示されます。サンプルプログラム集の EXE 名の多くは Project1 です。EXE の名前が同じであっても、フォルダが違えば別のプログラムとして扱われます。同じフルパスの EXE に複数の項目がある場合もあることに注意してください。

ファイアウォールを有効にするプログラムを選択して (複数の選択も可能)、右ペインの [削除] をクリックすると削除できます。


  • 図3
  • 該当プログラムのファイアウォールを有効にするには、リストから削除する
  • 右ペインの [プロパティ] で、選択項目の詳細な設定が可能

図4
各アイコンの意味

netsh コマンドを使用すると、以下のようにプログラムで操作できます。
変数の LRuleName, FAppExePath は、上の図の [名前] と [プログラム] に相当する値です。
上の図からも分かるように、Project1 ではパス名を確認しないと区別がつかないので、このコードでは名前を FTPTestProgram にしています。



[備考 1]
コントロールパネル関係ダイアログでの設定は、多くの場合、管理者としてログインしていれば、管理者に昇格しなくても設定可能ですが、確認のダイアログが表示されることもあります。
一方、コマンドやプログラムのコードで設定する場合は、管理者権限が必要な操作は管理者への昇格が必要です。

[備考 2]
上の図のファイアウォールの設定ダイアログの表示は自動更新はしません。ダイアログを表示したままでファイアウォールの設定を変更した場合は、[操作] [最新の情報に更新] をクリックして表示を更新する必要があります。


図5
サンプルの実行画面

リスト1
特定のプログラムだけファイアウォールの無効 (OFF) と有効 (ON) を切り換える
無効 (OFF) にすると [Windows セキュリティの重要な警告] ダイアログは表示されない
uses
  ShellAPI;

{$R *.dfm}

//=============================================================================
//  フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  OpenDialog1.Filter := 'exe ファイル (*.exe)|*.exe';
  OpenDialog1.InitialDir := ExtractFileDir(Application.ExeName);

  LabeledEdit1.Text := '';
  LabeledEdit2.Text := '';
end;

//=============================================================================
//  対象のEXEファイルの選択
//=============================================================================
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  OpenDialog1.OptionsEx  := [];
  OpenDialog1.FileName   := '';
  if not OpenDialog1.Execute then exit;
  OpenDialog1.InitialDir := ExtractFileDir(OpenDialog1.FileName);

  LabeledEdit1.Text := OpenDialog1.FileName;
  LabeledEdit1.SelStart := Length(LabeledEdit1.Text);

  LabeledEdit2.Text := ChangeFileExt(ExtractFileName(LabeledEdit1.Text), '');
end;

//=============================================================================
//  指定したプログラムの実行時に
//  [ Windows セキュリティの重要な警告 ] ダイアログを表示しないようにする
//  ShellExecuteの使用にはusesにShellAPIが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LAppExePath : string;
  LRuleName   : string;
  LCmdPath    : string;
  LArgument   : string;
  LhInst      : HINST;
begin
  if Trim(LabeledEdit1.Text) = '' then exit;
  if Trim(LabeledEdit2.Text) = '' then exit;

  LAppExePath := LabeledEdit1.Text;
  LRuleName   := LabeledEdit2.Text;

  LCmdPath := 'cmd.exe';
  LArgument := '/c netsh advfirewall firewall add '
             + 'rule name=' + LRuleName + ' '
             + 'dir=in action=allow '
             + 'program=' + LAppExePath + ' '
             + 'enable=yes';

  //管理者権限が必要なので第2引数をrunasとしている
  LhInst :=  ShellExecute(Handle,
                          'runas',
                          PChar(LCmdPath),
                          PChar(LArgument),
                          nil,
                          SW_HIDE);
  if LhInst > 32 then begin
    //管理者に昇格して実行した
  end else begin
    //管理者に昇格しなかった
  end;
end;

//=============================================================================
//  指定したプログラムの実行時に
//  [ Windows セキュリティの重要な警告 ] ダイアログを表示するようにする
//  ShellExecuteの使用にはusesにShellAPIが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LAppExePath : string;
  LRuleName   : string;
  LCmdPath    : string;
  LArgument   : string;
  LhInst      : HINST;
begin
  if Trim(LabeledEdit1.Text) = '' then exit;
  if Trim(LabeledEdit2.Text) = '' then exit;

  LAppExePath := LabeledEdit1.Text;
  LRuleName   := LabeledEdit2.Text;

  LCmdPath := 'cmd.exe';
  LArgument := '/c netsh advfirewall firewall delete '
             + 'rule name=' + LRuleName + ' '
             + 'program=' + LAppExePath;

  //管理者権限が必要なので第2引数をrunasとしている
  LhInst :=  ShellExecute(Handle,
                          'runas',
                          PChar(LCmdPath),
                          PChar(LArgument),
                          nil,
                          SW_HIDE);
  if LhInst > 32 then begin
    //管理者に昇格して実行した
  end else begin
    //管理者に昇格しなかった
  end;
end;




03_Windows ファイアウォールを無効にする
plSetFWState.zip [439 KB] 2016年10月05日版 (説明なし,ソースコードなし)
本項に掲載しているサンプルコードの EXE ファイル。再配布自由


開発環境で、[Windows セキュリティの重要な警告] ダイアログが表示されるのが煩わしい場合は、このダイアログを表示しないようにすることもできます。その設定方法です。

[ファイル名を指定して実行] のダイアログで以下のコマンドを実行します。

control.exe /name Microsoft.WindowsFirewall /page PageConfigureSettings


表示されたダイアログで、[Windows ファイアウォールを無効にする (推奨できません)] を選択して、[OK] ボタンでダイアログを閉じます。コンピュータの再起動は必要ありません。


図6
ファイルウォールの有効化と無効化

netsh コマンドを使用すると、以下のように、ファイアウォールの有効と無効をプログラムのコードで設定できます。
allprofiles の代わりに privateprofile にすると、ホームまたは社内 (プライベート) ネットワークだけのファイアフォールの設定になり、publicprofile にすると、パブリックネットワークだけの設定となります。


[備考]
上の図の設定のカスタマイズの表示は自動更新はしません。ダイアログを表示したままでファイアウォールの設定を変更した場合は、[表示] [最新の情報に更新] をクリックして表示を更新する必要があります。


リスト2
システム全体でファイアウォールの無効と有効を切り換える
無効にすると [Windows セキュリティの重要な警告] ダイアログは表示されない
uses
  ShellAPI;

{$R *.DFM}

//=============================================================================
//  Windows ファイアウォールを無効にする
//  ShellExecuteの使用にはusesにShellAPIが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LExeFile  : String;
  LArgument : String;
  LhInst    : HINST;
begin
  LExeFile  := 'cmd.exe';
  LArgument := '/c netsh advfirewall set allprofiles state off';

  //管理者権限が必要なので第2引数をrunasとしている
  LhInst :=  ShellExecute(Handle,
                          'runas',
                          PChar(LExeFile),
                          PChar(LArgument),
                          nil,
                          SW_HIDE);
  if LhInst > 32 then begin
    //管理者に昇格して実行した
  end else begin
    //管理者に昇格しなかった
  end;
end;

//=============================================================================
//  Windows ファイアウォールを有効にする
//  ShellExecuteの使用にはusesにShellAPIが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  LExeFile  : String;
  LArgument : String;
  LhInst    : HINST;
begin
  LExeFile  := 'cmd.exe';
  LArgument := '/c netsh advfirewall set allprofiles state on';

  //管理者権限が必要なので第2引数をrunasとしている
  LhInst :=  ShellExecute(Handle,
                          'runas',
                          PChar(LExeFile),
                          PChar(LArgument),
                          nil,
                          SW_HIDE);
  if LhInst > 32 then begin
    //管理者に昇格して実行した
  end else begin
    //管理者に昇格しなかった
  end;
end;


上のコードは、コマンドプロンプトで、下図のようにコマンドを実行するのと同じです。
ただし、コマンドプロンプトは、管理者権限で起動する必要があります。


図7
コマンドラインでファイアウォールの無効化と有効化




04_ファイアウォールの許可リストにプログラムを追加/削除する


[ファイル名を指定して実行] のダイアログで以下のコマンドを実行すると、下図の [許可されたプログラム] のダイアログが表示されます。
  • [削除] をクリックすると選択中の項目が削除される
  • [設定の変更] をクリックすると許可等の変更が可能となる
  • [詳細] をクリックすると、プログラムのパス名等が確認できる
  • [別のプログラムの許可] をクリックすれば、別のプログラムを追加できる
ネット上には、これに関する多くの解説記事があります。参考リンクの記事はその例です。

control.exe /name Microsoft.WindowsFirewall /page pageConfigureApps



[備考]
下図の許可されたプログラムの表示は自動更新はしません。ファイアウォールの設定をプログラムで変更した場合は、[表示] [最新の情報に更新] をクリックして表示を更新する必要があります。
ダイアログを開き直せば更新した表示になります。


図8
ファイアウォールの許可リスト

本ページの最初のサンプルを実行して「セキュリティの重要な警告」のダイアログを表示しないようにすると下図のように設定されます。プログラムで設定した FTPTestProgram という名前があることが確認できます。



図9