2013-03-05 3 views
7

この問題は数日間頭痛を引き起こしていましたが、その理由がわかりません。私はこれが私のマシン特有の環境問題だとはっきりと確信していますが、それでも私はテストで問題を引き起こしています。64ビットタイプのライブラリと32ビットタイプのライブラリが同期外れ

私はVisual Studio 2010 Professionalを使用してC#でDLLを作成しています。バージョン1は以下の通りです。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace TestCOM 
{ 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [System.Runtime.InteropServices.ComVisible(true)] 
    [System.Runtime.InteropServices.ProgId("TestCOM.Class1")] 
    [System.Runtime.InteropServices.Guid("803A1B2F-1CDA-4571-9084-87500388693B")] 
    public class Class1 
    { 
     public void showMessage() 
     { 
      MessageBox.Show("Hello from TextCom"); 
     } 

    } 
} 

このアセンブリはうまくコンパイルされ、すべてが良好です。 COMオブジェクトとして登録するには、次のスクリプトを実行します(最初は32ビット、次に64ビット)。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe TestCOM.dll /codebase /nologo /tlb:TestCOM32.tlb 
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe TestCOM.dll /codebase /nologo /tlb:TestCOM64.tlb 

次に、次のスクリプトを使用してテストしてください。

dim tc 
set tc = CreateObject("TestCOM.Class1") 
tc.showMessage() 

Iスクリプトをテストするためにcsriptを使用するので、私はそれが使用するビット深度を制御することができる - 私は64ビットで一度32ビットで一度それをテストし。これまでのところすべてが良いです。私は修正前

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

namespace TestCOM 
{ 
    [ClassInterface(ClassInterfaceType.AutoDual)] 
    [System.Runtime.InteropServices.ComVisible(true)] 
    [System.Runtime.InteropServices.ProgId("TestCOM.Class1")] 
    [System.Runtime.InteropServices.Guid("803A1B2F-1CDA-4571-9084-87500388693B")] 
    public class Class1 
    { 
     public void showMessage() 
     { 
      MessageBox.Show("Hello from TextCom"); 
     } 

     public void HelloWorld() 
     { 
      MessageBox.Show("Hello World!!"); 
     } 

    } 
} 

を次のように、機能を追加するために、元のアセンブリを修正今

は、私が「ます。regasm /登録解除」を使用して、ライブラリを登録解除し、それが未登録のに成功し、すべてのタイプを報告しました。

ライブラリを登録すると、変更が加えられて元のテストスクリプトが完全に機能します。テストスクリプトを拡張して、新しいHelloWorld関数を呼び出す場合。

32ビットスクリプトでは、完全に動作します。 64ビットスクリプトでは、TestCOM.Class1オブジェクトにそのような関数が存在しないと文句を言います

私はこれを何とかしようとしましたが、なぜ新しい機能が32ビットで利用できるのかわかりません64ビット通話ではありません。

私は間違っていますか?私が気づいていない64ビットのものや、変更が必要なレジストリ設定のどこかにキャッシュがありますか?

明確になります。 1.ビルドアセンブリ 2.登録スクリプトを使用して64 3.テストのための32と一度に一度、のregasmを使用して - すべてが 4.登録解除ライブラリを作品 5.変更を行い、ステップ2 7ごとに 6.登録を再構築テストは32ビットで動作しますが、64では動作しません。

答えて

2

明らかに、あなたはDLL地獄に悩まされています。常にCOMの周りにDLLの古いバージョンがロードされています。あなたのGACは初期の実験で汚染されている可能性があります.GACed版が最初に見つかるでしょう。あなたは[Guid]を指定することでそれを悪化させ、新しいクラスを古いクラスと同じに見えるようにします(同一ではないにしても)。 COMが新しいバージョンのクラスを見つけることができないことをCOMから通知しないようにします。

最も信頼性の高い、ノイズの多い、DLLがどこから来たのかを確認する方法は、SysInteralsのProcMonユーティリティを使用することです。レジストリキーを読み、DLLを読み込むことがわかります。どのディレクトリから来たのかを見ることができます。それがGACでないことを確認し、gacutil/uで削除して、ファイルのタイムスタンプをチェックして再構築してください。

+0

あなたは絶対的な伝説です。 何らかの理由でdllの以前のビルドのコピーがc:\ windows \ system32にあったようです。 このコピーを削除すると、すぐに問題が解決され、何かを再登録する必要はありません。 ありがとうございました - 何が起きているのかを見るためにprocmonを使用することは決してありませんでした。 最後に、GUIDを指定しないでください。私はいつもあなたがしなければならないと言われましたか? – DFriend

関連する問題