0

プロセス外 (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 プラットフォームで別のアクションを試すことにしました...

...そしてありがたいことに、スクリプトは正常に実行されました!

理想的には、完全な 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 logstartup-tasks-logおよびstartup-tasks-error-logファイルをチェックしても無駄でした。

4

1 に答える 1

0

昨年、これを解決することをあきらめた後。私は今週、それを解決するために別の協調的な努力をし、成功しました!

基本的に、(a) php_com_dotnet.dllCOMを有効にしてとクラスの使用を許可しVARIANT、(b) デフォルトの Local Activation アクセス許可を付与IIS_IUSRSして、COM コンポーネントへのアクセスを許可する必要がありました。以下に、実行した詳細な手順をリストしました...

  1. Web ロールのbinフォルダーにphpというフォルダーを追加します。

  2. PHP 5.3.15 / 5.4.5 以降、COMおよびVARIANT クラスを使用するには、 php.ini内で php_com_dotnet.dllを有効にする必要があります。以前のバージョンの PHP では、これらの拡張機能がデフォルトで有効になっていました (ソース: http://www.php.net/manual/en/com.installation.php )。phpフォルダーで、次の行のみを含む php.ini ファイルを作成します...

    [COM_DOT_NET] 
    extension=php_com_dotnet.dll
    
  3. 次のコンテンツを含むbinフォルダーにSetDCOMPermission.regファイルを作成し、既定のローカル アクティベーション アクセス許可を...IIS_IUSRS

    [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\OLE]
    "DefaultLaunchPermission"=hex(3):01,00,04,80,74,00,00,00,84,00,00,00,00,00,\
    00,00,14,00,00,00,02,00,60,00,04,00,00,00,00,00,14,00,1F,00,00,00,01,01,00,\
    00,00,00,00,05,12,00,00,00,00,00,18,00,1F,00,00,00,01,02,00,00,00,00,00,05,\
    20,00,00,00,20,02,00,00,00,00,18,00,0B,00,00,00,01,02,00,00,00,00,00,05,20,\
    00,00,00,38,02,00,00,00,00,14,00,1F,00,00,00,01,01,00,00,00,00,00,05,04,00,\
    00,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00,01,02,00,00,00,00,00,\
    05,20,00,00,00,20,02,00,00
    

    上記のレジストリの変更がすべての人に有効かどうかわからないので、私が使用したプロセスをここに文書化します(基本的には、RegFromAppIIS_IUSRSというプログラムを使用して、COM セキュリティで既定のローカル アクティベーション アクセス許可を付与するときにレジストリに加えられた変更を記録する必要がありました。レジストリの変更を .reg ファイルとして Web ロールのbinフォルダーに保存します)。

  4. アウトプロセス COM コンポーネント ( OleAutomationFeasibilityModel.exeファイル) をbinフォルダーにコピー アンド ペーストします。

  5. binフォルダーにRegisterOleAutomationFeasibilityModel.cmdファイルを作成して、COM コンポーネントを登録し、それを起動するために必要なアクセス許可を設定します...

    chcp 1252>NUL
    OleAutomationFeasibilityModel.exe /regserver
    regedit.exe /s SetDCOMPermission.reg
    exit /b 0
    
  6. ServiceDefinition.csdefファイルで、終了 Startup タグの直前に .cmd ファイルへの参照を挿入します。

    <Task commandLine="RegisterOleAutomationFeasibilityModel.cmd" executionContext="elevated" />
    
  7. Web ロールを発行する

同じような状況の誰かに役立つことを願っています!

于 2014-02-02T21:56:46.877 に答える