web-dev-qa-db-ja.com

.NET Frameworkアプリが間違ったバージョンの.NET Core / Standard Platform Extension Assemblyを検索するのはなぜですか、どうすれば修正できますか?

。NET APIカタログ から、Microsoft.Win32.Registryクラスがアセンブリの.NET Standard + Platform Extensions 2.0パッケージで宣言されていることを理解していますMicrosoft.Win32.Registry, Version=4.1.1.0, PublicKeyToken=b03f5f7f11d50a3a

enter image description here

.NET Standard 2.0をターゲットとするクラスライブラリを作成しました。簡単なクラスを次に示します。

public class NetStandardClass
{
    public string GetHklmRegValue()
    {
        var lmKey = Microsoft.Win32.Registry.LocalMachine;
        var softwareKey = lmKey.OpenSubKey("Software"); 
        return "value";
    }
}

上記のクラスライブラリを参照する.NET Framework 4.7.2コンソールアプリケーションを作成しました。

class Program
{
    static void Main(string[] args)
    {
        string value = new ClassLibrary2.NetStandardClass().GetHklmRegValue();
    }
}

これをWindowsで実行すると、ランタイム例外がスローされます。

System.IO.FileNotFoundException: 'ファイルまたはアセンブリを読み込めませんでした' Microsoft.Win32.Registry、Version = 4.1.3.、Culture = neutral、PublicKeyToken = b03f5f7f11d50a3a 'または1つその依存関係の。システムは、指定されたファイルを見つけることができません。'

私が読んだ内容 に基づいて、このシナリオでアセンブリの読み込みの問題が発生することは、既知の問題の一部です。規定された回避策は 自動バインディングリダイレクト を有効にし、.NET FrameworkアプリケーションがProject.ConfigではなくPackageReferenceを使用していることを確認することです。上記のコードを共有したプロジェクトでこれを実行しましたが、まだエラーが発生します。しかし、私を最も混乱させるのは、エラーが.NET標準ではなく.NET Core/.NET Core + Platform Extensionsアセンブリ(Version = 4.1.3.0、PublicKeyToken = b03f5f7f11d50a3a)を示していることです。 (Version = 4.1.1.0、PublicKeyToken = b03f5f7f11d50a3a)またはAPIカタログからの.NET Framework(Version = 4.0.0.0、PublicKeyToken = b77a5c561934e089)バージョン:

enter image description here

これは、出力ディレクトリにあるMicrosoft.Win32.Registry.DLLによってさらに裏付けられます。

enter image description here

さらに読む に基づいて、次のいずれかを実行することで少し進歩できます。

  • <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>を.NET標準クラスライブラリのprojファイルに追加する

-または-

  • Microsoft.Win32.Registry NuGetパッケージを直接.NET Frameworkコンソールアプリケーションに追加します。

これらのいずれかにより、アセンブリのバージョンの一部が読み込まれますが、奇妙な動作が発生します。LocalMachineプロパティのNREを取得しますが、起こります。

enter image description here


だからここに質問があります:

1.)プロジェクトが.NET Frameworkアプリケーションなので、.NET Framework APIのMicrosoft.Win32.Registryクラス、特に同じAPIカタログが参照するmscorlibアセンブリを使用しないのはなぜですか?

enter image description here

2.)GitHub投稿の「回避策」が機能しないのはなぜですか?

3.).NET Core/...拡張バージョンのアセンブリを探しているように見えるのはなぜですか?

4.).NET標準クラスライブラリのNuGet Microsoft.Win32.Registryアセンブリを明示的にエクスポートするか、.NET Frameworkコンソールアプリケーションでパッケージを直接参照すると、Microsoft.Win32.Registry.LocalMachineがnullであるという奇妙な動作が発生する理由、これはWindowsマシンでは決して当てはまりませんか?

7
rory.ap

以下の回答は、Visual Studio 2019の最新バージョン(執筆時点ではv16.4.3)がインストールされていることを前提としています。これは結果に影響を与える可能性があるためです。

質問1):

1.)プロジェクトが.NET Frameworkアプリケーションであるため、.NET Framework APIのMicrosoft.Win32.Registryクラス、特に同じAPIカタログが参照するmscorlibアセンブリを使用しないのはなぜですか?

これは、プロジェクトが次のいずれかの方法で設定されている場合、v4.0.0.0 mscorlib Registryクラスを実際に使用します。

  • オプション1

    • クラスライブラリ:ターゲットフレームワーク= netstandard2.0、NuGetパッケージ= Microsoft.Windows.Registry(v4.5.0)
    • コンソールアプリ:ターゲットフレームワーク= net472、NuGetが "packages.config"モードに設定されている、NuGetパッケージ= Microsoft.Windows.Registry(v4.5.0)[およびAccessControlsとPrincipal.Windowsも依存関係があるため]
      • 注:ここで、Microsoft.Windows.Registryパッケージを追加しないと、通常、レジストリdllのバージョン4.1.1.0を検索するときにランタイムエラーが発生します。しかし、私が探しているバージョンは、現在インストールされている.NET Core SDKのバージョンに基づいていると思います。
  • オプション2 [これは本当に欲しいものだと思う]

    • クラスライブラリ:ターゲットフレームワーク= netstandard2.0、NuGetパッケージ= Microsoft.Windows.Registry(v4.5.0)
    • コンソールアプリ:ターゲットフレームワーク= net472、NuGetは "PackageReference"モードに設定され、NuGetパッケージ=なし
      • 注:VS2019では、「最初のパッケージのインストール時にフォーマットの選択を許可する」オプションがオンになっている場合、NuGetパッケージがpackages.configではなくプロジェクトファイルで参照されるPackageReferenceスタイルの使用を選択できます。通常、このモードを設定するためだけに1つのNuGetパッケージをanyをインストールする必要がありますが、その後、そのパッケージをアンインストールして、そのモードを維持できます。最初にnet472プロジェクトを作成する前に、デフォルトモードを設定することもできると思います。
      • 注:ここで、PackageReferenceモードは、他の.NET Standard 2.0クラスライブラリへのNuGetの依存関係を解決するのに役立ちます。package.configモードでは、自分で行う必要があるようです。

これは簡単に再現できるはずですが、並べ替えの問題を引き起こす可能性があるのは次のいずれかです。-古いバージョンのVS2019が使用されている-VSでNuGetに対してオンになっているバインディングリダイレクト設定のスキップ-.NET 4.7に対してオフになっている自動バインディングリダイレクト2プロジェクト-パッケージまたは参照の変更後にソリューションを「再構築」しない-.NET SDKまたはVS2019の更新をインストールまたは更新した後にコンピューターを再起動しない-packages.configファイルがまだある

また、上記のオプション1で、Microsoft.Windows.Registryパッケージを追加しないと、ランタイムでバージョン4.1を探すと失敗することをテストで確認しました。レジストリdllの1.0。しかし、最初にMicrosoft.Windows.Registry 4.7.0をインストールしてからランタイム4.1.3.0を探して失敗し、その後アンインストールしました(これにより、2つの依存パッケージAccessControlとPrincipal.Windowsが残っています)。 なしプロジェクトの再構築:実行すると、実行時に4.1.3.0バージョンが失敗し、探しているバージョンが失敗します。再構築すると4.1.1.0に戻ります。 2つの依存パッケージを削除しても、これは同じです。注:これは、NuGetパッケージをアンインストールするのではなく、プロジェクト内のDLLへの参照を単に削除した場合にも機能します。

質問2):

2.)GitHub投稿の「回避策」が機能しないのはなぜですか?

16.4.3よりも古いバージョンのVS2019を使用している可能性があるため、これが発生しているように感じます。古いバージョンを使用していても、PackageReferenceモードで実行時エラーが発生することがわかりました。私がVS2019を16.4.3に更新しました(申し訳ありませんが、どのリビジョンが実際に修正するのかわかりません)。これがさまざまなSDKとの予期しないやり取りであるかどうかはわかりません(おそらく、最近リリースされたものの、VSの古いリビジョンではサポートされていないものもあります)。また、packages.configファイルがまだ残っている場合にも問題になる可能性があります。

別の問題は、インストールされている可能性があり、ライブラリバージョンの要件が異なる他のNuGetパッケージによる干渉である可能性があります。

質問3):

3.).NET Core/...拡張バージョンのアセンブリを探しているように見えるのはなぜですか?

.NET Standard 2.0を参照する.NET 4.7.2プロジェクト(デフォルトでは.NET標準プロジェクトは.NET Coreプロジェクトです)では、.NETフレームワークではなく.NET Coreフレームワークを使用します。したがって、レジストリへの参照はデフォルトでは利用できません。レジストリの使用を許可するには、少なくともMicrosoft.Windows.Registryパッケージが必要です。これには、ライブラリの.NET 4.7.2 mscorlibバージョンのシムとして機能する機能があると考えられますが、フォールバックとしての4.1.1.0バージョン(代わりに.NET Coreプロジェクトから参照している場合は4.1.3.0バージョン)。

質問4):

4.).NET標準クラスライブラリのNuGet Microsoft.Win32.Registryアセンブリを明示的にエクスポートするか、.NET Frameworkコンソールアプリケーションでパッケージを直接参照すると、Microsoft.Win32.Registry.LocalMachineで奇妙な動作が発生する理由はnullですが、これはWindowsマシンでは当てはまりません。

私はこれを個人的にテストしておらず、上記をテストしたときにこの問題に遭遇しませんでしたが、これに対する私の気持ちは、dllが依存するdllを欠落している可能性が高いということです。しかし、それについてさらに考えると、そうだとすれば、別の実行時エラーが発生する可能性があります。問題は、直接エクスポートするためのものではなく、途中で何かが欠落している可能性があることです。

また、これをWindows以外のプラットフォームで実行すると、たとえばLinuxランタイムには存在しないと思われるため、レジストリがnullとして返される可能性があることにも注意します。

その他の注意事項:

この種のことは、一般的に.NET Frameworkを参照または参照するVSおよび.NET Coreには少しバグがあり、これを改善するために定期的に行われているという一般的な感覚を得ています。

また、予想外の問題が発生したこともあります。たとえば、コンソールアプリにインストールしたパッケージに関係なく、.NETスタンダードコンソールアプリを作成し、.NETスタンダードクラスライブラリを参照しても、ランタイムエラーが発生します。まったく同じターゲットフレームワークは特別な設定なしで機能すると思いますが、そうではありません。ただし、代わりに.NET Coreコンソールアプリを作成すると、正しく機能します。それは少し不可解ですが、ミックスのどこかに常に技術的な説明があります。

3
Andy Mudrak