こんにちは、E46-M3と申します。
さっそくですが、
あるプログラムから別のアプリケーションを起動させる際
または、終了させる際「ハンドル」を使用しますが、
ハンドルそのものの知識が浅いので
是非わかりやすく教えて頂ければ思います。
また、プロセスハンドルとウインドウハンドルの
違いについても教えて頂ければと思います。
よろしくお願い致します。

A 回答 (2件)

 ハンドルについての解説は、それだけでかなりのスペースが必要です。

ので、簡単に書きます。
 詳細は、WindowsAPIバイブル等の書籍を購入して読んで来下さい。

 プロセスハンドルは、各アプリケーション内部で発生したプロセスが持つハンドルです。親ハンドルは、アプリケーションのプロセスハンドルにもなります。
 ウィンドウハンドルは、各アプリケーションから作成される窓毎に持つハンドルです。メイン画面のハンドルは、アプリケーションのハンドルとなります。

 別のアプリケーションを起動する場合には、プロセスハンドルが取得できます。しかし、Windowsの終了等には、プロセスハンドルではなく、ウィンドウハンドルが必要になります(ヘルプ読んでね)。

 説明の都合上端折っている所があるので、正確に覚える場合には、書籍の購入を強くお薦めします。
    • good
    • 0
この回答へのお礼

適切なアドバイスありがとうございます。
プロセスハンドルとウィンドウハンドルは、
基本的に別物なのですね。
/////////////
書籍って結構高いですよね。
でもあって損はないですからね。

お礼日時:2001/06/04 19:35

「ハンドル」は、何かを扱うときに、その何かにたどり着くためのもの、です。


広い意味でのポインタだと思って良いです。

「プロセスハンドル」は、プロセスに何かしたいとき(例えば、あるプロセスを
終了させたい、とか)、「ウィンドウハンドル」は、ウィンドウに何かをしたい
とき、に使います。

ちょっとややこしいのは、あるプログラムを終了させる場合に、そのプログラムが
ウィンドウを持っている場合には、ウィンドウに対して終了の指示ができると
いうことです。

Windowsでは、ほとんどのものを扱う場合には「ハンドル」を使います。メモリや
フォント等々、すべてハンドルを持っています。

# あまり、うまく説明できてないかな… (^^;
    • good
    • 0
この回答へのお礼

いえいえ。
とても参考になりましたよ。

ハンドルについていろいろと検索してみたのですが、
概念的な説明をしているようなページが見つからなかった
ので、質問してみたのですが、、やはり一筋縄では
いかなそうですね。もう少し勉強してみます。
ありがとうございました!

お礼日時:2001/06/04 19:18

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qプロセスのハンドルと識別子

エディットやボタンなどへのアクセスは、ウインドウハンドルを使ってそれらのオブジェクトにアクセスしているんだと考えられますが、
プロセスやスレッドにはハンドルと識別子の両方があるので、その違いが分かりません。
あるスレッドが動いていて、それを止める場合、そのスレッドのハンドルを使うのか識別子を使うのかが想像できるようになりたいのです。
プロセスを終わらせる関数を見つけ、その関数の引数の型を調べるのではなく、ハンドルと識別子の違いを理解して、それを想像する方法を教えてください。

Aベストアンサー

OSを限定しないと正確な説明はできないので、ここではWindowsを仮定します。(他のOSの場合は補足願います。)


グラフィックオブジェクト(エディットやボタンなど)の「ハンドル」と、カーネルオブジェクト(プロセスやスレッド)の「ハンドル」にはいくつか大きな違いがあります。

【グラフィックオブジェクトのハンドルの性質】
・1つのオブジェクトに1つのハンドル番号が割り当てられる
・ハンドル番号の割り当てがシステム全体で重複しない
・どのプロセスからも同じハンドル番号で同じオブジェクトを参照できる

【カーネルオブジェクトのハンドルの性質】
・1つのオブジェクトに複数のハンドル番号を割り当てることができる
・同じハンドル番号でも別のプロセスでは別のオブジェクトを指しているかもしれない
・同じハンドル番号でも別のプロセスでは無効かもしれない


例えば、プロセスAでウィンドウを作成し、そのハンドルが0x15e8だったとします。このとき別のプロセスBでハンドル0x15e8のウィンドウを操作すると、同じウィンドウを操作することになります。

これに対して、プロセスAでスレッドを作成し、そのハンドルが0x2ab0だったとします。このとき別のプロセスBでハンドル2ab0のスレッドを操作しようとしても、それが可能だとは限りません。

プロセスBがプロセスAのハンドルを「継承」しているか、プロセスBがスレッドの「識別子(ID)」を取得し、そこからプロセスB内で有効なハンドルを取得すれば、プロセスAのスレッドを操作することができるようになります。前者の場合、プロセスAの中で使用していたスレッドのハンドルがそのまま使えますが、後者の場合は同じ「プロセスAのスレッド」に対して、異なる値を持つ「プロセスB内で有効なハンドル」を取得することになります。


カーネルオブジェクトのハンドルはプロセスごとに割り当てられるので、システム全体を通じてハンドルを一覧することは通常はできません。しかしプロセスとスレッドに限っては、システム全体を通じての一覧ができないと不便です。そのため、プロセスとスレッドには特別に、システム全体を通じて一意であることが保証されている「識別子」が用意されています。

この「識別子」はグラフィックオブジェクトのハンドルと似た性質があります。

【プロセス識別子・スレッド識別子の性質】
・1つのオブジェクト(プロセスまたはスレッド)に1つの識別子が割り当てられる
・識別子の割り当てがシステム全体で重複しない
・どのプロセスからも同じ識別子で同じオブジェクトを識別できる


なお、識別子はオブジェクトを「識別」する(例えばスレッドAとスレッドBが同じか違うかを判断する)ためには使用できますが、オブジェクトの状態を「参照」・「操作(変更)」する(例えばスレッドAを停止する)ためには使用できません。識別子は「どのオブジェクトであるか」という情報を提供するだけだからです。

それ以上の情報の取得やオブジェクトの状態の操作は、プロセスごとにその参照・操作が許されているかどうかの設定(セキュリティ設定)があり、その設定を確認するためにオブジェクトを「開いて」ハンドルを取得する必要があります。

オブジェクトを開いてハンドルを取得する際には「オブジェクトに対してどういう操作を行うか」を指定します。このときシステムは、指定された操作が許されているかどうかをチェックします。ハンドルが取得できれば、その操作を行う権限があるということになります。


ハンドルと識別子の違いはこんなところです。

OSを限定しないと正確な説明はできないので、ここではWindowsを仮定します。(他のOSの場合は補足願います。)


グラフィックオブジェクト(エディットやボタンなど)の「ハンドル」と、カーネルオブジェクト(プロセスやスレッド)の「ハンドル」にはいくつか大きな違いがあります。

【グラフィックオブジェクトのハンドルの性質】
・1つのオブジェクトに1つのハンドル番号が割り当てられる
・ハンドル番号の割り当てがシステム全体で重複しない
・どのプロセスからも同じハンドル番号で同じオブジェク...続きを読む

Qプロセスのハンドルを確保

AプログラムからBプログラムを起動するプログラムを作成しています。

AはループでBプログラムを起動するのですが、Aでプロセスの起動数をチェックし、飽きのプロセスハンドルを確保しBプログラム意を起動する際にAで確保したハンドルを使用して起動するような処理をするにはどうしたらいいでしょうか?

例:プロセス最大起動数:5
  Aは10回ループし、Bを起動する。
  Aでプロセスハンドルを5個確保する。
  Bを起動する際に確保したハンドルを1個使用する。
  Bが終了したらハンドルを解放する。
  

Aベストアンサー

>プロセス終了後にハンドル初期化する際はどうしたらいいでしょう
>か?

以下に変更します。

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR nCmdLine,
int lCmdShow)
{
PROCESS_INFORMATION pr;
STARTUPINFOA st;
char buf[50];
HANDLE hProcess[5]={0,0,0,0,0};
HWND hWnd[5]={0,0,0,0,0};

memset(&st,0,sizeof(st));
st.cb=sizeof(st);

for (int j,i=1;i<=10;i++)
{
wsprintf(buf,"%d 回目",i);
switch (MessageBox(0,"処理を選択して下さい\r\rOK:起動\rキャンセル:次のループ",buf,MB_ICONINFORMATION|MB_OKCANCEL))
{
case IDOK:
for (j=0;j<5;j++)
if (!IsWindow(hWnd[j]))
{
CloseHandle(hProcess[j]);
hWnd[j]=0,hProcess[j]=0;
}
for (j=0;j<5;j++)
if (!hWnd[j]) break;
if (j==5) continue;
CreateProcess("c:\\windows\\notepad.exe",0,0,0,0,CREATE_NEW_PROCESS_GROUP,0,0,&st,&pr);
Sleep(1000);//低速CPUでも信頼できるウエイト
hWnd[j]=GetForegroundWindow();
hProcess[j]=pr.hProcess;
i=--i&0xf;
continue;
case IDCANCEL:
continue;
}
}
return 0;
}

>プロセス終了後にハンドル初期化する際はどうしたらいいでしょう
>か?

以下に変更します。

#include <windows.h>

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR nCmdLine,
int lCmdShow)
{
PROCESS_INFORMATION pr;
STARTUPINFOA st;
char buf[50];
HANDLE hProcess[5]={0,0,0,0,0};
HWND hWnd[5]={0,0,0,0,0};

memset(&st,0,sizeof(st));
st.cb=sizeof(st);

for (int j,i=1;i<=10;i++)
{
wsprintf(buf,"%d 回目",i);
switch (MessageBox(0,"処理を...続きを読む

Q異なるプロセス間でのイベントハンドルの共有

異なるプロセス間でのイベントハンドルの共有

WIN32 APIのDuplicateHandleを用いて、異なるプロセス間でのイベントハンドルを共有したいのですが、うまく動作しません。(1)~(3)にプログラムの詳細を示します。

(1) プロセスAで「本物」のプロセスハンドルを取得
  DuplicateHandle(
    GetCurrentProcess(),    
    GetCurrentProcess(),    // 疑似ハンドル
    GetCurrentProcess(),
    &RealProcessHandle,     // 本物のハンドル
    0,
    FALSE,
    DUPLICATE_SAME_ACCESS
  );

(2) プロセスAでイベントを作成
  hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

(3) プロセスBでイベントハンドルを複製
  DuplicateHandle(
    RealProcessHandle,     // プロセスAが(1)で取得した本物のハンドル
    hEvent,           // プロセスAが(2)で取得したイベントハンドル
    GetCurrentProcess(),
    &hNewEvent,         // プロセスBで利用するためのイベントハンドル
    0,
    FALSE,
    DUPLICATE_SAME_ACCESS
  );

上記のプログラムを実行すると、(1)と(2)は成功するものの、(3)の時点でエラーになり、
GetLastErrorでは6(ハンドルの異常)が表示されます。
プログラムのどこが悪いのでしょうか?

尚、OpenEventによるイベントハンドル共有は、
イベントに名前をつけなくてはならない問題があり、利用しない方針です。

異なるプロセス間でのイベントハンドルの共有

WIN32 APIのDuplicateHandleを用いて、異なるプロセス間でのイベントハンドルを共有したいのですが、うまく動作しません。(1)~(3)にプログラムの詳細を示します。

(1) プロセスAで「本物」のプロセスハンドルを取得
  DuplicateHandle(
    GetCurrentProcess(),    
    GetCurrentProcess(),    // 疑似ハンドル
    GetCurrentProcess(),
    &RealProcessHandle,     // 本物のハンドル
    0,
    FALSE,
    DU...続きを読む

Aベストアンサー

作成元のプロセスおよび、作成したハンドルに対して
適切なアクセス権を与えていますか?
特にPROCESS_DUP_HANDLEは、NT/2000以降では必須です。

また、関数に指定するハンドルが間違っているような気がします。
第1引数は”プロセスのハンドル”であり、第4引数は”複製する対象のハンドル”です。
提示されたソースではどちらが正しいのかわかりませんが、
もう一度、MSDNを確認し関数仕様を確認された方が良いように思います。
>&RealProcessHandle,     // 本物のハンドル
>RealProcessHandle,     // プロセスAが(1)で取得した本物のハンドル


なお、異なるプロセス間では、名前付き以外で共有する場合、
共有メモリや名前付きパイプなどを使用しなければならないパターンもあり
端から名前付きイベントを作成した方が安全な場合もあるので、
本当に名前付きイベントではダメなのか、再考するほうが良いかも知れません。

参考URL:http://msdn.microsoft.com/en-us/library/ms724251(VS.85).aspx

作成元のプロセスおよび、作成したハンドルに対して
適切なアクセス権を与えていますか?
特にPROCESS_DUP_HANDLEは、NT/2000以降では必須です。

また、関数に指定するハンドルが間違っているような気がします。
第1引数は”プロセスのハンドル”であり、第4引数は”複製する対象のハンドル”です。
提示されたソースではどちらが正しいのかわかりませんが、
もう一度、MSDNを確認し関数仕様を確認された方が良いように思います。
>&RealProcessHandle,     // 本物のハンドル
>RealProcessHandle,     // プ...続きを読む

Q子プロセスと親プロセス

ある本を読んでいると、以下のような問いにぶち当たり、プログラムの仕方がよくわからないのです。
自分でもいろいろ調べたのですが、わからないので質問させていただきます。

自分のプロセスIDと親のプロセスIDのプロセスIDを表示するコマンドshowpidを作り、showpidを子プロセスとして10回実行するプログラムを作りなさい。ただし、execを用いてshowpidを10回実行すること。

というものなのですが、自分のプロセスIDと親のプロセスIDの表示方法はわかったのですが、それをコマンドとして作り、子プロセスとして10回実行する方法がわからなくて困っております。。。

言語はc言語を使ってもらいたいです。以下に自分のプロセスIDと親のプロセスIDを表示するプログラムを付けときます。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(){
pid_t pid;
int status;
if((pid=fork())==0)
printf("I am a child with pid=%d. My parent pid is %d.\n",getpid(),getppid());
else{
wait(&status);
exit(EXIT_SUCCESS);
}

ある本を読んでいると、以下のような問いにぶち当たり、プログラムの仕方がよくわからないのです。
自分でもいろいろ調べたのですが、わからないので質問させていただきます。

自分のプロセスIDと親のプロセスIDのプロセスIDを表示するコマンドshowpidを作り、showpidを子プロセスとして10回実行するプログラムを作りなさい。ただし、execを用いてshowpidを10回実行すること。

というものなのですが、自分のプロセスIDと親のプロセスIDの表示方法はわかったのですが、それをコマンドとして作り、子プロセス...続きを読む

Aベストアンサー

showpid.c では単に、getpid() と getppid() の結果を出すだけでいいです。それをコンパイルすればコマンドが出来ます。

メインのプログラムでは、こんな感じで。
for(10回ループ) if(fork()==0) execv(showpidコマンド)

Q子プロセスの状態を親プロセスに渡したい

今、C言語を用いてシェルを作成していて、そこでcpコマンドを実現したいと思っています。その際、子プロセスを生成し、そこでgetcwdやchdirを使用してディレクトリの移動を行うのですが、子プロセスを終了させると親プロセスでは移動前のディレクトリに戻ってしまいます。
子プロセスでディレクトリを移動したときに,親プロセスでも移動された状態にするにはどうすればいいのでしょうか?それとも、この操作は親ディレクトリでしか行えないのでしょうか?
できるだけ詳しく教えていただけるとありがたいです。回答よろしくお願いします。

Aベストアンサー

質問に「cpコマンドを実現したい」と書かれているのは、もしかしてcdコマンドの書き間違いでしょうか。そう考えると、なぜ親プロセスのカレントディレクトリを移動したいのかが納得できます。
この推測が合っていたとして、普通はcdコマンドのために子プロセスを作ることはしません。cdはシェルのビルトインコマンドとして実現されているのが一般的です。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報