ティアのホームページ☆ミ:ID 1233:タイトル 不具合の原因が分かった! 2 oC
no prev page 1/1ページ(1件) no next page
To Close..不具合の原因が分かった! 2 2015年01月26日14時38分
不具合とは・・・・(以下略)

では分からないのでw


今回も、ひょんな事から原因は分かりました。

但し、原因は、未だに分かりません。

ではそれが一体どんな不具合かというと、

一言で言うと、System.__ComObjectです。


Comを通じて、OLE的な何かでもいいですし、そのまんまObjectでも良い。
そう言った物を.net Frameworkで利用すると・・・・

検索すると良く例が挙がっているので拝借しますが、例えばexcelだと
Microsoft.Office.Interop.Excel
と言うのが正式名称です。


開発環境では、オブジェクトを生成して、使用して・・・・っていう最中に常に

Microsoft.Office.Interop.Excel.xxxxxという名称が見えています。

しかし、ユーザーのPCでは見えている場合と見えていない場合があります。
今のところ、何が原因で、見えるところと見えないところがあるのかは分かっていません。


ただ、見えない所では、その後の処理の所でつまずいていたのです。

COMを通じて他社製品を使う場合、ユーザーの環境によっては、それが最新であったり古かったりするために、相手側のバージョンだとか、インターフェイスの有無とかを必ず確認してから動作させます。

例えば、エクセルの場合、表だとか、行だとか、列だとか、そう言ったオブジェクトを取得するときは、Comを通じて、取りあえずオブジェクトを取得します。

このオブジェクトがそれその物かを確認してから、セルにデータを書き込んだり、読み込んだり、そう言った事をします。

オブジェクトに対して、オブジェクトが本物かどうかの確認というのは、I/Fの有無、そして、I/Fを利用してバージョンの確認という手順で行います。


テストでは正しく動作しているので、Microsoft.Office.Interop.Excelという名称が見えていますが、実際のユーザー環境では違う物がオブジェクトとして取得される可能性があるので、I/Fの有無の確認は非常に重要です。

しかし、一部のwindouws環境では「System.__ComObject」がオブジェクトとして渡されていました。
このSystem.__ComObjectは.net環境でCOMを使った場合に、取りあえずなんだか分からないオブジェクトを取得したときに自動で渡される型です。


これは、


「名称不明」


とでも思ってください。

System.__ComObjectは何らかのCOMオブジェクトで有る事を通知しては居ますが、その実体については全くノータッチです。

ですから、これに対してIFの一覧の取得を行っても、

存在しない

という、返事しか帰ってきません。


.net Frameworkにとっては、System.__ComObjectはそれ以上でもそれ以下でも無い、System.__ComObject意外としては扱う気が全くないと言うことです。

ですから、COMにより取得したSystem.__ComObjectは自分で中身を判別してあげなくてはいけません。

しかし、中身を判別するために行う、FullNameの取得も、GUID取得も.netが中身を一切見ないためにSystem.__ComObjectと言う返事しか帰ってきません。


話になりませんね(笑


まぁ、ググるとすぐにMSのページが見付かりますが、

そこで利用するのが、isとasです。

isはSystem.__ComObjectで取得したオブジェクトがが、指定した方にキャストできるかどうかを判別します。

if(obj is Microsoft.Office.Interop.Excel.xxxx)
{
}
とでもすれば、中身がexcelの申し子かどうか分かります。

今までは、

obj.GetType().GetInterface()という方法で処理していました。

もともとはCppだったコードをC#に移植した辺りから、おそらくこの問題は合ったのでは無いかと思うのですが、

CPPではQueryInterfaceとDispatchを駆使してやっていたことが、1行で済む〜とか思っていたのが、大誤算です。

そもそもCppでさえQueryInterfaceを使えばインターフェースを簡単に取得できることが、C#のほうが直接I/Fの取得が出来ないとは全く思っていなかったあたしの落ち度ではあるんですが?

開発環境では、オブジェクトの中身が表示されていたので、全くもって正しく取得できていたのにもかかわらず、中身が見えていなかったためにエラーとして処理され、不具合が発生していたとは思いもしませんでした。


当たり前な話ですが、開発環境以外のPCでの動作確認も行っています。

それなのに、何で、こういった問題が起きたのかは、未だに分かっていません。


ただ、早期に対応するために
お客さんが不具合調査に協力してくれたから、事件は大きく進みました。

まず、驚いたのはSystem.__ComObjectってなんぞ〜って事。

初めの内は、この不具合を言うお客さんも少なかったので、Excelの登録が壊れていて、インターフェイスが足りないんじゃ無いかと思っていたんですよ。

デバッグのために、仕込んだ専用のコードで、取得したオブジェクトの詳細を表示させたんですけどね?
詳細なんて全くなにも無い(笑

そこからはMSだとかあちこちのサイトとにらめっこですよ?

運良く手元のPCの一台で同じ現象が発生したために、このPCでどうやったら動くようになるのか調査して・・・

まぁ as だとか is を発見したんですが?

GetInterfaceの所を全部 is に書き換えて終わりました。

因みに、asはisよりももうちょっと機能が多くて、 キャストできるならそのまま代入しろって感じの命令です。

isが
if( obj is xx ){}
って感じなのに対して

asは

xx a;
a = obj as xx;
因みにisの様に使うことも出来て
if( (obj as xx) != null ){}

見たいです。

尚、今回の不具合は、厳重にチェックをしていたのが原因で発生していたので、
チェックをもうちょっとルーズにしておけば、動いていたと言うのも問題の一つで、

チェックを何処までやるのかというのも課題になりました。

何はともあれ、開発環境と、実環境で、同じような挙動になるように対応して貰いたいです>MS
閉じる
テーマ:日記 URL:https://tsukiyori.sakura.ne.jp/index_m.cgi?ID=1233
 
no prev page 1/1ページ(1件) no next page