mayho33
Goto Top

Powershell Methode Compare-Object als C-Sharp Methode

Hallo @ All

Ich beiße wieder mal an einem Problemchen und hoffe auf eure Unterstützung

Ich möchte folgendes Powershell-Scriptchen in C# umsetzen. Es sollen Änderungen in der Registry nachverfolgt werden. in diesem Beispiel also...

1)...ein Snap der Registry vor einer Installation / Deinstallation
2) es folgt die De/Installation
3) Snap der Registry danach
4) Ausgeben des Diff beider Snaps (die geänderten Values)

$before = Get-ItemProperty HKLM:"\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"  
$after = Get-ItemProperty HKLM:"\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"  
Compare-Object $before $after

Resultat (bsp):
InputObject SideIndicator

@{DisplayName=testValue; DisplayVersion=1.2.3.4; PSPath=Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\... =>

Man kann in C# zwar via System.Management.Automation die Powershell ansprechen, mir kommt das aber etwas komisch vor PS via C# coden.
Gibt es denn in C# keine ähnliche Möglichkeit? Google spuckt dazu nix passendes aus. Kann natürlich auch sein, dass ich falsch suche.
Ein sehr vager Tipp war dies über Generische Methoden zu lösen, bloß fehlt mir dazu komplett der Ansatz.

Hat irgend jemand einen Tipp oder besser ein kleines Beispiel wie ich das lösen könnte?

Danke für eure Hilfe!

Grüße, Mayho

Content-Key: 303533

Url: https://administrator.de/contentid/303533

Printed on: April 26, 2024 at 08:04 o'clock

Member: colinardo
colinardo May 03, 2016 updated at 16:32:40 (UTC)
Goto Top
Hallo mayho,
schau mal hier vorbei:
https://github.com/GregFinzer/Compare-Net-Objects
bzw.
https://www.nuget.org/packages/CompareNETObjects
Das geht damit dann bspw. in dieser Art:
public void testcompare(){
    myclass o1 = new myclass("Test");  
    myclass o2 = new myclass("Test2");  
    KellermanSoftware.CompareNetObjects.CompareLogic logic = new KellermanSoftware.CompareNetObjects.CompareLogic();
    logic.Config.MaxDifferences = 100;
    MessageBox.Show(logic.Compare(o1, o2).DifferencesString);
}

public class myclass
    {
        public myclass(string prop) {
            Myproperty = prop;
        }
        public string Myproperty { get; set; }
    }
Grüße Uwe
Member: mayho33
mayho33 May 04, 2016 updated at 23:07:01 (UTC)
Goto Top
Hallo Uwe,

Danke für den Tipp. Habe ich auch gefunden. Leider liefert der Compare nur Kauderwelsch. z.B. das:

Begin Differences (1 differences):
Types [List`1.Count,List`1.Count], Item Expected != Actual, Values (133,134)
End Differences (Maximum of 1 differences shown).

Ich erwarte aber sowas wie im obigen Beispiel.
Meine Objects (befor und after) schauen so aus:
public static class MonitoredKeys
    {
        public static object StartValues { get; set; }
        public static object EndValues { get; set; }
    }

HIer mein Code. Ich rattere den gesamten Hive von z.B.: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall durch und speichere dies mal zwischen:

public class CurrentKey
    {
        public string KeyName { get; set; }
        public object Values { get; set; }
    }

public List<CurrentKey> GetSubkeysValue(string regPath, RegistryHive regHive, RegistryView regView)
        {
            List<CurrentKey> cList = new List<CurrentKey>();
            using (var hiveKey = RegistryKey.OpenBaseKey(regHive, regView))
            using (var key = hiveKey.OpenSubKey(regPath))
            {
                var subkeys = key.GetSubKeyNames();

                foreach (var subkey in subkeys)
                {
                    var before = GetKeyValue(hiveKey, Path.Combine(regPath, subkey));
                    cList.Add(new CurrentKey
                    {
                        KeyName = Path.Combine(regPath, subkey),
                        Values = before
                    });
                }
            }
            return cList;
        }
        internal List<KeyValuePair<string, object>> GetKeyValue(RegistryKey hive, string keyName)
        {
            object value;
            List<KeyValuePair<string, object>> curList = new List<KeyValuePair<string, object>>();
            using (var key = hive.OpenSubKey(keyName))
            {
                foreach (var valueName in key.GetValueNames())
                {
                    try
                    {
                        value = key.GetValue(valueName);
                        curList.Add(new KeyValuePair<string, object>(valueName, value));
                    }
                    catch (Exception) {}
                }
            }
            return curList;
        }


Nun habe ich eine recht komplexe Struktur deren KeyName-KeyValuePair-Verhältnis nicht immer gleich ausschaut. Nicht jeder Key hat die gleichen ValuesNames. Bei manchen sind es nur ganz wenige, bei manchen etwas mehr.

Ich gehe das 2x durch, vor einer De/Installation und danach. Die Differenz sollte sein, dass einer oder mehrere Keys oder auch nur Values dazugekommen sind, sich verändert haben oder gelöscht wurden. Und diese Differenz brauche ich mit all seinen Values (Auch wenn sie gelöscht wurden).
Powershell hat diese Funktionalität via Compare-Object. in C# schauts da wohl mau aus und ich bin mit meiner Weisheit am Ende (und die reicht leider auch nicht recht weit face-wink ).

Eventuell einen anderen Tipp parat?

Danke, Christian

ps: Jemand beschreibt wie es funktionieren könnte hier: http://stackoverflow.com/questions/2387946/finding-property-differences ...

Ist aber offensichtlich auch nur ein Stringvergleich laut dem: https://github.com/PaulSodimu/ObjectComparer/blob/master/ObjectComparer/ ...


var comparer = new ObjectComparer(new PublicPropertyObjectGraphFactory());
IEnumerable<ObjectComparisonMismatch> mismatches;
bool result = comparer.Compare(left, right, out mismatches);

foreach (var mismatch in mismatches)
{
    Console.Out.WriteLine("\t'{0}' = '{1}' and '{2}'='{3}' do not match. '{4}'",  
        mismatch.LeftObjectNode.Name, mismatch.LeftObjectNode.ObjectValue,
        mismatch.RightObjectNode.Name, mismatch.RightObjectNode.ObjectValue,
        mismatch.MismatchType);
}
Member: colinardo
colinardo May 05, 2016 updated at 05:04:01 (UTC)
Goto Top
Das war ja nur ein total simples Beispiel mit der Eigenschaft DifferencesString. Es gibt da ja auch die Differences Eigenschaft die eine Liste der Unterschiede enthält, dazu die Werte und die Objektnamen separat als Eigenschaften abfragbar, damit kannst du dir so eine Ausgabe "zusammenlöten" wie du es brauchst.
Member: mayho33
mayho33 May 05, 2016 at 21:54:22 (UTC)
Goto Top
Hi Uwe,

ja klar!, Sorry, wenn das so rüber gekommen ist als könnte ich das nicht schätzen. Ganz im Gegenteil. Habe natürlich auch ein paar andere Sachen ausprobiert, Aber da ist nichts dabei was ich brauchen könnte.

Habe es jetzt ganz klassisch gelöst: Zeilenweise jedes Value á Key in eine String-Variable, jeweils vor und nach einer Änderung in der Registry und dann in etwa so wie hier beschrieben:
https://msdn.microsoft.com/en-us/library/bb397894.aspx

Danke jedenfalls für deinen Tipp. Immer gerne gesehen face-smile

Grüße, Christian