问题
I am attempting to populate a tree structure with everything from the registry in string form so that I may use it to make comparisons to changes later on. So far I've come to an impasse with actually providing dynamic additions of children to the tree structure as I can never be certain as to how many children a subkey in the registry is going to have! Or how many values it will have, so I have to be able to dynamically populate the tree structure without knowing how many children there will ever be.
So far I have this:
private void buildRegistryListTreeFromScratch(string[] rootSubs) {
//The rootSubs argument is the first layer of subkeys directly underneath the root keys
RegistryKey rootKey = Registry.CurrentUser;
registryTreeTracker.Name = "Current User";
for (int i = 0; i < rootSubs.Length; i++) {
registryTreeTracker.Children.Add(new RegistryTreeNode(rootSubs[i]));
}
for (int i = 0; i < rootSubs.Length; i++) {
RegistryKey selectedKey = rootKey.OpenSubKey(rootSubs[i]);
if (selectedKey.SubKeyCount > 0) {
subKeyBelow(rootSubs[i]);
}
}
}
private void subKeyBelow(string path) {
RegistryKey rootKey = Registry.CurrentUser;
RegistryKey selectedKey = rootKey.OpenSubKey(path);
for (int i = 0; i < registryTreeTracker.Children.Count; i++){
if (registryTreeTracker.Children[i].Name == path) {
registryTreeTracker.Children[i] ... //This is the impasse I have reached
}
}
}
the class I am using for the object registryTreeTracker is a class provided to me by Daniel Hilgarth in a question related to this, and its definition is as follows:
public class RegistryTreeNode {
private readonly List<RegistryTreeNode> _children = new List<RegistryTreeNode>();
public RegistryTreeNode(string name, params RegistryTreeNode[] children) {
Name = name;
_children.AddRange(children);
}
public List<RegistryTreeNode> Children {
get {
return _children;
}
}
public string Name {
get;
set;
}
}
回答1:
You would use a recursive method to build your tree. This method would receive the root key of the current level of the tree as well as the registry key that should be added to that root key.
It would look something like this:
public TreeNode AddChildNode(TreeNode parent, string name)
{
var child = new TreeNode(name);
parent.Children.Add(child);
return child;
}
public void AddSubTree(TreeNode treeRoot, RegistryKey registryKeyToAdd)
{
var child = AddChildNode(treeRoot, registryKeyToAdd.Name);
foreach(var subKeyName in registryKeyToAdd.GetSubKeyNames())
{
try
{
AddSubTree(child, registryKeyToAdd.OpenSubKey(subKeyName));
}
catch(SecurityException e)
{
AddChildNode(child, string.Format("{0} - Access denied", subKeyName));
}
}
}
public TreeNode BuildRegistryTree()
{
var root = new TreeNode("Computer");
AddSubTree(root, Registry.CurrentUser);
AddSubTree(root, Registry.LocalMachine);
return root;
}
You would call BuildRegistryTree to get the complete tree.
回答2:
For the sake of a more conclusive question here is the culmination of my work thanks to Daniel Hilgarth:
//the rootSubs argument is a string array containing all the subkeys of the root keys
private void buildRegistryListTreeFromScratch(string[] rootSubs) {
RegistryKey rootKey = Registry.CurrentUser;
registryTreeTracker.Name = "Current User";
for (int i = 0; i < rootSubs.Length; i++) {
registryTreeTracker.Children.Add(new RegistryTreeNode(rootSubs[i]));
}
for (int i = 0; i < rootSubs.Length; i++) {
RegistryKey selectedKey = rootKey.OpenSubKey(rootSubs[i]);
if (selectedKey.SubKeyCount > 0) {
subKeyBelow(rootSubs[i]);
}
}
}
private void subKeyBelow(string path) {
RegistryKey rootKey = Registry.CurrentUser;
RegistryKey selectedKey = rootKey.OpenSubKey(path);
for (int i = 0; i < registryTreeTracker.Children.Count; i++){
if (registryTreeTracker.Children[i].Name == path) {
recursiveSubKeyBelow(registryTreeTracker.Children[i], path);
}
}
}
private void recursiveSubKeyBelow(RegistryTreeNode currentNode, string path) {
RegistryKey rootKey = Registry.CurrentUser;
RegistryKey selectedKey = rootKey.OpenSubKey(path);
string originalPath = path;
RegistryKey originalKey = rootKey.OpenSubKey(originalPath);
for (int i = 0; i < selectedKey.SubKeyCount; i++){
currentNode.Children.Add(new RegistryTreeNode(selectedKey.GetSubKeyNames()[i]));
}
for (int i = 0; i < originalKey.SubKeyCount; i++) {
string deeperPath = originalPath + "\\" + originalKey.GetSubKeyNames()[i];
try {
selectedKey = rootKey.OpenSubKey(deeperPath);
if (selectedKey.SubKeyCount > 0) {
recursiveSubKeyBelow(currentNode.Children[i], deeperPath);
}
} catch(SecurityException) {
i++;
}
}
}
Thanks loads Dan! With your suggestions/help this problem became a lot more manageable!
来源:https://stackoverflow.com/questions/17576269/dynamicly-adjusting-tree-populated-with-registry-values