64 bit Windows altında .NET Framework 4.x kullanan kayıt defteri erişimi için hala yerel destek vardır . Aşağıdaki kod Windows 7, 64 bit ve ayrıca Windows 10, 64 bit ile test edilmiştir .
"Wow6432Node"
Bir kayıt ağacını diğeriyle eşleyerek sanal olarak orada görünmesini sağlayan bir düğümü taklit eden kullanmak yerine , aşağıdaki işlemi yapabilirsiniz:
64 bit veya 32 bit kayıt defterine erişmeniz gerekip gerekmediğine karar verin ve aşağıda açıklandığı gibi kullanın. Her iki düğümden de kayıt defteri anahtarlarını tek bir sorguda almak için bir birleşim sorgusu oluşturan daha sonra bahsettiğim kodu (Ek bilgiler bölümü) de kullanabilirsiniz - böylece gerçek yollarını kullanarak onları yine de sorgulayabilirsiniz.
64 bit kayıt defteri
64 bit kayıt defterine erişmek için RegistryView.Registry64
aşağıdakileri kullanabilirsiniz :
string value64 = string.Empty;
RegistryKey localKey =
RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine,
RegistryView.Registry64);
localKey = localKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
if (localKey != null)
{
value64 = localKey.GetValue("RegisteredOrganization").ToString();
localKey.Close();
}
Console.WriteLine(String.Format("RegisteredOrganization [value64]: {0}",value64));
32 bit kayıt
32bit kayıt defterine erişmek istiyorsanız , RegistryView.Registry32
aşağıdakileri kullanın :
string value32 = string.Empty;
RegistryKey localKey32 =
RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine,
RegistryView.Registry32);
localKey32 = localKey32.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion");
if (localKey32 != null)
{
value32 = localKey32.GetValue("RegisteredOrganization").ToString();
localKey32.Close();
}
Console.WriteLine(String.Format("RegisteredOrganization [value32]: {0}",value32));
Kafanız karışmasın, her iki sürüm de Microsoft.Win32.RegistryHive.LocalMachine
ilk parametre olarak kullanılıyor , 2. parametreye göre 64 bit mi yoksa 32 bit mi kullanılacağını ayırt edersiniz ( tersi ).RegistryView.Registry64
RegistryView.Registry32
Unutmayın ki
64 bit Windows'ta, HKEY_LOCAL_MACHINE\Software\Wow6432Node
64 bit sistemde çalışan 32 bit uygulamalar tarafından kullanılan değerleri içerir. Yalnızca gerçek 64 bit uygulamalar değerlerini HKEY_LOCAL_MACHINE\Software
doğrudan içinde depolar . Alt ağaç Wow6432Node
, 32 bit uygulamalar için tamamen şeffaftır, 32 bit uygulamalar hala HKEY_LOCAL_MACHINE\Software
bekledikleri gibi görür (bu bir tür yeniden yönlendirme). Windows'un eski sürümlerinde ve 32 bit Windows 7'de (ve Vista 32 bit) alt ağaç Wow6432Node
açıkça mevcut değildir .
Windows 7'deki (64 bit) bir hata nedeniyle, 32 bit kaynak kodu sürümü, hangi kuruluşu kaydetmiş olursanız olun her zaman "Microsoft" döndürürken, 64 bit kaynak kodu sürümü doğru kuruluşu döndürür.
Sağladığınız örneğe dönersek, 64 bitlik dala erişmek için aşağıdaki yolu izleyin:
RegistryKey localKey =
RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine,
RegistryView.Registry64);
RegistryKey sqlServerKey = localKey.OpenSubKey(
@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL");
string sqlExpressKeyName = (string) sqlServerKey.GetValue("SQLEXPRESS");
Ek bilgiler - pratik kullanım için:
Johny Skovdal'ın yorumlarda önerdiği ilginç bir yaklaşımı eklemek istiyorum , yaklaşımını kullanarak bazı yararlı işlevler geliştirmek için seçtiğim: Bazı durumlarda, 32 bit veya 64 bit. SQL örnek adları böyle bir örnektir. Bu durumda aşağıdaki gibi bir birleşim sorgusu kullanabilirsiniz (C # 6 veya üstü):
public static IEnumerable<string> GetRegValueNames(RegistryView view, string regPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
return RegistryKey.OpenBaseKey(hive, view)
?.OpenSubKey(regPath)?.GetValueNames();
}
public static IEnumerable<string> GetAllRegValueNames(string RegPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
var reg64 = GetRegValueNames(RegistryView.Registry64, RegPath, hive);
var reg32 = GetRegValueNames(RegistryView.Registry32, RegPath, hive);
var result = (reg64 != null && reg32 != null) ? reg64.Union(reg32) : (reg64 ?? reg32);
return (result ?? new List<string>().AsEnumerable()).OrderBy(x => x);
}
public static object GetRegValue(RegistryView view, string regPath, string ValueName="",
RegistryHive hive = RegistryHive.LocalMachine)
{
return RegistryKey.OpenBaseKey(hive, view)
?.OpenSubKey(regPath)?.GetValue(ValueName);
}
public static object GetRegValue(string RegPath, string ValueName="",
RegistryHive hive = RegistryHive.LocalMachine)
{
return GetRegValue(RegistryView.Registry64, RegPath, ValueName, hive)
?? GetRegValue(RegistryView.Registry32, RegPath, ValueName, hive);
}
public static IEnumerable<string> GetRegKeyNames(RegistryView view, string regPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
return RegistryKey.OpenBaseKey(hive, view)
?.OpenSubKey(regPath)?.GetSubKeyNames();
}
public static IEnumerable<string> GetAllRegKeyNames(string RegPath,
RegistryHive hive = RegistryHive.LocalMachine)
{
var reg64 = GetRegKeyNames(RegistryView.Registry64, RegPath, hive);
var reg32 = GetRegKeyNames(RegistryView.Registry32, RegPath, hive);
var result = (reg64 != null && reg32 != null) ? reg64.Union(reg32) : (reg64 ?? reg32);
return (result ?? new List<string>().AsEnumerable()).OrderBy(x => x);
}
Artık yukarıdaki işlevleri aşağıdaki gibi kullanabilirsiniz:
Örnek 1: SQL örnek adlarını alın
var sqlRegPath=@"SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL";
foreach (var valueName in GetAllRegValueNames(sqlRegPath))
{
var value=GetRegValue(sqlRegPath, valueName);
Console.WriteLine($"{valueName}={value}");
}
size sqlRegPath'deki değer adlarının ve değerlerinin bir listesini verecektir.
Not: Yukarıdaki ilgili işlevlerde parametreyi atlarsanız, bir tuşun varsayılan değerine (komut satırı aracı tarafından görüntülendiği REGEDT32.EXE
gibi (Default)
) erişebilirsiniz ValueName
.
Bir kayıt defteri anahtarındaki Alt Anahtarların listesini almak için , GetRegKeyNames
veya işlevini kullanın GetAllRegKeyNames
. Kayıt defterinde daha fazla anahtar arasında geçiş yapmak için bu listeyi kullanabilirsiniz.
Örnek 2: Yüklü yazılımın kaldırma bilgilerini alın
var currentVersionRegPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion";
var uninstallRegPath = $@"{currentVersionRegPath}\Uninstall";
var regKeys = Registry.GetAllRegKeyNames(RegPath: uninstallRegPath);
tüm 32 bit ve 64 bit kaldırma anahtarlarını alacaktır.
SQL sunucusu 32 bit veya 64 bit olarak kurulabildiğinden (yukarıdaki Örnek 1) işlevlerde gereken boş işlemeye dikkat edin . Fonksiyonlar aşırı yüklenmiştir, bu nedenle gerekirse 32 bit veya 64 bit parametresini geçebilirsiniz - ancak, atlarsanız 64 bit okumaya çalışır, bu başarısız olursa (boş değer), 32 bit değerleri okur.
Burada bir özellik var: GetAllRegValueNames
Genellikle bir döngü bağlamında kullanıldığından (yukarıdaki Örnek 1'e bakın), döngüleri null
basitleştirmek yerine boş bir numaralandırılabilir döndürür foreach
: bu şekilde ele alınmayacaksa, döngünün önekinin alınması gerekir bunu yapmak zahmetli olan bir if
ifadeyi kontrol etmek null
- böylece işlevde bir kez ele alınır.
Neden boş hakkında endişeleniyorsun? Çünkü umursamazsanız, kodunuzda bu boş referans istisnasının neden atıldığını bulmak için çok daha fazla baş ağrınız olur - bunun nerede ve neden olduğunu bulmak için çok zaman harcarsınız. Ve eğer üretimde olduysa, günlük dosyalarını veya olay günlüklerini incelemekle çok meşgul olacaksınız (umarım günlüğe kaydetme uygulamışsınızdır) ... savunmaya yönelik bir şekilde yapabileceğiniz boş sorunlardan daha iyi kaçının. Operatörler ?.
, ?[
... ]
ve ??
size çok yardımcı olabilir (yukarıda verilen koda bakın). Okumayı tavsiye ettiğim C # ' da yeni null atanabilir referans türlerini tartışan ve ayrıca bu Elvis operatörü hakkında güzel bir makale var .
İpucu: Windows altında tüm örnekleri test etmek için Linqpad'in ücretsiz sürümünü kullanabilirsiniz . Kurulum gerektirmez. Ad alanı içe aktarma sekmesine basıp F4girmeyi unutmayın Microsoft.Win32
. Visual Studio'da, using Microsoft.Win32;
kodunuzun en üstünde olması gerekir.
İpucu: Yeni tanımak için boş taşıma operatörleri , LINQPad aşağıdaki kodu denemek (ve hata ayıklama):
Örnek 3: Boş işleme operatörlerini gösterme
static string[] test { get { return null;} }
static void Main()
{
test.Dump();
test?.Dump();
test?[0].Dump();
(test?[0]).Dump();
(test?[0]??"<null>").Dump();
}
.Net fiddle ile deneyin
İlgileniyorsanız, işte araçla başka neler yapabileceğinizi gösteren bir araya getirdiğim bazı örnekler.