BinフォルダーからDLLをインポートしているWebアプリケーションがあります。
_const string dllpath = "Utility.dll";
[DllImport(dllpath)]
_
私がやりたいのは、まず現在のプロジェクトではなく、別の場所にあるフォルダーからDLLをインポートすることです。
そのフォルダーのパスはレジストリキーに格納されます。
どうすればいいですか?
編集:
なぜこれを解決できないのですか?
_public partial class Reports1 : System.Web.UI.Page
{
RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(@"Software\xyz");
string pathName = (string)registryKey.GetValue("BinDir");
const string dllpath = pathName;
[DllImport(dllpath)]
public static extern bool GetErrorString(uint lookupCode, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder buf, uint bufSize);
protected void Page_Load(object sender, EventArgs e)
{
_
string pathName = (string)registryKey.GetValue("BinDir");
はここでは機能していませんが、pageloadイベントで機能しています...
しかし、これを行うとDLLインポートは機能しません...どうすれば修正できますか?
レジストリの読み取りは非常に簡単です。 Microsoft.Win32
名前空間には、Registry
静的クラスがあります。 HKLM
ノードからキーを読み取るためのコードは次のとおりです。
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\NodeName")
ノードがHKCU
の場合、LocalMachine
をCurrentUser
に置き換えることができます。
RegistryKey
オブジェクトを取得したら、GetValue
を使用してレジストリから値を取得します。上記の例を使用して、pathNameレジストリ値を取得すると次のようになります。
string pathName = (string) registryKey.GetValue("pathName");
そして、RegistryKey
オブジェクトを使い終わったら閉じることを忘れないでください(または、値を取得するステートメントをUsing
ブロックに入れてください)。
更新
いくつかのことがわかります。最初に、pathNameを次のように定義された静的プロパティに変更します。
Private static string PathName
{
get
{
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(@"Software\Copium"))
{
return (string)registryKey.GetValue("BinDir");
}
}
}
2つの問題は次のとおりです。
RegistryKey
参照はレジストリを開いたままにします。これをクラスの静的変数として使用すると、コンピューターで問題が発生します。これらの答えはどれも私にとってはうまくいきませんでした。これは私が使用したものです:
static void Main()
{
const string dotNetFourPath = "Software\\Microsoft";//note backslash
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(dotNetFourPath))
{
Console.WriteLine(registryKey.SubKeyCount);//registry is not null
foreach (var VARIABLE in registryKey.GetSubKeyNames())
{
Console.WriteLine(VARIABLE);//here I can see I have many keys
//no need to switch to x64 as suggested on other posts
}
}
}
これらのすべての答えは、64ビットOSでの実行に問題を引き起こす可能性があります-これは現在では一般的です。
私の状況では、「任意のCPU」ターゲットにコンパイルします。64ビットOSにインストールすると、ソフトウェアは正常に動作します。しかし、私のユニットテストでは問題が発生しています。明らかに32ビットモードで実行されます。
この場合、HKEY_LOCAL_MACHINE\SOFTWARE\MyCompany\MySoftware
ではなくHKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MyCompany\MySoftware
が検索されますが、エントリはありません!
この状況では、検索の開始点を指定する必要があります
RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)
合計で使用できます。
string configurationDirectory = string.Empty;
using (RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (RegistryKey registryKey = hklm.OpenSubKey(@"SOFTWARE\MyCompany\MySoftware"))
{
if (registryKey != null)
{
configurationDirectory = (string)registryKey.GetValue("ConfigurationDirectory");
}
}
}
try
{
RegistryKey regKey = Registry.LocalMachine;
regKey = regKey.OpenSubKey(@"Software\Application\");
if (regKey != null)
{
return regKey.GetValue("KEY NAME").ToString();
}
else
{
return null;
}
}
catch (Exception ex)
{
return null;
}
これを使用できます:
/// <summary>
/// To read a registry key.
/// input: KeyName (string)
/// output: value (string)
/// </summary>
public string Read(string KeyName)
{
// Opening the registry key
RegistryKey rk = baseRegistryKey ;
// Open a subKey as read-only
RegistryKey sk1 = rk.OpenSubKey(subKey);
// If the RegistrySubKey doesn't exist -> (null)
if ( sk1 == null )
{
return null;
}
else
{
try
{
// If the RegistryKey exists I get its value
// or null is returned.
return (string)sk1.GetValue(KeyName.ToUpper());
}
catch (Exception e)
{
// AAAAAAAAAAARGH, an error!
ShowErrorMessage(e, "Reading registry " + KeyName.ToUpper());
return null;
}
}
}
詳細については、 このWebサイト をご覧ください。