Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Delphiで多重起動の禁止

84 views
Skip to first unread message

Masanori Yamamoto

unread,
Aug 4, 1997, 3:00:00 AM8/4/97
to

やまもとです

Delphi 1.0Jでプログラムの多重起動防止の為に下記の様に
記述していたのですがDelphi 3.0では機能しません
どなたか別の方法を知っている方教えてください

program test;
uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
{$R *.RES}

begin
if hprevinst=0 then begin
Application.Initialize;
Application.Title := 'TEST PROGRAM';
Application.CreateForm(TForm1, Form1);
Application.Run;
end;
end.

--
/**********************************************************
* 山本 政則 ( Masanori Yamamoto ) #P/N-ML0003T#*
* *
* E-mail: man...@fsinet.or.jp *
* Web : http://www.fsinet.or.jp/‾mannori/ *
**********************************************************/

TRINITY

unread,
Aug 4, 1997, 3:00:00 AM8/4/97
to

| Delphi 1.0Jでプログラムの多重起動防止の為に下記の様に
| 記述していたのですがDelphi 3.0では機能しません
| どなたか別の方法を知っている方教えてください
|
| program test;
| uses
| Forms,
| Unit1 in 'Unit1.pas' {Form1},
| {$R *.RES}
|
| begin
| if hprevinst=0 then begin
| Application.Initialize;
| Application.Title := 'TEST PROGRAM';
| Application.CreateForm(TForm1, Form1);
| Application.Run;
| end;
| end.

Delphi3.0のせいではなくて、Windows95では、
hprevinstにある決まった値(何だったかは忘れた)
しか返さないので、この方法が使えません。
チェックする方法は、以下の通りです。

プロジェクトソース(*.dprファイル)

program ********;

uses
Forms,
Windows,
**** in '*.pas' {*};

var //<-----
Mutex: THandle; //<-----

begin
Mutex:=CheckInstance //<-----
if Mutex=0 then //<-----
exit; //<-----
Application.Initialize;
Application.Title := '********';
Application.CreateForm(T*,*);
.
.
.
Application.Run;
ReleaseMutex(Mutex); //<-----
end.

*.pasファイル
(*.dprファイルのuses節で宣言されているもの)

unit *******

interface

uses
Windows, Messages, Classes, Sysutils,...;

type
T**** = class(TForm)
***: T**;
.
.
procedure ********;
procedure ********;
function ********;
.
.

private
{private }
public
{public }
end;

var
*:T*;
.
.

const
.
.

function CheckInstance:THandle; //<-----

implementation

{$R *.DFM}

function CheckInstance:THandle; //<-----
var Mutex:THandle; //<-----
begin //<-----
Result:=0; //<-----
Mutex:=OpenMurex(MUTEX_ALL_ACCESS, //<-----
False,PChar(Application.Title)); //<-----
if Mutex<>0 then //<-----
begin //<-----
CloseHandle(Mutex); //<-----
Exit; //<-----
end //<-----
else //<-----
Result:=CreateMutex(Nil,False, //<-----
PChar(Application.Title)); //<-----
end; //<-----

この中で、//<-----が付いている行を追加します。
追加する場所は、必ずこのとおりにしてください。
そうしないとDelphiのコンパイラに怒られます^^;。
これで、二重起動を防止できます。
ちなみに、//で<-----をコメントアウトしているので、
このままエディタにコピペして、そのままコンパイルできます。
なお、varで、変数宣言してあるものは、
お好みの名前に変更できます。

--
手塚宏之(TRINITY)
東京電子専門学校情報処理科3年制 2年
E-Mail:<f509...@ca.aif.or.jp>
WEB Page:<http://www.vector.co.jp/authors/VA011063/>


Masayuki Miura

unread,
Aug 5, 1997, 3:00:00 AM8/5/97
to

ちなみに、MSVB(4.2, 5.0)での多重起動の禁止は
どういったコードになるのでしょうか?

--
セイコー・イージーアンドジー株式会社
設計部 設計課
Tel. 047-392-7818 Fax. 047-391-0985
三浦 正之(E-mail:masayuk...@sii.co.jp)


YUTANI Miki

unread,
Aug 5, 1997, 3:00:00 AM8/5/97
to

最近少なくなってきたと思ったのに…。

In article <5s4s59$q...@news.aif.or.jp> "TRINITY" <f509...@ca.aif.or.jp> writes:

> Delphi3.0のせいではなくて、Windows95では、
> hprevinstにある決まった値(何だったかは忘れた)
> しか返さないので、この方法が使えません。

これはそうなんですが、

> チェックする方法は、以下の通りです。
(snip)


> function CheckInstance:THandle; //<-----
> var Mutex:THandle; //<-----
> begin //<-----
> Result:=0; //<-----
> Mutex:=OpenMurex(MUTEX_ALL_ACCESS, //<-----
> False,PChar(Application.Title)); //<-----

(snip)


> この中で、//<-----が付いている行を追加します。
> 追加する場所は、必ずこのとおりにしてください。
> そうしないとDelphiのコンパイラに怒られます^^;。

実際に通していないコードをその断りなく記すのも問題なのですが、
そういった一般的な問題点をさしひいても間違っています。

> これで、二重起動を防止できます。

できません。
OpenMutex() を使っては全然解決になりません。
オペレーティングシステムの教科書などで
同期処理を復習してください。

正しくは、CreateMutex() して
GetLastError() が ERROR_ALREADY_EXISTS か否かを調べます。

--
YUTANI Miki
mailto:yu...@kt.rim.or.jp
http://www.kt.rim.or.jp/~yuta/

TAMAKI Masahiko

unread,
Aug 5, 1997, 3:00:00 AM8/5/97
to

こんにちは。玉城です。

Masayuki Miura <masayuk...@sii.co.jp> wrote in article
<5s5rl9$s...@orange.sii.co.jp>...
> ちなみに、MSVB(4.2, 5.0)での多重起動の禁止は
> どういったコードになるのでしょうか?

Visual Basicに4.2というバージョンはないのですが...
ま、その話は置いといて

http://www.vector.co.jp/authors/VA010786/
[Basic Technique]というコーナーにそういうサンプルが載っています。

_/_/_/ 玉城真彦 tam...@tinet-i.ne.jp
_/_/_/ Visual Basic増強作戦 http://www.vector.co.jp/authors/VA010786/

TRINITY

unread,
Aug 5, 1997, 3:00:00 AM8/5/97
to

YUTANI Miki <yu...@jade.dti.ne.jp> wrote in article
<5s5s1d$rqk$1...@news2.dti.ne.jp>...


| > チェックする方法は、以下の通りです。
| (snip)
| > function CheckInstance:THandle; //<-----
| > var Mutex:THandle; //<-----
| > begin //<-----
| > Result:=0; //<-----
| > Mutex:=OpenMurex(MUTEX_ALL_ACCESS, //<-----
| > False,PChar(Application.Title)); //<-----
| (snip)
| > この中で、//<-----が付いている行を追加します。
| > 追加する場所は、必ずこのとおりにしてください。
| > そうしないとDelphiのコンパイラに怒られます^^;。
|
| 実際に通していないコードをその断りなく記すのも問題なのですが、

私が作ってるプログラムの二重起動防止は、
全てこの方法を使っています。
そして、二重起動は確実に防がれています
(一瞬タスクバーにアイコンが表示されるもののすぐに終了する)。

| OpenMutex() を使っては全然解決になりません。
| オペレーティングシステムの教科書などで
| 同期処理を復習してください。
|
| 正しくは、CreateMutex() して
| GetLastError() が ERROR_ALREADY_EXISTS か否かを調べます。

TECH Win 1997年2月号のDelphi講座で、
謎の全治氏こと、服部誠氏が書かれているコードは、
これと同じ物(というよりも、それをそのまま利用)です。
また、ほかの記事で、
http://www.niftyserve.or.jp/forum/fdelphi/
を参照のこと、とあるのがありますが、
そこでも(FindWindowが入っているものの)
基本的には同じであるようです。

#ほかにもFindWindowなどもあるけど、それを使うと
#何かしない限り、デバッグができない(コンパイル・
#実行したとたんに終了してしまうから)。
#私の場合は、コマンドラインオプションを使いましたが。

Hiki Takehito

unread,
Aug 5, 1997, 3:00:00 AM8/5/97
to

こんにちは。

> Delphi 1.0Jでプログラムの多重起動防止の為に下記の様に
> 記述していたのですがDelphi 3.0では機能しません
> どなたか別の方法を知っている方教えてください

 Delphi User's Folumに書いてあります。

http://www.niftyserve.or.jp/forum/fdelphi/


+[] Signature.pas ------------------------------------------_DX+

Name := '比企 剛仁';
E-Mail := f849...@ca.aif.or.jp ;
HomePage := http://www.vector.co.jp/authors/VA009712/take/ ;

{ FreeのWin95環境設定ツール「Change-moi 2.12a」はいかが? }
+=============================================================/+

YUTANI Miki

unread,
Aug 6, 1997, 3:00:00 AM8/6/97
to

In article <5s70bq$2...@news.aif.or.jp> "Hiki Takehito" <f849...@ca.aif.or.jp> writes:

> > Delphi 1.0Jでプログラムの多重起動防止の為に下記の様に
> > 記述していたのですがDelphi 3.0では機能しません
> > どなたか別の方法を知っている方教えてください
>  Delphi User's Folumに書いてあります。
> http://www.niftyserve.or.jp/forum/fdelphi/

上記 Web ページに書いてあるような
FindWindow() や OpenMutex() を使う方法ですと、
完全に二重起動を禁止することはできません。
2 個のプロセスがほとんど同時にこれらの API を
くぐりぬけてしまう可能性があるからです。

くぐりぬけを防ぐためには、いきなり CreateMutex() して
GetLastError() が ERROR_ALREADY_EXISTS かどうかを調べる
方法にする必要があります。
私が Delphi Mailing List に入っていた頃 (1996年9 or 10月頃?) に
サンプルコードを流した憶えがありますので
どこかに残っているかもしれません。

また、同等の処理を C で書いたものを
<URL:news:YUTA.97Fe...@uranus.kt.rim.or.jp>
で見ることができます。

Hiki Takehito

unread,
Aug 6, 1997, 3:00:00 AM8/6/97
to

こんにちは。

> くぐりぬけを防ぐためには、いきなり CreateMutex() して
> GetLastError() が ERROR_ALREADY_EXISTS かどうかを調べる
> 方法にする必要があります。

 こんな感じで作ってみましたが、見て下さいませんか。

program Exitwin;

uses
Forms,
Windows,
Exit in 'Exit.pas' {frmExit};

{$R *.RES}

const
hApp='ExitWin';
Msg='起動済みです。';
begin
CreateMutex(nil, False, hApp);
if GetLastError()<>ERROR_ALREADY_EXISTS then
begin
Application.Initialize;
Application.CreateForm(TfrmExit, frmExit);
Application.Run;
end
else
MessageBox(0,PChar(Msg),nil,MB_OK or MB_ICONERROR);
end.

 これで動かしてみましたが、二重起動を防止できました。

Hiki Takehito

unread,
Aug 8, 1997, 3:00:00 AM8/8/97
to

こんにちは。

> ええ、こんなかんじです。
> 気になる点は、hAppはもっと複雑な名前 (たとえば GUID) にしたほうがいい、とか
> CreateMutex の戻り値も見たほうがいいのでは、といったところくらいです。

 了解しました。

> >  これで動かしてみましたが、二重起動を防止できました。
>
> 1番目のプロセスをデバッグ実行して Application.Initialize の行でブレークし、
> そのまま2番目のプロセスをコマンドライン実行してみてください。
> それでも二重起動しなければオーケーです。

 やってみたところ二重起動しませんでした。

 ご忠告に感謝いたします。では。

0 new messages