2009-12-22

IIS の php から FileMaker Pro ファイルをオープンするのに四苦八苦

 Windows Server 2003 の IIS で php ファイルから FileMaker Pro ファイルを開くという操作を試しているのですが、どうもうまくいきません。

【目標】
 IIS で公開されている test.php というファイルからサーバディスクに配置した dbopen.vbs を起動し、vbs から FileMaker Pro ファイル test.fp7 を開く。

dbopen.vbs の中身は次のとおりです。ここでは、FileMaker Pro アプリケーションのインスタンスを作成し、それからローカルコンピュータの test.fp7 を開いて showMSG というスクリプトを実行するという流れになっています。このファイルを作って単独で実行すると正常に動作することは確認済みです。


Dim FMApp
Dim FMDocs, myOpenFile

Set FMApp = CreateObject("FMPRO.Application")
FMApp.Visible = True
Set FMDocs = FMApp.Documents
Set myOpenFile = FMDocs.Open("c:\hoge\test.fp7" ,"Admin","somePwd")
myOpenFile.DoFMScript ("showMSG")

Set myOpenFile = Nothing
Set FMDocs = Nothing
Set FMApp = Nothing



【試した操作】
1. IIS 経由で php を実行すると、その実行者は IUSR もしくは NETWORK SERVICE になるため、実行権限を必要なファイル群に与える必要があります。dbopen.vbs は WScript.exe から起動させるため、System32 ディレクトリの中にある WScript.exe に IUSR の実行権限を付与しました。
2. これだと dbopen.vbs で CreateObject を使って FileMaker のインスタンスを作成する時に書き込みエラーが発生するため、IUSR ではなく、ログイン中のユーザアカウントで実行できるよう、PsTools の psexec.exe を使って vbs のみログインユーザ権限で実行するようにしました。

PsTools の紹介とダウンロードはこちら

以下のように test.php のソースに指定しました。


$retval = `C:\hoge\PsTools\psexec.exe -u Administrator -p somePassword1234 -d WScript.exe C:\hoge\dbopen.vbs`;


備考:
1. psexec.exe に IUSR アカウントを割り当て、実行権限を付与しておく必要があります。
2. ``で囲ったコマンドラインがシェルコマンドとして解釈されるため、ここでは exec()関数を使用していません。
3. -d はスクリプトの終了を待たずに psexec を終了させるためのスイッチです(異常終了時のプロセス残留回避)。
4. vbs ファイルは単体では認識されないため、WScript.exe を明示的に指定する必要があります。

 このように設定してから Web ブラウザより test.php を実行すると、ブラウザが読み込み中状態となってしまいます。そこでタスクマネージャを起動して確認してみると、実行者 NETWORK SERVICE のプロセスとして psexec.exe が残っていることがわかりました。

【現象】
 psexec の実行ユーザが NETWORK SERVICE になっていると、デスクトップにそのアプリケーションが表示されず、バックグランドプロセスとして残留してしまいます。
 二台の Windows Server 2003 環境で実行したところ、一台は test.fp7 がデスクトップに表示され、showMSG スクリプトまで表示されたのですが、もう一台のマシンがどうもうまくいきません。

 psexec に NETWORK SERVICE を割り当てて実行権限を付与したり、IIS マネージャのアプリケーションプールのセキュリティアカウントを NETWORK SERVICE 以外に設定するなど試したのですが、やはりプロセスがバックグランドで残留したままの状態となります。


 IIS で運用中の php スクリプトからシェルコマンドでアプリケーションを起動し、そのアプリケーションをデスクトップに表示させる方法をご存じの方は、情報をお待ちしております。

2009-12-11

FileMaker V10による在庫管理、一考

久々のFileMaker(以下、FM)の話題。
V9以前のFMでは、在庫を算出する場合は、在庫テーブルで以下のようにやっていたのではないだろうか?

在庫::在庫(計算) = 在庫::前月分在庫 - Sum(出庫明細::出庫数) + Sum(入庫明細::入庫数)


このやり方は簡単でいいのだけれど、出庫明細や入庫明細のレコード数が多いと、1つの商品の在庫の算出にさえ、数十秒から数分の時間がかかってしまう可能性がある。 よって、商品数と伝票枚数(商品取引)が多く、リアルタイムの在庫を即時把握したいような業種では、FMは使えなかった。
言い換えると、在庫や各種残高算等、あるテーブル(上例では、出庫明細、入庫明細)のフィールド値に基づき計算を行いその結果を他テーブルの(計算フィールドではない)フィールドに精度を確保しながら保存する、ということができないということは、1995年のV3リリース以来、FMの長年の弱点の一つであった。

そんなところにFM V10が現れたのは一年程前だったか。 このバージョンでFMはイベント発生時のスクリプト起動(以下、スクリプトトリガ)に対応した。 スクリプトトリガ、特に、レコード保存時にスクリプトを実行する「OnRecordCommit」により、上記の弱点が解消される可能性がでてきたように思われる。
以下、その原案。

1. 想定(目標)
以下のような簡単な在庫管理データベースがあり、出庫伝票作成時に各商品の出庫数を在庫数から差し引くことを目的とし、その実装(スクリプト)を考えてみる。
尚、出庫伝票は新規作成のみであり、明細の更新は不可(ホンナ無茶な)とする。

【図1】


【図2】

図1の出庫伝票で、[出庫数]に入力をしレコードを保存する動作を行った時に、在庫リストの[在庫数]の値が[出庫数]を差し引いた値に更新されればいい。 但し、このとき在庫リストの[在庫数]は計算ではなく、数値フィールドである、というのが今回の肝である。


2.実装
まずレコードを保存(Commit)時に在庫テーブルの[在庫数]フィールドから[出庫数]を差し引くスクリプトが必要である。

【図3】


という具合に、出庫明細を1行づつ移動して、関連する在庫レコードの[在庫数]から[出庫数]を差し引き、[在庫数]にセットする。 途中あるエラー処理は、[出庫数]更新時にエラーが発生した場合、このスクリプトで行ったすべての処理を取り消し、レコードを最後に保存した状態に戻すためのものである。

では、ユーザの操作(クリック)に依存せず、レコード保存(Commit)時に必ずこのスクリプトを実行するにはどうしたらよいか? ここでFM V10の新機能、スクリプトトリガの「OnRecordCommit」を使用する。 詳細はマニュアルを見ていただくとして、下図のように上記で作成したスクリプトを登録すればよい。

【図4】

以上で完了。


3.テスト
テストをしてみると、一応、機能する。
図1の出庫伝票入力後に保存を行うと、商品1~3の[在庫数]は正しく「9」に更新される。

また、[在庫数]更新時にエラーが発生すると、その出庫伝票が最後に更新されたときの状態に戻り、在庫レコードも元の状態に戻る。
たとえば、商品1と2の[在庫数]の更新には成功したが、商品3の[在庫数]の更新に失敗すると、すべての処理が取り消され、最後の保存状態に戻る。 このとき、出庫レコード自体が一度も保存されていなければ、明細レコードだけではなく、出庫レコードも保存されない(作成されない)筈である。 


4.課題
さて、上記のように当初の思惑は達成されたが、いくつかの課題と懸念がある。
  1. 今回は出庫伝票は新規のみである、ことを前提としているが、当然、これでは実用には耐ええない。出庫明細の更新、削除にも対応する必要がある。
  2. 在庫テーブルで極力競合が発生しないようにテーブル設計する必要がある。
  3. 十分なテスト --- マルチユーザで競合が発生しないこと、また競合発生時も整合性が確保されること。
  4. 上記実装が正しく機能しているか、検証する仕組みの構築

1.は面倒だか、明細の主キー、商品ID、更新前の[出庫数]と更新後の[出庫数]の差分を変数に記憶しておき、Commit時に個々の商品の[在庫数]からその差分を減算すれば、解決可能である。

クリティカルな環境で上記のような在庫ロジックを実装し、実際の運用まで持ち込むのはなかなか大変だと思われるが、在庫や残高の算出遅延が運用上のネックとなっているシステムでは、一考の価値があるのではなかろうかと。

以上

土屋


【関連リンク】

2012/8/1追記:
当社の在庫管理の講習で使用してるサンプルシステム「FMEasy在庫」を公開しました。フリー版/開発版のダウンロードは→こちら

【FMEasy在庫 の画面】


2009-12-08

Panda Cloud Office Protection エンジン更新後に Hyper-V 搭載サーバ機でトラブル発生

 Panda Managed Office Protection(以降MOP)がクラウド型エンドポイントセキュリティサービスの Panda Could Office Protection(以降COP) として 2009年12月1日より新サービスとして提供が始まったことに伴い、11月下旬から順次既存ユーザへのエンジンアップデートが行われました。

 今月に入ってから弊社環境でも COP エンジンの自動アップデートが行われ、つい昨日アップデート後のサーバ機の再起動を行ったわけですが、Hyper-V 搭載サーバ機では再起動時にネットワークカード(以降NIC)の挙動がおかしくなることを確認したため、今回はその現象と対応方法をまとめます。

【現象】
 COP エンジンの自動アップデート後にサーバ機の再起動を促すメッセージが出るが、ここで再起動をかけると、Hyper-V を運用中のサーバ機の NIC が正常に動作しなくなる。
 Ping チェックを行うと、実体 NIC、仮想 NIC 共に Ping 応答が断続的になったり、まったく応答がなくなったりする。

【対応方法】
 この現象は前回のMOPエンジン更新時にも発生し、当方で試したかぎりでは以下に示す方法以外では成功したことがありません。

1. Hyper-V マネージャの右ペインのメニュー項目より「仮想ネットワーク マネージャ」を選択し、稼働中の仮想ネットワークカードをすべて削除します。(削除前に設定情報はメモしておいてください)

2. Ping テストやインターネットブラウジングなどを行い、実体 NIC が正常に動作するようになっていることを確認します。
 仮想ネットワーク マネージャに戻り、左ペインより「新しい仮想ネットワーク」を選択して、右ペインで“追加”ボタンを押して新しい仮想 NIC を追加します。

3. Hyper-V マネージャの仮想マシンリストにある仮想マシンを右クリックし、表示されるサブメニューより「設定...」を選択します。
 当該仮想マシンの設定画面が表示されるので、左ペインより「レガシ ネットワークアダプタ」を選択し、上記で追加した仮想 NIC を割り当て直します。

この操作をすべての仮想マシンについて行います。
4. 仮想マシンを再起動し、Ping テストやネットブラウジングを行い、仮想 NIC が正常に動作するようになっていることを確認します。

この件については Panda にも現象を報告済みですが、もし上記の方法以外で有効な対応方法をご存じの方は情報提供していただけると大変有難いです。