Delphi Programming / Object Pascal
[掲載 2011年04月30日] [更新 2014年07月05日] Delphi サンプルプログラム集
469_各種ツール類の起動
動作確認等
Windows 7 U64(SP1) + Delphi XE(UP1) Pro, XE5(UP2) Pro
Windows Vista 以降用.一部は Windows XP でも表示可能
469_ShowTools.zip [3,510 KB] 2016年08月15日版 (EXE 同梱)
2011年05月02日
CreateProcess を使用して起動するコードに変更
cmd.exe /k を cmd.exe /c に修正(この修正がないと,cmd.exe がメモリ上に残ってしまう)
[04]を追加
2011年05月05日
Windows 7 の 32 ビット版と 64 ビット版の記事内容の間違いを修正
2011年10月31日
全体的に Windows 7 用に修正
NewStr 関数を関数内関数として String 型として処理するようにした (Unicode 対応策)
DEKO さんの,ざつだんの 08/01/13 の記事に,Vista ショートカット集があります.このショートカット集の [ツール] フォルダにあるツール類をリストから選択して,ShellExecute 関数で起動するようにしたサンプルです.
これらのツール類は,Vista にはあるが,Windows 7 ではなくなっていたり,変更となっているものもあります.Windows のエディションによっても動作しない場合があります.また,64 ビット版の Windows 7 では,32 ビット 64 ビット版の両方が用意されているもの,32 ビット版または 64 ビット版しか用意されていないものがあります.
このサンプルコードでは,環境変数を実際のパスに変換していますが,64 ビット版の Windows 7 の場合下表のようになっています.
Windows Vista にはあった以下のツール類は,Windows 7 では標準でインストールされません.代替ソフトがマイクロソフトのサイトからダウンロード可能になっていましたが,2019年08月16日現在の時点では入手できなくなっています.
Windows ミーティング スペース (代替ソフトは Microsoft Office Live Meeting)
Windows フォト ギャラリー (代替ソフトは Windows Live フォト ギャラリー)
Windows ムービー メーカー (代替ソフトは Windows Live ムービー メーカー)
Windows メール (代替ソフトは Windows Live メール)
Windows カレンダー(同上)
表1
64 ビット版 Windows 7 のプログラムフォルダとシステムフォルダ
フォルダ
説明
%ProgramFiles%
64bit 版の Windows では,プログラムは以下のフォルダにインストールされている(またはインストールされる)
32 ビット用のプログラムは,Program Files (x86)
64 ビット用のプログラムは,Program Files
32 ビット版の Windows では常に Program Files
32 ビット版の Windows には Program Files (x86) はない
%SystemRoot%\system32
64 ビット版の Windows では 64 ビット用のシステムフォルダ
32 ビット版の Windows では 32 ビット用
のシステムフォルダ
実フォルダ名は Windows\System32
64 ビット版の Windows では,このフォルダを指定しても,32 ビットのアプリは %SystemRoot%\SysWOW64 内のファイルを使用する (リダイレクト機能による)
%SystemRoot%\SysWOW64
64 ビット版の Windows では 32 ビット用のシステムフォルダ
32 ビット版の Windows にはない
実フォルダ名は Windows\SysWOW64
32 ビットのアプリは,%SystemRoot%\system32 を指定しても自動的にこちらにリダイレクトされる
%SystemRoot%\Sysnative
32 ビットアプリケーションから,64 ビットのシステムフォルダにアクセスするための仮想ディレクトリ
32 ビット版の Windows にはない
64 ビットのアプリからは使用できない
図1
実行画面
copy code
unit ShowToolsUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class (TForm)
ListBox1: TListBox;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ListBox1DblClick(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure ListBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private 宣言 }
FCmdPath : string ;
FCmdPara : string ;
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
uses
ShellAPI,
StrUtils;
{$R *.DFM}
// =============================================================================
// ListBox1に起動用の文字列をセット
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
// ---------------------------------------------------------------------------
// ListBox1に文字列と実行用のパス名をセット
// ---------------------------------------------------------------------------
procedure AddItem(ACaption, APath: String );
var
LpAddStr : PString;
begin
New(LpAddStr);
LpAddStr^ := APath;
ListBox1.AddItem(ACaption, TObject(LpAddStr));
end ;
// -----------------------------------------------------------------------------
var
LStringList : TStringList;
LPos : Integer;
LStrCaption : string ;
LStrPath : string ;
i : Integer;
begin
// 表示用の文字列とパス名を格納したファイルを読み込んで処理
LStringList := TStringList.Create;
try
LStringList.LoadFromFile('ToolsPathList.txt' );
for i := 0 to LStringList.Count - 1 do begin
LPos := Pos(',' , LStringList[i]);
LStrCaption := Copy(LStringList[i], 1 , LPos -1 );
LStrPath := Copy(LStringList[i], LPos + 1 , Length(LStringList[i]));
// ListBox1のItemに追加
AddItem(LStrCaption, LStrPath);
end ;
finally
FreeAndNil(LStringList);
end ;
ListBox1.ItemIndex := 0 ;
ListBox1Click(nil );
end ;
// =============================================================================
// ListBox1のオブジェクトを破棄
// =============================================================================
procedure TForm1.FormDestroy(Sender: TObject);
var
i : Integer;
begin
for i := 0 to ListBox1.Items.Count - 1 do begin
Dispose(PString(ListBox1.Items.Objects[i]));
end ;
end ;
// =============================================================================
// ListBox1のOnDblClickイベント処理
// ListBoxで選択しているツールを起動
// =============================================================================
procedure TForm1.ListBox1DblClick(Sender: TObject);
var
LRetCode : Integer;
begin
if ListBox1.ItemIndex < 0 then exit;
if FCmdPath = '' then exit;
LRetCode := ShellExecute(Handle, '' , PChar(FCmdPath), PChar(FCmdPara), nil , SW_SHOW);
if LRetCode <=32 then begin
MessageBox(Handle, PChar(SysErrorMessage(LRetCode)), '情報' , MB_ICONINFORMATION);
end ;
end ;
// =============================================================================
// ListBox1のOnClickイベント処理
// 選択項目のShellExecute関数に渡す引数の文字列を作成
// =============================================================================
procedure TForm1.ListBox1Click(Sender: TObject);
// ---------------------------------------------------------------------------
// 環境変数を含む(%等の文字を含む)を実際のパス名に変換
// ---------------------------------------------------------------------------
function ExpandEnvironmentString(S: String ): String ;
var
LDstChar : array [0 ..MAX_PATH - 1 ] of Char;
begin
ExpandEnvironmentStrings(PChar(S), LDstChar, MAX_PATH);
Result := LDstChar;
end ;
// ---------------------------------------------------------------------------
var
LStringList : TStringList;
LOriginCmd : string ;
LEnvPath : string ;
begin
if ListBox1.ItemIndex < 0 then exit;
// 選択中のItems文字列を取得してコマンド文字列を作成
LOriginCmd := Trim(PString(ListBox1.Items.Objects[ListBox1.ItemIndex])^);
LEnvPath := ExpandEnvironmentString(LOriginCmd);
// 実行ファイル名とパラメータに分解
LStringList := TStringList.Create;
try
LStringList.Delimiter := ' ' ;
LStringList.StrictDelimiter := True;
LStringList.DelimitedText := LEnvPath;
if LStringList.Count = 1 then begin
FCmdPath := Trim(LEnvPath);
FCmdPara := '' ;
end else begin
FCmdPath := Trim(LStringList[0 ]);
FCmdPara := Trim(StringReplace(LEnvPath, FCmdPath, '' , [rfIgnoreCase]));
end ;
finally
FreeAndNil(LStringList);
end ;
// パス名の空白までをパスと認識してしまうのでダブルクォーテーションで囲む
// パラメータはそのままとする
if Pos(' ' , FCmdPath) > 1 then begin
if LeftStr(FCmdPath, 1 ) <> '"' then begin
FCmdPath := AnsiQuotedStr(FCmdPath, '"' );
end ;
end ;
Edit1.Text := LOriginCmd;
end ;
// =============================================================================
// ListBox1のOnKeyDownイベント処理
// =============================================================================
procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if ListBox1.ItemIndex < 0 then exit;
if Key = VK_RETURN then begin
ListBox1DblClick(nil );
Key := 0 ;
end ;
end ;
end .
以下は Delphi XE2 でプラットフォームを Win64,つまり VCL-64 でコンパイルした EXE ファイルをを主に,Windows 7 Ultimate の 64 ビット版で実行した結果です.
各々の図の上のバス名は,実際に ShellExecute 関数の引数に使用した文字列です.この文字列は「ファイル名を指定して実行」のダイアログで実行できます.
%SystemRoot%\System32\FXSCOVER.exe
図2
FAX 送付状エディタ
"%Programfiles%\Internet Explorer\iexplore.exe"
図3
Internet Explorer
%SystemRoot%\system32\SnippingTool.exe
図4
Snipping Tool
図5
Snipping Tool
このサンプルプログラムの実行画面をキャプチャーしたところ
"%SystemRoot%\Help\Tablet PC\TouchTraining.exe"
図6
Tablet PC タッチトレーニング
Windows Vista にある
Windows 7 にはない
"%SystemRoot%\Help\Tablet PC\PenTraining.exe"
図7
Tablet PC ペンのトレーニング
Windows Vista にある
Windows 7 にはない
"%CommonProgramFiles%\Microsoft Shared\Ink\TabTip.exe"
図8
Tablet PC 入力パネル
[ツール] [終了]で 終了なので注意
[×] は隅の方に移動するだけ
"C:\Program Files\DVD Maker\DVDMaker.exe"
図9
Windows DVD メーカー
%SystemRoot%\system32\WFS.exe
図10
Windows FAX とスキャン
"C:\Program Files\Windows Journal\Journal.exe"
図11
Windows Journal
%SystemRoot%\ehome\ehshell.exe
図12
Windows Media Center
"C:\Program Files\Windows Media Player\wmplayer.exe" /prefetch:1
図13
Windows Media Player
"%ProgramFiles%\Windows Mail\wab.exe"
図14
Windows アドレス帳
"%ProgramFiles%\Windows Calendar\wincal.exe"
図15
Windows カレンダー
Windows Vista にある
Windows 7 にはない
%ProgramFiles%\Windows Photo Gallery\WindowsPhotoGallery.exe"
図16
Windows フォトギャラリー
"%programfiles%\Windows Collaboration\WinCollab.exe"
図17
Windows ミーティングスペース
"%ProgramFiles%\Movie Maker\MovieMk.exe"
図18
Windows ムービーメーカー
Windows Vista にある
Windows 7 にはない
Windows XP でも表示可能
"%Programfiles%\Windows Mail\WinMail.exe"
図19
Windows メール
"%Programfiles%\Windows Live\Mail\wlmail.exe"
図20
Windows Live メール
Windows 7 用にマイクロソフトが提供しているメーラー
筆者のは 32 ビット版なので,64 ビットのアプリからは起動できない
%SystemRoot%\Speech\Common\sapisvr.exe -SpeechUX
図21
Windows 音声認識
%SystemRoot%\system32\migwiz\migwiz.exe
図22
Windows 転送ツール
%SystemRoot%\system32\wbem\wbemtest.exe
図23
WMI テスト
%SystemRoot%\system32\eventvwr.msc /s
図24
イベントビューア
%SystemRoot%\explorer.exe
図25
エクスプローラ
%SystemRoot%\System32\SoundRecorder.exe
図26
サウンドレコーダ
%SystemRoot%\System32\msdt.exe
図27
サポート 診断ツール
%systemroot%\system32\rstrui.exe
図28
システムの復元
%SystemRoot%\system32\osk.exe
図29
スクリーンキーボード
%SystemRoot%\System32\taskmgr.exe
図30
タスクマネージャ
%SystemRoot%\system32\cleanmgr.exe
図31
ディスククリーンアップ
%SystemRoot%\system32\dfrgui.exe
図32
ディスクデフラグ ツール
%SystemRoot%\System32\Narrator.exe
図33
ナレーター
%SystemRoot%\system32\NetProj.exe
図34
ネットワーク プロジェクタ接続
%systemroot%\system32\sdclt.exe
図35
バックアップと復元
%SystemRoot%\system32\rundll32.exe %SystemRoot%\system32\shell32.dll,OpenAs_RunDLL ABC.txt
図36
ファイルを開くプログラム選択
%windir%\system32\rundll32.exe shell32.dll,#61
explorer.exe shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}
図37
ファイル名を指定して実行
Windows XP でも表示可能
最初のコマンドでは説明文が表示されない (Windows XP では表示される)
%SystemRoot%\system32\mspaint.exe
図38
ペイント
"%SystemRoot%\HelpPane.exe -Embedding"
図39
ヘルプとサポート
図40
ヘルプとサポート
%SystemRoot%\system32\MdSched.exe
図41
メモリ 診断ツール
%SystemRoot%\system32\notepad.exe
図42
メモ帳
%SystemRoot%\System32\credwiz.exe
図43
ユーザー名およびパスワード保存
%SystemRoot%\System32\msra.exe
図44
リモートアシスタンス
%SystemRoot%\System32\mstsc.exe
図45
リモートデスクトップ
図46
レジストリエディタ
Windows XP でも表示可能
64 ビット版の Windows で 32 ビットのレジストリエディタを起動するには,
%SystemRoot%\SysWOW64\Regedit
を実行する
"%ProgramFiles%\Windows NT\Accessories\wordpad.exe"
図47
ワードパッド
%SystemRoot%\System32\SndVol.exe
図48
音量ミキサ
%SystemRoot%\System32\eudcedit.exe
図49
外字エディタ
%SystemRoot%\System32\Magnify.exe
図50
拡大鏡
"%CommonProgramFiles%\Microsoft Shared\Ink\mip.exe"
図51
数式パネル
%SystemRoot%\system32\calc.exe
図52
電卓
Windows XP でも表示可能
Windows XP と Windows 7 の電卓は,EXE 名は同じだが,全く別のアプリ
%SystemRoot%\System32\StikyNot.exe
図53
付箋
%SystemRoot%\system32\charmap.exe
図54
文字コード表
%SystemRoot%\system32\slui.exe
図55
Windows ライセンス認証
%SystemRoot%\system32\Rundll32.exe shell32.dll,SHHelpShortcuts_RunDLL Connect
図56
ネットワークドライブの割り当て
%SystemRoot%\system32\ComputerDefaults.exe
図57
プログラムのアクセスとコンピューターの既定の設定
%SystemRoot%\System32\MRT.exe
図58
悪意のあるソフトウェアの削除ツール
ツール類,システム関係ダイアログのコマンドラインは,以下のように,[スタート] メニューから調べることができます.
同じ名前のツール,機能であっても,Windows XP, Windows Vista, Windows 7 によって,環境変数名,実際のパス名が違うことがあります.また,アプリケーションで使用する時は,実パスではなく,環境変数を含む値にしておき,実行時に実パスに変換した方が無難です.OS のバージョンにる違いによるトラブルを防止できる可能性があります.
図59
プロパティダイアログを表示
対象のツール等上でマウス右ボタンクリックで [プロパティ] を選択
図60
リンク先をコピー
コピーしたパスの文字列をコマンドラインの引数に使用する
04_ FAX と画像ビューア・フォトビューアの起動
Windowsでは,デフォルトの設定で,拡張子が .JPG の画像ファイルをダブルクリックすると,画像を表示するツールが付属しています.この画像を表示するソフトは,
Windows XP では [FAXと画像ビューア]
Vista では [Windows フォトギャラリー]
Windows 7 では [Windows フォトビューア]
となっています.
次のテストプログラムでは,Edit1 に入力したファイルの画像を表示します.XP,Vista,7 のどのバージョンの Windows でも動作します.
Windows XP の [FAX と画像ビューア] は,1 つ だけしか起動できません.一方,Vista と 7 では起動するたびに別のウィンドウが開きます.画像ごとにウィンドウが開けないのか,という質問がネット上で結構ありました.Vista 以降,この要望に応えた形となっているようです.
1 つしか起動できない仕様のままだと,複数起動することができませんが,複数起動できれば,既に起動しているウィンドウを閉じれば 1 つだけが起動している状態にすることもできます.
[備考]
本サンプルを Windows 7 で実行すると Windows フォトビューアが起動しますが,実際の Windows フォトビューアは別の場所にあります.それが起動します.
図61
設計時画面
図62
実行画面
Edit1 に,表示する画像のフルパスをセットしておく
図63
Windows 7 での実行例
図64
Windows Vista での実行例
図65
Windows XP での実行例
リスト2
FAX と画像ビューア・フォトビューアの起動
copy code
unit ShowPhotoViewerUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class (TForm)
Button1: TButton;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// -----------------------------------------------------------------------------
// コマンドラインのコマンドを実行する関数
// 起動は待たない.またツール類の終了も待たない.
// -----------------------------------------------------------------------------
function RunCommmadLine(CommandLine: string ): DWORD;
var
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0 );
StartupInfo.cb := sizeof(TStartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
// これがないとコマンドプロンプトのウィンドウが表示されてしまう
// この指定を有効にするためには,dwFlagsにSTARTF_USESHOWWINDOWを指定する
StartupInfo.wShowWindow := SW_HIDE;
// 参照カウンタ対策
UniqueString(CommandLine);
if not CreateProcess(nil ,
PChar(CommandLine),
nil ,
nil ,
True,
CREATE_NEW_CONSOLE,
nil ,
nil ,
StartupInfo,
ProcessInfo) then begin
Result := WAIT_FAILED
end else begin
GetExitCodeProcess(ProcessInfo.hProcess, Result);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end ;
end ;
// =============================================================================
// Edit1に表示する画像ファイルのフルパスをセット
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Text := ExtractFilePath(Application.ExeName) + 'RIMG0414.JPG' ;
end ;
// =============================================================================
// ボタンクリックしたらEdit1に入力されている画像ファイルを表示
// CreateProcessでコマンドプロンプトの引数にフォトビューアを指定して起動
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
Rundll32ExePath : String ;
ViewerdllPath : String ;
ImagePath : String ;
ACmdStr : String ;
begin
// ShellExecute,ShellExecuteExを使用すれば,Rundll32.exeのフルパス不要
Rundll32ExePath := '"C:\Windows\system32\Rundll32.exe " ' ;
ViewerdllPath := '%SystemRoot%\system32\shimgvw.dll, ImageView_Fullscreen ' ;
ImagePath := Trim(Edit1.Text);
Screen.Cursor := crHourGlass;
try
// コマンド文字列を作成
ACmdStr := 'cmd.exe /c ' + Rundll32ExePath + ViewerdllPath + ImagePath;
RunCommmadLine(ACmdStr);
finally
Screen.Cursor := crDefault;
end ;
end ;
end .
リスト3
FAX と画像ビューア・フォトビューアの起動
ShellExecute 関数で起動する例
copy code
unit ShowPhotoViewerUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls,ShellAPI, ExtCtrls;
type
TForm1 = class (TForm)
Button1: TButton;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// =============================================================================
// Edit1に表示する画像ファイルのフルパスをセット
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Text := ExtractFilePath(Application.ExeName) + 'RIMG0414.JPG' ;
end ;
// =============================================================================
// ボタンクリックしたらEdit1に入力されている画像ファイルを表示
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
ViewerdllPath : String ;
ImagePath : String ;
begin
ViewerdllPath := 'C:\Windows\system32\shimgvw.dll, ImageView_Fullscreen ' ;
ImagePath := Trim(Edit1.Text);
ShellExecute(Handle,
'OPEN' ,
'Rundll32.exe' ,
PChar(ViewerdllPath + ImagePath),
nil ,
SW_SHOWNORMAL);
end ;
end .
05_ 16 ビットアプリ時代の WinExec 関数を使用する場合
16 ビット版の Windows 3.1 時代の WinExec 関数も利用可能ですが,引数の文字列を AnsiString 型にしないと機能しません.WinExec 関数はユニコード文字を認識しません.Delphi 2007 以前であれば String 型でも動作します.
Delphi 2007 以前の非ユニコード版の Delphi の String 型は,AnsiString 型を意味します.
わざわざ,新たに WinExec 関数を使用する必要性は全くありません.
リスト4
FAX と画像ビューア・フォトビューアの起動
WinExec 関数を使用した例
copy code
unit ShowPhotoViewerUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TForm1 = class (TForm)
Button1: TButton;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end ;
var
Form1: TForm1;
implementation
{$R *.DFM}
// =============================================================================
// Edit1に表示する画像ファイルのフルパスをセット
// =============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Text := ExtractFilePath(Application.ExeName) + 'RIMG0414.JPG' ;
end ;
// =============================================================================
// ボタンクリックしたらEdit1に入力されている画像ファイルを表示
// WinExecの文字列引数はAnsiStringでないと動作しない
// Delphi 2007以前であればString型でも動作する
// =============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
ViewerdllPath : AnsiString;
ImagePath : AnsiString;
CmdLine : AnsiString;
begin
ViewerdllPath := 'C:\Windows\system32\shimgvw.dll, ImageView_Fullscreen ' ;
ImagePath := Trim(Edit1.Text);
CmdLine := 'Rundll32.exe ' + ViewerdllPath + ImagePath;
WinExec(PAnsiChar(CmdLine), SW_SHOWNORMAL);
end ;
end .
06_ mshta.exe による HTML ファイルの表示 - 実行には要注意
mshta.exe の引数に HTML ファイルのアドレスを指定して実行すると,ステータスバーやメニュー等がないダイアログ形式でページを表示できます.下図は,以下のコマンドで当サイトのトップページを表示した例です.
mshta.exe http://mrxray.on.coocan.jp/index.htm
mshta.exe は IE の付属ツールの一部です.主に,拡張子が .hta
というファイルを実行する用途で使われています.
mshta.exe では,IE
(Internet Explorer) で実装されているセキュリティ機能は適用されません.そのため,mshta.exe で外部のサイトのウェブページにアクセスした場合,悪質なスクリプト等によってコンピュータをリモートコントロールされてしまう被害を受けることがあります.
ワンクリック詐欺 (ワンクリックウェア) と呼ばれるポップアップメニューの表示も,HTA ファイルで提供されていることがあります.これらの HTA ファイルを mshta.exe が表示します.
図66
mshta.exe によるウェブページの表示