職場の同僚に頼まれて、任意に選択したフォルダへのアクセスを禁止したり、それを解除したりするスクリプトを書いた。PowerShellの使い方を勉強すれば、フォルダの属性の変更は容易に実行できるから、セキュリティ対策として不完全なことは百も承知。
ダブルクリックでは開けないフォルダを作っただけなんだけれど、起動したPowerShellのWindowを閉じる部分でちょっとハマったので、備忘録として、ここにメモ。
フォルダへのアクセスを禁止したり、それを解除したりするスクリプトは、使い方を誤るとたいへんなコトになる(と思う)ので、ここには書かない。
【もくじ】
1.PowerShellを起動してスクリプトを実行
2.PowerShellのWindowを閉じる
3.PowerShellのWindowを表示しない方法もある
4.まとめ
5.お願いとお断り
1.PowerShellを起動してスクリプトを実行
PowerShellで実行したいスクリプトを用意する。ここではそれを「SetDeny.ps1」とした。Formに用意したEditコントロールのキャプションを次のように指定する。
スクリプトを実行するButtonを1つ用意。名前をButtonDeny、Captionを「変更」として、次の手続きを作成。
procedure TForm1.ButtonDenyClick(Sender: TObject);
var
strExeFile: string;
strParams: string;
begin
strExeFile:= 'PowerShell.exe';
strParams:= '-noExit -ExecutionPolicy RemoteSigned '+EditDeny.Text;
ShellExecute(0, '', PChar(strExeFile), PChar(strParams), nil, SW_SHOWNORMAL);
end;
実行(F9)すると・・・
スクリプトを実行したら、PowerShellのWindowも閉じたい。
2.PowerShellのWindowを閉じる
そこで上の手続きを次のように変更。
procedure TForm1.ButtonDenyClick(Sender: TObject);
var
strExeFile: string;
strParams: string;
hWndInstance: HWND;
begin
strExeFile:= 'PowerShell.exe';
strParams:= '-noExit -ExecutionPolicy RemoteSigned '+EditDeny.Text;
//ShellExecute(0, '', PChar(strExeFile), PChar(strParams), nil, SW_SHOWNORMAL);
hWndInstance:= ShellExecute(0, '', PChar(strExeFile), PChar(strParams), nil, SW_SHOWNORMAL);
//Windowの存在を確認
if hWndInstance > 32 then
begin
//タイムラグを設定
//Sleep(100); //短すぎる
Sleep(1000); //My環境では500でも動作した
//ExitとEnterキーの入力を送信
ButtonExitClick(Sender);
end;
end;
PowerShellのWindowを閉じる部分は、別の手続きにしないと期待した通りに動作しなかった・・・。
なんでかな?
procedure TForm1.ButtonExitClick(Sender: TObject);
var
hWndPSWindow: HWND;
begin
//PowerShellを閉じる
hWndPSWindow:=FindWindow(nil, PChar('Windows PowerShell'));
if hWndPSWindow <> 0 then
begin
SetForegroundWindow(hWndPSWindow);
//文字列の送信
SendKeys('Exit');
//Enterキーの送信
SendKeys(#13#10);
end else begin
ShowMessage('PowerShellのウィンドウが見つかりません!');
end;
end;
あと、最初は、PowerShellのWindowを探す部分を次のように書いていたんだけれど、これではWindowが見つからなくて・・・
hWndPSWindow:=FindWindow(nil, PChar('PowerShell'));
よく見たらPowerShellのタイトルは Windows PowerShell だった・・・
hWndPSWindow:=FindWindow(nil, PChar('Windows PowerShell'));
3.PowerShellのWindowを表示しない方法もある
自分的には「画面に何か動きがあった」方が安心できる気がしたので、PowerShellを表示する方法を選んだが、もちろん表示しない方法もある。いつもお世話になるMr.XRAYさんのWebページに詳しい解説がある。
Delphi で Windows PowerShell を使用する
http://mrxray.on.coocan.jp/Delphi/Others/PowerShellDelphi.htm#09
4.まとめ
(1)PowerShellに文字列を送信するには、FindWindow関数を使う。
(2)手続き的には、SetForegroundWindow関数とSendKeysを組み合わせて実行。
(3)PowerShellを閉じるタイミングはSleep関数で調整。
5.お願いとお断り
このサイトの内容を利用される場合は、自己責任でお願いします。ここに記載した内容を利用した結果、利用者および第三者に損害が発生したとしても、このサイトの管理者は一切責任を負えません。予め、ご了承ください。