7

この問題が原因で数日間頭が痛くなり、その理由がわかりません。これは私のマシンに固有の環境問題であると確信していますが、それでもテストで問題が発生します。

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()

csript を使用してスクリプトをテストするので、使用するビット深度を制御できます。32 ビットで 1 回、64 ビットで 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");
        }

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

    }
}

変更の前に、「regasm /unregister」を使用してライブラリの登録を解除すると、すべてのタイプが正常に登録解除されたと報告されました。

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

32 ビット スクリプトでは、完全に機能します。64 ビット スクリプトでは、TestCOM.Class1 オブジェクトに対してそのような関数が存在しないというエラーが表示されます。

私はこれをあらゆる方法で試しましたが、新しい関数が 32 ビットの呼び出し元で使用できるのに、64 ビットの呼び出しでは使用できない理由を特定できません。

私は何を間違っていますか?私が認識していない64ビットのもののどこかにキャッシュがありますか、またはレジストリ設定を変更する必要がありますか?

明確にするために。1. アセンブリをビルドする 2. regasm を使用して登録する (32 用に 1 回、64 用に 1 回) 3. スクリプトを使用してテストする - すべてが機能する 4. ライブラリを登録解除する 5. 変更を加え、再構築する 6. ステップ 2 に従って登録する 7. テストは 32 ビットで動作する、しかし64ではありません。

4

1 に答える 1

2

明らかに、あなたは DLL 地獄に苦しんでおり、常に COM の周りにあり、古いバージョンの DLL をロードしています。GAC は、以前の実験によって汚染された可能性があります。GAC されたバージョンが常に最初に検出されます。[Guid] を指定すると、新しいクラスが古いクラスと同じように見えますが、同一ではありません。新しいバージョンのクラスが見つからないことを COM が通知しないようにします。

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

于 2013-03-05T14:51:24.160 に答える