。NET APIカタログ から、Microsoft.Win32.Registry
クラスがアセンブリの.NET Standard + Platform Extensions 2.0
パッケージで宣言されていることを理解していますMicrosoft.Win32.Registry, Version=4.1.1.0, PublicKeyToken=b03f5f7f11d50a3a
。
.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)バージョン:
これは、出力ディレクトリにあるMicrosoft.Win32.Registry.DLLによってさらに裏付けられます。
さらに読む に基づいて、次のいずれかを実行することで少し進歩できます。
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
を.NET標準クラスライブラリのprojファイルに追加する-または-
Microsoft.Win32.Registry
NuGetパッケージを直接.NET Frameworkコンソールアプリケーションに追加します。これらのいずれかにより、アセンブリのバージョンの一部が読み込まれますが、奇妙な動作が発生します。LocalMachine
プロパティのNREを取得しますが、起こります。
だからここに質問があります:
1.)プロジェクトが.NET Frameworkアプリケーションなので、.NET Framework APIのMicrosoft.Win32.Registry
クラス、特に同じAPIカタログが参照するmscorlib
アセンブリを使用しないのはなぜですか?
2.)GitHub投稿の「回避策」が機能しないのはなぜですか?
3.).NET Core/...拡張バージョンのアセンブリを探しているように見えるのはなぜですか?
4.).NET標準クラスライブラリのNuGet Microsoft.Win32.Registry
アセンブリを明示的にエクスポートするか、.NET Frameworkコンソールアプリケーションでパッケージを直接参照すると、Microsoft.Win32.Registry.LocalMachine
がnullであるという奇妙な動作が発生する理由、これはWindowsマシンでは決して当てはまりませんか?
以下の回答は、Visual Studio 2019の最新バージョン(執筆時点ではv16.4.3)がインストールされていることを前提としています。これは結果に影響を与える可能性があるためです。
1.)プロジェクトが.NET Frameworkアプリケーションであるため、.NET Framework APIのMicrosoft.Win32.Registryクラス、特に同じAPIカタログが参照するmscorlibアセンブリを使用しないのはなぜですか?
これは、プロジェクトが次のいずれかの方法で設定されている場合、v4.0.0.0 mscorlib Registry
クラスを実際に使用します。
オプション1
オプション2 [これは本当に欲しいものだと思う]
これは簡単に再現できるはずですが、並べ替えの問題を引き起こす可能性があるのは次のいずれかです。-古いバージョンの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.)GitHub投稿の「回避策」が機能しないのはなぜですか?
16.4.3よりも古いバージョンのVS2019を使用している可能性があるため、これが発生しているように感じます。古いバージョンを使用していても、PackageReferenceモードで実行時エラーが発生することがわかりました。私がVS2019を16.4.3に更新しました(申し訳ありませんが、どのリビジョンが実際に修正するのかわかりません)。これがさまざまなSDKとの予期しないやり取りであるかどうかはわかりません(おそらく、最近リリースされたものの、VSの古いリビジョンではサポートされていないものもあります)。また、packages.configファイルがまだ残っている場合にも問題になる可能性があります。
別の問題は、インストールされている可能性があり、ライブラリバージョンの要件が異なる他のNuGetパッケージによる干渉である可能性があります。
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.).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コンソールアプリを作成すると、正しく機能します。それは少し不可解ですが、ミックスのどこかに常に技術的な説明があります。