Re: The Windows English CHM Sample with MS Word Automation.
I see that $Word->Release() is called after $Word->Quit().
This seems to be erroneous. Actually, $Word->Release() should not have to be called if proper COM garbage collection is taking place. Release() is a C++ construction not used in either Visual Basic or VBScript or even MS-JScript. Just to be sure, however, I ran the sample through php.exe (5.04 CLI on Windows XP SP1 with Office 2003) and got a RPC failed error on the line containing $Word->Release(). The rest of the sample works fine, and the results are as expected. So, I propose 2 scenarios:
1.There is a problem with the documentation (more likely).
2.There is a problem with PHP504 itself, as this problem is reproduced with any COM Automation call, not just Word.
PHP と COM
PHP は Win32 プラットフォーム上で COM と DCOM オブジェクトに アクセスすることができます。
- とある計算を行う DLL を作成しました。これを PHP で実行させる方法は ありますか?
- 'Unsupported variant type: xxxx (0xxxxx)'とはどういう意味ですか?
- PHP でビジュアルオブジェクトを操作できますか?
- COM オブジェクトをセッション情報として保存できますか?
- COM の出力するエラーをトラップできますか?
- PHP スクリプトから DLL を作成することはできますか? Perl では できるのですが。
- 'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'とはどういう意味ですか?
- COM オブジェクトをリモートサーバーから実行するにはどうすればよいですか?
- 'DCOM is disabled in C:\path...\scriptname.php on line 6' という エラーが発生しました。どうすればよいですか?
- PHP を使用したページで ActiveX オブジェクトをロード/操作することは できますか?
- 実行中のコンポーネントのインスタンスを取得することはできますか?
- COM オブジェクトから送られてくるイベントを扱う方法はありますか?
- 2 つ以上のインターフェイスを公開している COM オブジェクトのメソッドを 呼び出そうとして困っています。どうすればよいですか?
- PHP は COM を扱えるということは分かりました。では COM+ については どうですか?
- PHP が COM オブジェクトを操作することができるということは、MTS を 使ってコンポーネントリソースを扱えると考えてもよいということですか?
- とある計算を行う DLL を作成しました。これを PHP で実行させる方法は ありますか?
-
もしそれが普通の DLL なら、現在のところ PHP からそれを実行する手段は ありません。DLL が COM サーバーを含んでいて IDispatch インターフェイスが 実装されている場合、PHP からアクセスすることができます。
- 'Unsupported variant type: xxxx (0xxxxx)'とはどういう意味ですか?
-
多くの VARIANT タイプとその組み合わせがあり、そのほとんどは サポートされていますが、残りのいくつかは未だ実装されていません。 また配列も完全にサポートされているわけではなく、PHP と COM の間で 受け渡しが可能なのは 1 次元の添字付配列のみです。もしこの他に サポートされていないタイプを見つけた場合は(既知でなければ)、 できる限りの情報を添えてバグとして報告してください。
- PHP でビジュアルオブジェクトを操作できますか?
-
基本的には可能です。しかし PHP はほとんどの場合ウェブスクリプティングの 言語として使用されウェブサーバー上で実行されるため、ビジュアルオブジェクトが サーバーのデスクトップに現れることはありません。もし PHP を アプリケーション作成に使用する、すなわち PHP-GTK と合わせて 使用する場合にはアクセスに制限はありません。COM を通じて ビジュアルオブジェクトを操作することができます。
- COM オブジェクトをセッション情報として保存できますか?
-
できません。COM インスタンスはリソースとして扱われるため、1 つの スクリプトを実行している間のみ使用可能です。
- COM の出力するエラーをトラップできますか?
-
PHP 5 では、COM 拡張モジュールは com_exception 例外をスローします。これをキャッチし、code メンバを調べることで次にすべきことを決定できます。
PHP 4 では、PHP が提供する方法(@, track_errors, ...)を使用して COM のエラーをトラップすることはできません。
- PHP スクリプトから DLL を作成することはできますか? Perl では できるのですが。
-
いいえ、残念ながら PHP にはそのようなツールはありません。
- 'Unable to obtain IDispatch interface for CLSID {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'とはどういう意味ですか?
-
このエラーが発生する理由はいくつかあります。
- CLSID が正しくない
- 要求された DLL が無い
- 要求されたコンポーネントが IDispatch インターフェイスを実装していない
- COM オブジェクトをリモートサーバーから実行するにはどうすればよいですか?
-
ローカルオブジェクトを実行するのと全く同様です。ただ、COM コンストラクタの 2 番目のパラメータにリモートマシンの IP アドレスを 渡すだけです。
php.ini に com.allow_dcom=
TRUEをセットするのを忘れないでください。
- 'DCOM is disabled in C:\path...\scriptname.php on line 6' という エラーが発生しました。どうすればよいですか?
-
php.ini を編集して com.allow_dcom=
TRUE. としてください。
- PHP を使用したページで ActiveX オブジェクトをロード/操作することは できますか?
-
これは PHP とは関係ありません。ActiveX オブジェクトは、HTML ドキュメントから要求があった場合にクライアント側でロードされます。 PHP スクリプトとは関係が無く、従ってサーバー側と直接やりとりすることも できません。
- 実行中のコンポーネントのインスタンスを取得することはできますか?
-
モニカーを使用すれば可能です。同じ Word インスタンスに対して複数の 参照を取得したい場合は、以下のようにしてインスタンスを生成します。
<?php $word = new COM("C:\docs\word.doc"); ?>こうすれば、実行中のインスタンスが無い、もしくはインスタンスの 取得が不可能だった場合には新規に生成され、インスタンスが取得できた 場合にはそのハンドルを返します。
- COM オブジェクトから送られてくるイベントを扱う方法はありますか?
-
イベントシンクを定義し、 com_event_sink() を使用してそれをバインドすることが可能です。PHP でイベントシンククラスの 雛形を作成するために com_print_typeinfo() を 使用することが可能です。
- 2 つ以上のインターフェイスを公開している COM オブジェクトのメソッドを 呼び出そうとして困っています。どうすればよいですか?
-
この問題に対する答えは、簡単ですが残念なものです。正確には わかりませんが、おそらく打つ手はありません。もしこの問題に関する 具体的な情報があったら» 私 に教えてください。
- PHP は COM を扱えるということは分かりました。では COM+ については どうですか?
-
COM+ とは MTS(Microsoft Transaction Server) と MSMQ(Microsfot Message Queue Service) を通じてコンポーネントを操作する フレームワークによって COM を拡張したものです。が、PHP がそういった コンポーネントをサポートするにあたって特別に必要なことはありません。
- PHP が COM オブジェクトを操作することができるということは、MTS を 使ってコンポーネントリソースを扱えると考えてもよいということですか?
-
PHP それ自体はまだトランザクションをサポートしていません。従って エラーが発生してもロールバック処理は行われません。もし トランザクションをサポートするコンポーネントを使用する場合は、 自分でトランザクション処理を実装する必要があります。
It may be obvious to everyone else but...
If you want to write your own COM DLL in MSVC++6 and you want to pass it a string, you need the following in your .idl file:
HRESULT function_name([in] BSTR parameter_name,
[retval, out] BSTR * retval);
retval is the result of your function as a string to be passed back.
BSTR is an unsigned short *, so if you want to use your string with STL string etc. you may need to convert parameters to and from char *.
The burden of my message is that from PHP
$comThing = new COM("comThing.comThing");
print $comThing->function_name("Jeremy");
Jeremy will be marshalled as wide chars, which match BSTR.
ONE SAMPLE USING MS-XML3 PARSER ON WINDOWS
<?
$xml= new COM("Microsoft.XMLDOM");
$xml->async=false;
$xml->load("STYLE.xml");
$xsl = new COM("Microsoft.XMLDOM");
$xsl->async=false;
$xsl->load("STYLE.xsl");
$response=$xml->transformNode($xsl);
print $response;
?>
In reference to question 1:
On one project I had a dll that exposed certain functions I wished to call from within PHP. I created a PHP Module which had a matching function for each in the DLL. The PHP Module did no processing, merely served as an adapter for the original DLL.
in response to item #1 above: "If this is a simple DLL there is no way yet to run it from PHP."
Answer: There are several different packages/add-ons to php that enable low level access to the windows api. One of the most popular of these packages is available at http://www.winbinder.org
Winbinder does have the ability to load a dll and call it's functions. Winbinder also provides a large set of windows apis for creating windows and controls. This is useful for creating stand-alone desktop apps. It is a possible alternative to php-gtk.
I've had mixed results with Winbinder, some things work very well, others are buggy; source code is available. It's worth a look, Evaluate carefully.
Be careful with function com_event_sink(), it doesn't totally work : when catching events, all parameters given to your callback function have the same value as the last one => see bug http://bugs.php.net/bug.php?id=31040
