3

DLL が C# にインストールされているかどうかを検出する最も効果的な方法は何ですか? 私はこれに興味があります:msvcr80.dll。C# プログラムから LoadLibrary 相互運用 API 呼び出しを呼び出そうとしましたが、機能しませんでした。私はそれを検出する必要があるだけで、それを利用する必要はありません。

4

2 に答える 2

4

msvcr80.dllのピンボーキングは困難です。これは特別なDLLであり、Windowsのサイドバイサイドキャッシュ(c:\ windows \ winsxs)に格納され、通常、マシンには多くのバージョンがインストールされています。私はこのマシンに16個持っています。サイドバイサイドキャッシュは、アンマネージDLLのGACに相当します。コードでこのようなDLLを使用するには、使用するmsvcr80.dllの特定のバージョンを示すマニフェストが必要です。

したがって、最初に行う必要があるのは、独自のプログラムのマニフェストにエントリを追加することです。プロジェクト+新しいアイテムの追加、アプリケーションマニフェストアイテムテンプレートを選択します。msvcr80.dllへの依存関係を含めるように編集する必要があります。マニフェストは次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.6195" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
        </dependentAssembly>
    </dependency>
</asmv1:assembly>

バージョン属性に注意してください8.0.50727.6195。これは現在最新です。世の中に出回っている他の一般的なリビジョンは、42(元のRTMバージョン)と762(SP1バージョン)および多数のセキュリティアップデートです。通常、マニフェストで.42を使用できます。更新によってデプロイされたパブリッシャーポリシーファイルは、マシンにインストールされている最新バージョンにリダイレクトされます。

また、processorArchitecture属性に注意してください。64ビットバージョンのDLLを使用する場合は、「amd64」が必要です。x86を使い続け、プログラムが32ビットモードで実行されるようにすることをお勧めします。EXEプロジェクトを右クリックし、[プロパティ]、[ビルド]タブ、[プラットフォームターゲット]=x86を選択します。

[DllImport]を使用してDLLから関数を呼び出すことができるようになりました。好き:

    [DllImport("msvcr80.dll", CallingConvention = CallingConvention.Cdecl)]
    private static extern IntPtr _errno();

何の役にも立たない無垢な関数を意図的に選びました。これをピンボークして、必要なバージョン番号のDLLがインストールされているかどうかをテストできます。例外をキャッチして、そこにないことを確認します。例外なく実行したい場合は、LoadLibrary()をpinvokeします。

私はあなたがこれらの合併症を完全に期待していなかったと推測するつもりです。まったく異なるアプローチは、Windowsコードで使用される同等のDLLを使用することです。「異常な」機能をピンボークしようとしない限り、これは問題ありません。Windowsのすべてのインストールにはmsvcrt.dllがあり、その存在を確認する必要はなく、マニフェストも必要ありません。[DllImport]属性でDLL名を変更するだけです。ただし、MicrosoftがこのCRTのプライベートコピーを大幅に変更した場合、いつかプログラムが破損する可能性があることに注意してください。

于 2013-01-28T18:11:49.680 に答える
1

PATH環境変数の下のディレクトリとグローバルアセンブリキャッシュの両方をチェックする必要があります。これは、このAPIを使用して行うのが最適です。

于 2013-01-28T17:16:09.887 に答える