2005年07月31日

事前に登録したプログラムを順番に終了させる方法

空の雲は厚く、郊外は緑のジャングル、
時おりスコールと雷鳴が都会慣れした我々を脅かす。
日本の梅雨と変わらない気候が重くのしかかる。
そこは赤道にほど近い東南アジアのとある場所...

先進国で生活されるほとんどの皆さんは、
水道、ガス、電気などのライフラインは
整備されいることが当たり前と思われるでしょう。
私が出張で滞在した東南アジアのライフラインは、
日本の水準では考えられないものでした。

雷が鳴るたびに電源の供給が停止し、
機関系システムが、
たびたびUPS電源のお世話になるのです。
停電も日本のように瞬停ではなく、
復旧しないこともしばしばありました。
(今では改善され良くなったと聞きますが...)

少し前置きが長くなりました。
今回は停電発生時にUPSの
自動シャットダウン機能などから実行し、
機関系システムの関連プロセスを一斉に終了させるのに便利な
WindowsのサンプルプログラムをDelphiで紹介しましょう。
OSシャットダウン前に、関連プロセスを順番に終了し、
大切なデータを保護することが目的です。

通常の行儀良いWindowsアプリケーションは、
「WM_QUIT」メッセージを受信すると終了処理を行います。
中にはははみ出し者がいるもので、
これに従わなアプリケーションもあることでしょう。

本プログラムはINIファイルに記述されたプログラム名を、
EnumWindows」、「EnumProcesses」APIの
実行結果から情報を検索し終了させます。
終了手順は、該当プロセスへ「WM_QUIT」を送信し、
相手が自主的に行儀良く終了するのを待ちます。
一定時間内に相手が終了しない場合、
TerminateProcess」を発行し強制的に終了させます。
一連の処理を実行後、本プログラムは自動で終了し、
起動から終了までの処理をログファイルに書き込みます。

処理内容
説明
@プロセスの取得
「EnumWindows」、「EnumProcesses」などのAPIを利用し、現在稼動中のプロセス情報を取得する。基本的にウィンドウを持つプロセスの情報を取得する。
AINIファイルの読込
INIファイルを読込み、終了させたいプロセスの実行モジュール名を取得する。
Bプロセスの終了
Aで読込んだ実行モジュール名を@のプロセス情報から取得し終了処理を行う。はじめ該当プロセスへ「WM_QUIT」を送信するが、一定時間以上応答が無い場合、「TerminateProcess」APIを発行し該当プロセスを強制終了する。

全ソースは【続きを読む】をクリック!

【画面イメージ】

Terminator.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 06:39 | 運用管理編

2005年07月30日

指定された文字型データをダンプ形式に整形する方法

Client/Server型プログラムや
バックグラウンドプログラムが、
データ不備が原因でうまく
動かなかった経験はないでしょうか?
そんなあなたにプログラムが扱うデータを
ダンプ形式(16進数表示とASCII文字)で表示する
ちょっと便利な関数をDelphiで紹介します。

障害解析ツールなどに組み込んで利用してください。
本関数はマルチバイト文字未対応です。
必要に応じプログラムを修正し使用してくださいね。

ではさっそく、プログラムを紹介しましょうね。

_CoordinateDumpStringsソースは【続きを読む】をクリック!

関数仕様
function_CoordinateDumpStrings(
 pBuffer: PChar; pSize: integer;
  pStrList: TStrings): TStrings;
説明
_CoordinateDumpStrings関数は指定された文字列データをダンプ形式(16進数表示とASCII文字)に整形します。pBufferは文字列データの先頭ポインタを、pSizeは文字列データ長を指定します。関数がダンプ形式に整形した結果はpStrListに戻されます。
使用例
procedureTForm1.Button1Click(Sender: TObject);
begin
 // Memo1に入力された文字列をダンプ形式に整形し、
 // 整形した結果をMemo2に格納し表示する。

 Memo2.Lines.Clear;
 _CoordinateDumpStrings(
  Pointer(Memo1.Text),
   Length(Memo1.Text), Memo2.Lines);
end;

【画面イメージ】

CoordinateDumpStrings.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 07:43 | 障害解析編

2005年07月29日

TCP/IPコネクション型ソケットで非同期通信する方法

TCP/IPのコネクション型ソケット(socket)を使い
プログラム同士を効率よく通信させたいのだけど、
処理をブロッキングすることなく通信させるには
どうしたらよいか悩んだことはありませんか?

今回はプログラム同士が
TCP/IP通信を実現するため、
接続、切断、受信、送信完了の
各事象をイベント駆動型で
プログラムに通知し効率よく通信させる
方法をDelphiでご紹介します。

一般的にTCP/IPのサーバタイプは特定の
サービスをクライアントに提供するため、
特定のポート番号でソケットをオープンし、
クライアントからの接続を待ちます。

一方、TCP/IPのクライアントは特定の
サービスをサーバに要求するため、
サービスを提供している相手(サーバ)と
そのサービスを表すポート番号へ、
ソケットを接続しサービスの要求を行います。

サービスの代表的なものに、
ftp、telnetなどは良くご存知かと思います。
もう少し具体的に見ていくと、
サーバ、クライアントの主な処理は次のようになります。

サーバ処理
説明
@サービスの開始
TCP/IPのストリームソケットを作成(socket)し、自分のIPアドレスとサービスを提供するポート番号をバインド(bind)する。
リッスン(listen)を行い、クライアントから接続を待つ。
サンプルプログラムは、終了するまでこのソケットを維持し、クライアントから接続の要求を受付け続ける。
A接続の受理
@のソケットにクライアントから接続要求があるか検査(select)する。
クライアントから接続要求があった場合、接続を受理(accept)する。
接続の受理に成功した場合、データ送受信用に新しいソケットが確保される。
以降のデータ送受信はこのソケットが使用される。
B要求の受信
Aのソケットでクライアントからデータを受信しているか検査(select)する。
受信データがある場合、取得(recv)する。
Cサービスの実行
クライアントの要求データでサーバのサービスを実行し、必要であれば応答データを戻す。
サンプルプログラムは、クライアントから受信したデータをそのままクライアントへ送信する。
D応答の送信
Cの処理でクライアントへ何らかの応答データを送信する場合、Aのソケットでクライアントへデータを送信できるか検査(select)する。
データを送信できる場合、送信(send)する。
E終了処理
全てのソケットを閉じ(closesocket/close)終了する。

クライアント処理
説明
@接続の要求
TCP/IPのストリームソケットを作成(socket)し、相手(サーバ)のIPアドレスとサーバのポート番号を設定し接続要求(connect)を行う。
サーバがクライアントの接続を受理した場合、接続は成功する。
サーバが不在かサーバのサービスが開始されていない場合、接続は失敗する。
A要求の送信
@のソケットでクライアントが要求データを送信できるか検査(select)する。
データを送信できる場合、送信(send)する。
サンプルプログラムは、画面で入力されたテキストを送信する。
B応答の受信
@のソケットでサーバから応答データを受信しているか検査(select)する。
受信データがある場合、取得(recv)する。
サンプルプログラムは、サーバがクライアントのデータをエコーバックするので、クライアントは自分が送信したテキストを受信する。
C終了処理
全てのソケットを閉じ(closesocket/close)終了する。

ここで問題になるのは
クライアントとサーバ間で
実際にやり取りするデータです。
送受信データの終わりはTCP/IP上に
実装されるプログラムの責任で行う必要があります。


送信データ長がウインドサイズを超えるような
データを送受信する場合、
送信側で仮に一回で送信できたとしても、
受信側では何回かに分けて受信することになります。
select関数はソケットに受信データがあるかないか、
送信できる状態であるかないかの情報は取得できても
送受信データがどこで終わっているか判断がつかないのです。

select関数の受信事象をそれぞれ
バラバラのデータと認識したのでは、
とんでもないことになりますね。
(初心者の方はよくやる失敗ですので注意してくださいね。)

サンプルプログラムは
この問題を回避するため、
送受信データの先頭に
ネットワークバイトオーダーのデータ長を付加し、
送信データが全て送信できた時に送信完了イベントを、
受信データを全て受信できた時に
受信イベントが発生するようになっています。

ではでは、早速サンプルプログラムを見ていただきましょう!

全ソースは【続きを読む】をクリック!

プログラムは若干複雑になってますが、
全ソースを公開しますので、
がんばって理解してくださいね。
また役に立ったと思われるあなた、
いつもの良く冷えた"ビ"がつくものおごってくださいね。(笑い)

【画面イメージ】

SocketTester.gif

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 07:20 | 通信編

2005年07月28日

文字列と出現回数から文字列の位置を取得する方法

Delphi標準関数Posを応用した関数です。
指定された文字列から特定の部分文字列を検索し、
検索ヒット回数が指定された回数になった場合、
その部分文字列の文字位置を戻す関数です。

な〜んのことはありません。
Pos関数に検索ヒット回数の引数が追加されただけですが、
この関数を利用する局面は、以外にもたくさんあるのです。

今回ご紹介する関数は、
「文字列からトークンを取得する方法」
などの関数と組み合わせることで、
文脈自由型のコンパイラやインタープリタの文脈解析、
プログラムの挙動を制御するINIファイルの解析など、
幅広い問題の解決にご利用いただけるかと思います。


ではさっそく、プログラムを紹介しましょうね。

_Posソースは【続きを読む】をクリック!

関数仕様
function _Pos(
 pSubStr, pSource: String; pCount: Integer): Integer;
説明
pSourceで指定された文字列から、pSubStrで指定された部分文字列を検索し、検索ヒット回数が指定されたpCountと同じ場合、pSource中の部分文字列の位置を戻します。部分文字列が見つからない場合や、検索ヒット回数の条件を満たさない場合、関数はゼロを戻します。
使用例
procedure TForm1.Button1Click(Sender: TObject);
var
 lText: String;
 lIndex: Integer;
begin
 lText := 'Hello! This is guy. sorry? My Name is guy.';
 // 上記文字列から
 // 1回目にヒットした'guy'の文字位置を取得する。
 // 文字位置は'16'が戻されます。

 lIndex := _Pos('guy', lText, 1);
 Edit1.Text := Format('%d', [lIndex]);
 // 上記文字列から
 // 2回目にヒットした'guy'の文字位置を取得する。
 // 文字位置は'39'が戻されます。

 lIndex := _Pos('guy', lText, 2);
 Edit1.Text := Edit1.Text + Format(',%d', [lIndex]);
 // 上記文字列から
 // 3回目にヒットした'guy'の文字位置を取得する。
 // 文字位置は'0'が戻されます。

 lIndex := _Pos('guy', lText, 0);
 Edit1.Text := Edit1.Text + Format(',%d', [lIndex]);
end;

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 06:59 | 文字列操作編

2005年07月27日

職場でのパレートの法則

あなたはパレートの法則をご存知でしょうか?
昔、イタリア国の財産や資産を調査した
経済学者パレートは、その財産や資産の約8割は
イタリア国民のほんの2割の人々から
生み出されていると言うことを発見したのです。

この法則は不思議なことに、
我々を取り巻くほとんどの現象に当てはまります。

例えばあなたがよく知っている働きアリは、
エサの採取や自分たちのコロニーを作るため、
実際に働く個体は全体の2割、
残り8割は何をする訳ではなくウロウロするばかりで、
我々人間の衣食住といった生産活動の視点から見ると、
一見この8割の存在価値がない様に見えます。

ところが面白いことに、
この全く働かない8割を隔離してしばらく放置すると、
働くもの2割、働かないもの8割ときれいに分かれるのです。
(あたなもアリを捕まえて実験してみると体験できますよ。)

一方、働くもの2割同士を
集めたスペシャル集団をつくった場合、
今まで働く2割に属していたにも関わらず、
やはり8割が働かないもになってしまうのです。
(ITプロジェクトを優秀な社員で構成しても、
必ず成功するという保証はないですよね。)

現在アメリカでは、この8割の存在価値と、
この8割が残り2割に与える影響などについて、
科学的、生物学的側面から必死に研究しています。

さて、このパレートの法則をあなたの会社に
当てはめたらどうなるのでしょうか?
一見、存在価値が無いような社員は
いないように思うかもしれませんが良く観察してください。
彼らは仕事をしているのでしょうか?
それとも単に作業をしているだけなのでしょうか?
言われた事を正確、かつ迅速こなすことができる社員は、
2割の集団でしょうか?8割の集団でしょうか?
他と協調せず独りでバリバリ仕事をする社員は
どちらの集団に属するのでしょうか?
協調しているかに見える人たちはの集団は、
金儲けのプロ集団でしょうか?
あるいは単に仲良しで傷を
慰めあうだけの仲良しグループでしょうか?

そして最も重要ですが、
あなたはどちらなのでしょうか?

答えはすでにお持ちのことと思います。
自分のライフスタイルを明確にし、
少なくとも自分自身が
納得するビジネススタイルを確立すれば、
見えている部分や気付くことが
広がりもし、狭くもなることでしょう。
また、あなたが抱えているさまざまな問題に対し、
どのように対処するか、
こと細かくその行動に表れることでしょう。
会社員の場合どんな言い訳をしても、
十中八九の確率で
あなたの性格、人間性、志向、スキルなどは、
とうの昔に会社側や周りが見抜いています。

あなたが会社でダメ人間であっても、
その欠点は問題になりません。
2割の集団になれる
得意分野や居場所が必ずあるはずです。
そこでの行動が、2割の集団に属するか、
8割の集団に属するかを左右するだけのことです。

必ずあなただけの居場所を見つけてくださいね!

関連書籍

Copyright guy@かしらもんじ でぇ〜

posted by guy at 06:48 | ビジネススタイル

2005年07月26日

文字列から文字要素(トークン)を取得する方法

検索エンジンのキーワード欄に入力された文字列や、
CSVファイルのようなカンマ、タブで区切られた文字列から、
各文字要素(トークン)を取得する方法をDelphiで紹介します。


私が大学生だった頃、
AI(人工知能)なる言葉やLISP言語が流行していました。
このAIの研究に没頭されていた教授から、
夏休みにインタープリタをつくりなさいという課題を与えられ、
面白半分、悩み半分で取組んだ思い出があります。

今回ご紹介する関数は、
CVSファイルの文字列トークン取得から、
文脈自由型のコンパイラやインタープリタの文脈解析まで、
幅広い問題の解決にご利用いただけるかと思います。
また、このアルゴリスムは
初級情報処理技術者資格試験にも
出題されるたことがありますよ。


ではさっそく、プログラムを紹介しましょうね。

_GetTokenソースは【続きを読む】をクリック!

関数仕様
function _GetToken(
 var pSource: String; pDelimiter: String): String;
説明
pSourceで指定された文字列から、pDelimiterで指定された区切り文字こどに文字列要素を取り出し戻します。文字列要素を取り出した後、入力されたpSourceは、始めに見つかった区切り文字以降の文字列に再編集されます。pSourceで指定された文字列から文字列要素を取り出せない場合、関数は空の文字列を戻します。pDelmiterには区切り文字を複数指定できます。
使用例
procedure TForm1.Button1Click(Sender: TObject);
var
 lText,
 lToken: String;
begin
 // 'Hello, This is guy.'の文字列から' ,.'を区切り文字とし、
 // 'Hello','This','is','guy'の各文字トークンを取得する。

 lText := 'Hollo, This is guy.';
 while (lText <> '') do
 begin
  lToken := _GetToken(lText, ' ,.');
  if (lToken = '') then
   Break;
  Memo1.Lines.Add(lToken);
 end;
end;

関連書籍


Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 08:38 | 文字列操作編

2005年07月25日

Win32プロセス情報をまるごと取得する方法

WindowsNT、2000、XP
上で動作する各プログラムの
CPU使用率、メモリ使用量、優先順位、
ハンドル数、スレッド数などを取得するには、
どうすればよいか悩んだことかはありませんか?

Win32SDKのヘルプを見ても、
残念ですが、その解決方法は記載されておりません。
ところが、実際に各プロセスの上記情報を取得できる
非公開の(隠された)APIが存在するのです。

我々がMicrosoftOfficeと同等の
ワープロや表計算ソフトをつくったとして、
それらソフトはオリジナルよりも高速に
動作するでしょうか?
おそらく答えは「No」ではないでしょうか。
そこには我々が知り得ない
数々の非公開テクニックがあるからです。

ではさっそく、そのプログラムを公開しましょう。
今回あなたが実際にプログラムを実行して確認出来るように、
Delphiソースを、すべて公開しますから、安心してくださいね。

このプログラムは、
Windowsのタスクマネージャのプロセス一覧と
ほぼ同等の機能を持っています。
約1秒間隔で、Windowsが管理するプロセス情報から、

「NtQuerySystemInformation」

という隠れAPI関数で、各プロセスの情報を取得し、
各プロセスの一覧を作成し表示します。
あとおまけで、
OSのCPU使用率、物理メモリの使用率、
ディスクの使用率の各傾向を、
グラフでビジュアルに表示します。

全ソースは【続きを読む】をクリック!

この記事を読んで役に立ったと思うあなた、
私にビール1本おごってくださいね。(笑い)


【画面イメージ】

WTM24.gif

関連書籍

Copyright guy@かしらもんじ でぇ〜

続きを読む
posted by guy at 07:52 | 運用管理編

2005年07月24日

はじめまして!

1995年2月、アメリカの某生産工場で、
Delphi言語の大規模なITプロジェクトが始まろうとしていた。
その頃、私はCとVBのプログラミング言語しか知らない、
ごく普通のプログラマとして、
日々会社の開発業務に追われる毎日を送っていた。

ある日、上司から「おまえはアメリカへ行きたいか?」
との突然の問いかけに答える間もなく、
プロジェクトの開発メンバとしてアサインされることとなった。

はじめて、私がDelphiと出会ったのは、丁度この頃でした。

「Delphiってなんだ? 
デルパイ、デルピー、デルフィー、デルファイ、
いったい何て発音すればいいんだ?」

と同僚と話していたのが、
今となってはとても懐かしい思いがします。
(日本人は「デルファイ」、
アメリカ人は「デルフィー」と発音しています。)
これほど、Delphiなど全く知らなかった私が、
今では開発業務でDelphiを使い、
多くのITプロジェクトをバリバリこなすレベルに至っています。
(自慢してごめんなすって)
おっと、すこし前置が長くなってスイマセン。
まずは自己紹介させていただきます。
このページの管理人で、
遊び好き、飲み好き、少し恥ずかしがり屋の「guy」です。

はじめまして!

このページは、
Delphiプログラミングをこれから始めようとする人を始め、
具体的な問題解決のサンプルやノウハウをお探しのあたな、
そして私にも役立つ情報を出来る限り提供し、

「Delphiプログラミングの輪」
をつくって行きたいと考えております。
今後も、ごひいきしてくださいね。
と言うか、
見ないと「あなた!」損しますよ!
なんてね...

関連書籍


Copyright guy@かしらもんじ でぇ〜

posted by guy at 07:53 | はじめまして!

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。