プロセス外 (exe ファイルなど) の COM コンポーネントの COM オブジェクトをインスタンス化し、それを使用してコンポーネントが公開する COM メソッドを呼び出す単純な PHP スクリプトを作成しました。この COM メソッドは、最初の引数として渡された数値を単純に 4 倍し、その結果を 2 番目の引数 (参照渡し) に返します。以下に示すスクリプトは、WampServer 2.0 (Apache 2.2.11 / PHP 5.3.1) 上の私のローカル開発マシンで正常に動作します。COM コンポーネントは、Delphi を使用して構築された Win32 実行可能ファイルです。
<?php
// ensure no time limit is imposed
set_time_limit(0);
// show all errors, warnings and notices whilst developing
error_reporting(E_ALL);
$numIn = 3;
$numOut = new VARIANT(1, VT_I4);
echo '----- BEFORE ---------' . '<br>';
echo 'NumIn: ' . $numIn . '<br>';
echo 'NumOut: ' . $numOut . '<br>';
echo '----------------------' . '<br>';
$oleapp = new COM("OleAutomationFeasibilityModel.Automation") or die ("Could not initialise feasibility model object.");
echo '<br />COM object created version = ' . $oleapp->Version . '<br /><br />';
$oleapp->CalculateWithVariants($numIn, $numOut);
unset($oleapp);
echo '----- AFTER ---------' . '<br>';
echo 'NumIn: ' . $numIn . '<br>';
echo 'NumOut: ' . $numOut . '<br>';
echo '----------------------' . '<br>';
?>
注: 私が理解しているように、整数や文字列などの一般的なデータ型は機能しないため、VARIANT 型を使用した COM メソッドへの参照によってのみパラメーターを渡すことができます ( http://www.php.net/manual/を参照)。 ja/ref.com.php#45038 )。
次に、COM コンポーネントを正常に登録するスタートアップ スクリプトを使用して、Azure Web ロール (クラウド サービス) を作成およびデプロイしました。つまり、適切なレジストリ キーがレジストリに表示されました。COM コンポーネントと対話できることをさらに確認するために、RDP を使用してクラウド サービス インスタンスに接続し、COM コンポーネントのメソッドをテストするための GUI を提供する Access アプリケーションがあるため、Microsoft Access Runtime 2010 をインストールしました。このアプリケーションを実行し、COM コンポーネントとのやり取りに成功し、COM コンポーネントを使用してCalculateWithVariants
メソッドに整数を渡すと、予想される 4 倍の結果が返されました。これで、COM コンポーネントがインストールされ、Azure クラウド サービス インスタンスで操作できることがわかりました。
次に、上記の PHP スクリプトを Web ロールに含めて、Azure にデプロイしました。残念ながら、ブラウザーからスクリプトを呼び出すと、HTTP エラー 500 (内部サーバー エラー) が発生し、その理由を突き止めるのに苦労しています。を参照しているすべての行をコメントアウトして$oleapp
も、同じエラーが発生します。バリアント オブジェクトをインスタンス化する行をさらにコメント アウトすると、エラーは発生しません。COM オブジェクトをインスタンス化する行とその下の行を元に戻すと、エラー メッセージは表示されませんが、エコーされるテキストは、COM オブジェクト作成行の前の行、つまりVersion
メソッドの呼び出しに失敗するものだけです。そのため、バリアント オブジェクトの作成と COM オブジェクトの作成に苦労しているようです。
この問題を解決する方法に関して、私は少し立ち往生しています。したがって、誰かが前進するための指針を持っているなら、私は非常に感謝しています.
更新 1
Azure プラットフォームで別のアクションを試すことにしました...
- Windows Server 2008 R2 OS でAzure仮想マシンを作成する
- このアプローチが機能するかどうかをテストするための迅速かつ簡単な方法として、 WampServer 2.2E (Apache 2.2.22 / PHP 5.3.13 / MySQL 5.5.24) を VM にインストールします。
- 上記のPHPスクリプトをWampServerの「wwwディレクトリ」にコピーします
- WampServerの起動
- WampServer メニューから「Put Online」オプションを選択します (Windows タスクバーの通知領域にある WampServer アイコンを左クリックしてアクセスします)。
- ポート 80 への接続を許可する VM ファイアウォールの「受信規則」を作成する
...そしてありがたいことに、スクリプトは正常に実行されました!
理想的には、完全な VM で PHP のインストールを維持する必要がないため、これを Azure クラウド サービスとして機能させたいと考えています。
更新 2
クラウド サービスを再起動してから、クラウド サービスのインスタンスにリモート接続し、アプリケーション イベント ビューアーを調べてみました。起動中に WMI が 1 つのエラーを記録したことを確認しました。
クエリ "SELECT * FROM __InstanceModificationEvent WITHIN 60" を使用したイベント フィルター WHERE TargetInstance ISA "Win32_Processor" AND TargetInstance.LoadPercentage > 99" エラー 0x80041003 のため、名前空間「//./root/CIMV2」で再アクティブ化できませんでした 問題が修正されるまで、イベントはこのフィルターを介して配信できません。
その後、上記のスクリプトを数回実行し、Application Event Viewer を再確認しましたが、何も記録されていませんでした。
また、IIS ログと Azure log
、startup-tasks-log
およびstartup-tasks-error-log
ファイルをチェックしても無駄でした。