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/ *
**********************************************************/
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/>
--
セイコー・イージーアンドジー株式会社
設計部 設計課
Tel. 047-392-7818 Fax. 047-391-0985
三浦 正之(E-mail:masayuk...@sii.co.jp)
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/
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/
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などもあるけど、それを使うと
#何かしない限り、デバッグができない(コンパイル・
#実行したとたんに終了してしまうから)。
#私の場合は、コマンドラインオプションを使いましたが。
> 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」はいかが? }
+=============================================================/+
> > 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>
で見ることができます。
> くぐりぬけを防ぐためには、いきなり 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.
これで動かしてみましたが、二重起動を防止できました。
> ええ、こんなかんじです。
> 気になる点は、hAppはもっと複雑な名前 (たとえば GUID) にしたほうがいい、とか
> CreateMutex の戻り値も見たほうがいいのでは、といったところくらいです。
了解しました。
> > これで動かしてみましたが、二重起動を防止できました。
>
> 1番目のプロセスをデバッグ実行して Application.Initialize の行でブレークし、
> そのまま2番目のプロセスをコマンドライン実行してみてください。
> それでも二重起動しなければオーケーです。
やってみたところ二重起動しませんでした。
ご忠告に感謝いたします。では。