RegistryValues auslesen Count-Unterschiede zwischen C-Sharp und PS
Hi @ All
Ich habe eine Frage zu Powershell bzw. warum ich in Powershell andere Werte bekomme als in C#
Im Detail:
Ich habe eine Methode in C# mithilfe derer ich alle Registry-SubKeys von diesen Pfaden auslese:
Dabei berücksichtige ich RegistryHive und RegistryView. Lasse ich die Methode in C# durchlaufen, habe ich am Ende 518 Einträge in meiner Liste. Mit der gleichen Methode in Powershell aber nur 368.
Mir ist aufgefallen, dass einige SubKeys nicht ausgewertet werden in PS und ich frage mich nun warum?
Methode in C#:
Methode in Powershell:
Lese ich die SubKeys Powershell-Like aus bekomme ich 346 Einträge in meiner Liste (HÄÄÄ ???).
Hat jemand Ahnung warum das so ist und wie ich das bereinigen kann?
Vielen Dank für eure Unterstützung und beste Grüße!
Mayho
Ich habe eine Frage zu Powershell bzw. warum ich in Powershell andere Werte bekomme als in C#
Im Detail:
Ich habe eine Methode in C# mithilfe derer ich alle Registry-SubKeys von diesen Pfaden auslese:
- Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
- Software\Microsoft\Windows\CurrentVersion\Uninstall
Dabei berücksichtige ich RegistryHive und RegistryView. Lasse ich die Methode in C# durchlaufen, habe ich am Ende 518 Einträge in meiner Liste. Mit der gleichen Methode in Powershell aber nur 368.
Mir ist aufgefallen, dass einige SubKeys nicht ausgewertet werden in PS und ich frage mich nun warum?
Methode in C#:
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace RegRead
{
partial class Program
{
public static List<RegistryKey_Model> GetRegistryKeyPathes()
{
RegistryKey currentRegKey = null;
List<RegistryKey_Model> toReturn = new List<RegistryKey_Model>();
List<RegistryView> regViews = new List<RegistryView> { { RegistryView.Registry64 }, { RegistryView.Registry32 } };
List<RegistryHive> regHives = new List<RegistryHive> { { RegistryHive.CurrentUser }, { RegistryHive.LocalMachine } };
Dictionary<string,string> regTargetPathes = new Dictionary<string, string>
{
{ "Registry64", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" },
{ "Registry32", "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" }
};
foreach (RegistryHive hive in regHives)
{
foreach (RegistryView view in regViews)
{
try
{
if (hive == RegistryHive.LocalMachine && (view == RegistryView.Registry32 || view == RegistryView.Default))
currentRegKey = Registry.LocalMachine.OpenSubKey(regTargetPathes[RegistryView.Registry32.ToString()]);
else if (hive == RegistryHive.LocalMachine && view == RegistryView.Registry64)
currentRegKey = Registry.LocalMachine.OpenSubKey(regTargetPathes[RegistryView.Registry64.ToString()]);
else if (hive == RegistryHive.CurrentUser && (view == RegistryView.Registry32 || view == RegistryView.Default))
currentRegKey = Registry.CurrentUser.OpenSubKey(regTargetPathes[RegistryView.Registry32.ToString()]);
else if (hive == RegistryHive.CurrentUser && view == RegistryView.Registry64)
currentRegKey = Registry.CurrentUser.OpenSubKey(regTargetPathes[RegistryView.Registry64.ToString()]);
}
catch (Exception) { }
if (currentRegKey != null)
{
foreach (var subKey in currentRegKey.GetSubKeyNames())
{
toReturn.Add(new RegistryKey_Model
{
RegHive = GetRegistryHive(currentRegKey.Name),
RegView = GetRegistryView(currentRegKey.Name),
RegKey = Path.Combine(currentRegKey.Name.ToString(), subKey.ToString())
});
}
}
}
}
return toReturn;
}
private static RegistryView GetRegistryView(string fullKeyOrValuePath)
{
RegistryView regView = RegistryView.Registry32;
if (!Regex.Match(fullKeyOrValuePath, @"(Wow6432Node)", RegexOptions.IgnoreCase).Success && Environment.Is64BitOperatingSystem)
regView = RegistryView.Registry64;
return regView;
}
private static RegistryHive GetRegistryHive(string fullKeyOrValuePath)
{
RegistryHive regHive = RegistryHive.LocalMachine;
if (Regex.Match(fullKeyOrValuePath, @"(HKCU|HKEY_CURRENT_USER)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.CurrentUser;
if (Regex.Match(fullKeyOrValuePath, @"(HKCR|HKEY_CLASSES_ROOT)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.ClassesRoot;
if (Regex.Match(fullKeyOrValuePath, @"(HKU|HKEY_USERS)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.Users;
if (Regex.Match(fullKeyOrValuePath, @"(HKCC|HKEY_CURRENT_CONFIG)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.CurrentConfig;
if (Regex.Match(fullKeyOrValuePath, @"(HKLM|HKEY_LOCAL_MACHINE)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.LocalMachine;
return regHive;
}
}
public class RegistryKey_Model
{
private RegistryHive _RegHive;
public RegistryHive RegHive
{
get { return _RegHive; }
set { _RegHive = value; }
}
private RegistryView _RegView;
public RegistryView RegView
{
get { return _RegView; }
set { _RegView = value; }
}
private string _RegKey;
public string RegKey
{
get { return _RegKey; }
set { _RegKey = value; }
}
}
}
Methode in Powershell:
$Source= @"
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
public class RegistryKeyPathes
{
public static List<RegistryKey_Model> Get()
{
RegistryKey currentRegKey = null;
List<RegistryKey_Model> toReturn = new List<RegistryKey_Model>();
List<RegistryView> regViews = new List<RegistryView> { { RegistryView.Registry64 }, { RegistryView.Registry32 } };
List<RegistryHive> regHives = new List<RegistryHive> { { RegistryHive.CurrentUser }, { RegistryHive.LocalMachine } };
Dictionary<string,string> regTargetPathes = new Dictionary<string, string>
{
{ "Registry64", "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" },
{ "Registry32", "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" }
};
foreach (RegistryHive hive in regHives)
{
foreach (RegistryView view in regViews)
{
try
{
if (hive == RegistryHive.LocalMachine && (view == RegistryView.Registry32 || view == RegistryView.Default))
currentRegKey = Registry.LocalMachine.OpenSubKey(regTargetPathes[RegistryView.Registry32.ToString()]);
else if (hive == RegistryHive.LocalMachine && view == RegistryView.Registry64)
currentRegKey = Registry.LocalMachine.OpenSubKey(regTargetPathes[RegistryView.Registry64.ToString()]);
else if (hive == RegistryHive.CurrentUser && (view == RegistryView.Registry32 || view == RegistryView.Default))
currentRegKey = Registry.CurrentUser.OpenSubKey(regTargetPathes[RegistryView.Registry32.ToString()]);
else if (hive == RegistryHive.CurrentUser && view == RegistryView.Registry64)
currentRegKey = Registry.CurrentUser.OpenSubKey(regTargetPathes[RegistryView.Registry64.ToString()]);
}
catch (Exception) { }
if (currentRegKey != null)
{
foreach (var subKey in currentRegKey.GetSubKeyNames())
{
toReturn.Add(new RegistryKey_Model
{
RegHive = GetRegistryHive(currentRegKey.Name),
RegView = GetRegistryView(currentRegKey.Name),
RegKey = Path.Combine(currentRegKey.Name.ToString(), subKey.ToString())
});
}
}
}
}
return toReturn;
}
private static RegistryView GetRegistryView(string fullKeyOrValuePath)
{
RegistryView regView = RegistryView.Registry32;
if (!Regex.Match(fullKeyOrValuePath, @"(Wow6432Node)", RegexOptions.IgnoreCase).Success && Environment.Is64BitOperatingSystem)
regView = RegistryView.Registry64;
return regView;
}
private static RegistryHive GetRegistryHive(string fullKeyOrValuePath)
{
RegistryHive regHive = RegistryHive.LocalMachine;
if (Regex.Match(fullKeyOrValuePath, @"(HKCU|HKEY_CURRENT_USER)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.CurrentUser;
if (Regex.Match(fullKeyOrValuePath, @"(HKCR|HKEY_CLASSES_ROOT)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.ClassesRoot;
if (Regex.Match(fullKeyOrValuePath, @"(HKU|HKEY_USERS)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.Users;
if (Regex.Match(fullKeyOrValuePath, @"(HKCC|HKEY_CURRENT_CONFIG)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.CurrentConfig;
if (Regex.Match(fullKeyOrValuePath, @"(HKLM|HKEY_LOCAL_MACHINE)", RegexOptions.IgnoreCase).Success)
regHive = RegistryHive.LocalMachine;
return regHive;
}
}
public class RegistryKey_Model
{
private RegistryHive _RegHive;
public RegistryHive RegHive
{
get { return _RegHive; }
set { _RegHive = value; }
}
private RegistryView _RegView;
public RegistryView RegView
{
get { return _RegView; }
set { _RegView = value; }
}
private string _RegKey;
public string RegKey
{
get { return _RegKey; }
set { _RegKey = value; }
}
}
"@
Add-Type -TypeDefinition $Source
$values = [RegistryKeyPathes]::Get()
Lese ich die SubKeys Powershell-Like aus bekomme ich 346 Einträge in meiner Liste (HÄÄÄ ???).
$values = @()
try{
$values += Get-ItemProperty HKLM:Software\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue
$values += Get-ItemProperty HKLM:Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue
$values += Get-ItemProperty HKCU:Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue
$values += Get-ItemProperty HKCU:Software\Microsoft\Windows\CurrentVersion\Uninstall\* -ErrorAction SilentlyContinue
}
catch {}
$values.Count
Hat jemand Ahnung warum das so ist und wie ich das bereinigen kann?
Vielen Dank für eure Unterstützung und beste Grüße!
Mayho
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 463894
Url: https://administrator.de/forum/registryvalues-auslesen-count-unterschiede-zwischen-c-sharp-und-ps-463894.html
Ausgedruckt am: 05.02.2025 um 04:02 Uhr
6 Kommentare
Neuester Kommentar
Get-ChildItem liefert aber ganz andere Dinge als Get-Itemproperty, das ist dir hoffentlich schon bewusst?! Das eine Schlüssel, das andere Properties.
Als erstes würde ich mal die Catch-Blocks ausgeben lassen und nicht ins Nirvana laufen lassen, genauso bei der PS Variante.
Welches OS welche PS Version und Bitness der PS-Session als auch die Bitness der c# exe?
Als erstes würde ich mal die Catch-Blocks ausgeben lassen und nicht ins Nirvana laufen lassen, genauso bei der PS Variante.
Welches OS welche PS Version und Bitness der PS-Session als auch die Bitness der c# exe?
C# Bitness: x86
Ideen??
Ja ist mir jetzt eigentlich vollkommen klar, bau deine c# exe mal als 64bit, und du wirst sehen das es geht (getestet, Ergebnisse absolut gleich, egal welches System ich heranziehe, waren mind. 4 unterschiedliche). Mit Workarounds kann man das auch mit Flags über RegOpenKeyEx in einem x86 Prozess machen.Ideen??
Generell gilt aber folgendes:
.NET app kompiliert für "x86":
Auf 32-bit Platformen, nutzt es die 32-bit Registry
Auf 64-bit Platformen, nutzt die 32-bit registry (in Wow6432Node)
Zugriff auf die 64-bit Registry ist nicht möglich (ohne Workarounds)
.NET app kompiliert für "x64":
Läuft auf 32-bit platformen nicht
Auf 64-bit Platformen, nutzt die 64-bit Registry (nicht in Wow6432Node)
Zugriff auf die 32-Bit Registry über Workaround möglich
.NET app kompiliert für "AnyCpu"
Entweder 32 or 64 bit je nach Platform
Auf 32-bit Platformen, nutzt die 32-bit registry
Auf 64-bit Platformen, nutzt die 64-bit registry (nicht in Wow6432Node)
Zugriff auf die 32-Bit Registry nur über Workaround möglich
MS empfiehlt es aber ausdrücklich nicht so vorzugehen.
Grüße Uwe