2026/01/15(木) [n年前の日記]
#1 [delphi] Delphiで多重起動禁止処理をしたい
Delphi 12 で多重起動禁止処理をしたい。Mutex とやらを使えばいいらしいけど…。
こんな感じでいいのだろうか。コンソールアプリとして作成して試してみた。
ググっていたら OpenMutex() を使う事例も見かけたけれど、タイミング的にすり抜けてしまう時があるとかなんとか…。多重起動禁止をしたいだけならいきなり CreateMutex() を呼んでしまっていいらしい。
CreateMutex() の第2引数に True を指定して所有権なるものを要求する事例も見かけたけれど、単に多重起動禁止をしたいだけなら False を与えてしまっていいらしい。その場合、所有権は持ってないから ReleaseMutex() も呼ばなくていい、とAIが言っている。ただ、ハンドルは持ってしまっているから CloseHandle() は呼ばないといけない。
コマンドプロンプトを2つ起動して、多重起動してしまうか確認してみたけれど、ちゃんと多重起動禁止状態になってくれた。
こんな感じでいいのだろうか。コンソールアプリとして作成して試してみた。
program DelphiMutexTest1;
{$APPTYPE CONSOLE}
{$R *.res}
{ 多重起動禁止処理のテスト。Delphiコンソールアプリ }
uses
System.SysUtils,
Winapi.Windows;
var
hMutex: THandle;
const
APPLIMUTEXID = 'MyConsoleApp_SingleInstance_Mutex';
begin
try
{
Mutex を作成して多重起動禁止処理を行う。
第二引数を True にすると所有権を要求するが、
False なら所有権を要求しない。
多重起動を禁止するだけなら所有権までは要らないらしい。
}
hMutex := CreateMutex(nil, False, PChar(APPLIMUTEXID));
if hMutex = 0 then
begin
Writeln('Error : CreateMutex() に失敗。終了します。');
{ ハンドルを取得できてないので CloseHandle() は呼ばなくていい }
Exit;
end;
if GetLastError = ERROR_ALREADY_EXISTS then
begin
Writeln('既にアプリが起動しています。終了します。');
{ ハンドルは取得しているので CloseHandle() を呼ぶ }
CloseHandle(hMutex);
Exit;
end;
try
Writeln('アプリを起動しました。');
Writeln('Press Enter to Exit.');
Readln;
finally
if hMutex <> 0 then
begin
{
所有権を持っているなら ReleaseMutex() をしないといけない。
今回 CreateMutex() で所有権を要求していないので、
ReleaseMutex() はしなくていい
}
// ReleaseMutex(hMutex);
{ ハンドルは取得しているので CloseHandle() を呼ぶ }
CloseHandle(hMutex);
Writeln('Mutex を解放しました。');
end;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
- uses のところに Winapi.Windows を追加して、CreateMutex() を使う。
- CreateMutex() に渡す識別名?が string なら、PChar() で囲まないといけない。直接 '...' で書くなら PChar() は不要。
ググっていたら OpenMutex() を使う事例も見かけたけれど、タイミング的にすり抜けてしまう時があるとかなんとか…。多重起動禁止をしたいだけならいきなり CreateMutex() を呼んでしまっていいらしい。
CreateMutex() の第2引数に True を指定して所有権なるものを要求する事例も見かけたけれど、単に多重起動禁止をしたいだけなら False を与えてしまっていいらしい。その場合、所有権は持ってないから ReleaseMutex() も呼ばなくていい、とAIが言っている。ただ、ハンドルは持ってしまっているから CloseHandle() は呼ばないといけない。
コマンドプロンプトを2つ起動して、多重起動してしまうか確認してみたけれど、ちゃんと多重起動禁止状態になってくれた。
[ ツッコむ ]
#2 [delphi] Delphiでexeを生成したらscrも作りたい
Delphi 12 で、プロジェクトをビルドして .exe を生成したら、その .exe をリネームコピーして .scr も作りたい。
プロジェクトのオプションの「ビルドイベント」で、ビルド後イベントとしてファイルコピーを指定することができるっぽい。
プロジェクト → オプション → ビルド → ビルドイベント → ビルド後イベント → コマンド。以下を打ちこんでみた。
プロジェクトのオプションの「ビルドイベント」で、ビルド後イベントとしてファイルコピーを指定することができるっぽい。
プロジェクト → オプション → ビルド → ビルドイベント → ビルド後イベント → コマンド。以下を打ちこんでみた。
copy /Y "$(OUTPUTPATH)" "$(OUTPUTDIR)$(OUTPUTNAME).scr"
- DOSコマンドの copy を使ってファイルコピーする。
- 「/Y」は上書き確認無しの指定。
- $(OUTPUTPATH) は、生成される .exe のファイルパス。
- $(OUTPUTDIR) は、出力先ディレクトリのパス。最後に「\」 がついてる。
- $(OUTPUTNAME) は、出力ファイルの拡張子無しの名前。
[ ツッコむ ]
#3 [delphi] Delphiでビルドしたexeにアイコンを指定したい
Delphi 12 でビルドした .exe にアイコンを指定したい。
- プロジェクト → オプション → アプリケーション → アイコン。
- ターゲットを選んでおいて、「アイコンの読み込み」をクリック。
- ファイル選択ダイアログで .ico を選択。
- プロジェクトのディレクトリにコピーするか? みたいな感じで尋ねてくるのでコピーを選ぶ。
◎ アイコン画像の作成 :
アイコン画像は、Inkscape で作成して png としてエクスポートして、Greenfish Icon Editor Pro Portable で開いてアイコン化した。
_Greenfish Icon Editor Pro 4.5 - Official Website
_Greenfish Icon Editor Pro Portable | PortableApps.com
_「Greenfish Icon Editor Pro」多機能なアイコン・カーソル作成ソフト - 窓の杜
自分、PortableApps版を使っていたものと思い込んでいたけれど、公式の Portable版(.zip版)を使ってたっぽい。zipを解凍して gfie.exe を実行すれば起動する。
Settings → Language...、を選べば日本語化できる。
ウインドウに png画像をドラッグアンドドロップすれば画像を開ける。アイコン → イメージからWindows用のアイコンを作成、を選べばアイコンが生成できる。
_Greenfish Icon Editor Pro 4.5 - Official Website
_Greenfish Icon Editor Pro Portable | PortableApps.com
_「Greenfish Icon Editor Pro」多機能なアイコン・カーソル作成ソフト - 窓の杜
自分、PortableApps版を使っていたものと思い込んでいたけれど、公式の Portable版(.zip版)を使ってたっぽい。zipを解凍して gfie.exe を実行すれば起動する。
Settings → Language...、を選べば日本語化できる。
ウインドウに png画像をドラッグアンドドロップすれば画像を開ける。アイコン → イメージからWindows用のアイコンを作成、を選べばアイコンが生成できる。
[ ツッコむ ]
以上、1 日分です。