Check out my new blog at https://shibumiware.blogspot.com

Tuesday, May 23, 2017

Random Code Snippets from Work and Play Volume I

Introduction

I have my career and I have my hobby, which blissfully happen to be the same.   I do different software design for work than for play
(typically).  I like to share, so while you won't see the heavy, important IP from work anywhere in this blog,  I will share code where
I see fit, so here is Snippets from Work and Play Volume I, which includes code from work and play intermixed to because it comes to
me when it comes to me.

 Enjoy!





Tired of all Those Try/Catch Blocks in your Code?

Particularly in a WinForm's app interacting with primarily the base class libraries and maybe one or two other 3rd party APIs, you end up wrapping your
code
in a try/catch block that accounts for the most likely types of exceptions thrown, backstopped by catching the general case. I have used snippet manager
and snippets for this for a long while until it struck me that an extension method is perfect
for this:


public static bool TryCatchMethod(this Action action, IWin32Window parentWindow)
{
    try
    {
        action();
        return true;
 
    }
    catch (ShibumiWareException exception)
    {
        MessageBoxFx.Warning(parentWindow, exception.CreateMessage(false), MessageBoxButtons.OK);
    }
    catch (SoapException exception)
    {
        MessageBoxFx.Warning(parentWindow, exception.CreateMessage(false), MessageBoxButtons.OK);
    }
    catch (WebException exception)
    {
        MessageBoxFx.Warning(parentWindow, string.Format(Resources.ERROR_SERVER_RETURNED_0_1, exception.Response, exception.CreateMessage(false)), MessageBoxButtons.OK);
    }
    catch (Exception exception)
    {
        MessageBoxFx.Warning(parentWindow, exception.CreateMessage(false), MessageBoxButtons.OK);
    }
 
    return false;
}
You may have methods that take parameters, etc, and you can do what you need to do to extend or overload this to make that work, but in the
app I am working has both a menu and tool bar item for every action, so I wrap the core of the action into a Perform method: PerformLoad, PerformLogin,
and so far forth.  So this works great, plus it then becomes an expression body with a Try/Catch blog :-)


private void MainForm_Load(object sender, EventArgs e) => ((Action)PerformLoad).TryCatchMethod(this)

Here is a Simple One - String to Stream

So you want a string turned into a stream?  We do it all the time. Here you go:

public static Stream ToStream(this string stringData)
{
    MemoryStream memoryStream = new MemoryStream();
    StreamWriter writer = new StreamWriter(memoryStream);
 
    writer.Write(stringData);
    writer.Flush();
    memoryStream.Position = 0;
 
    return memoryStream;
}
Use it like this:

using (Stream stream = _Template.ToStream())
{
    _ActiveDocument.Load(stream, Encoding.UTF8);
}
The astute may ask "what about disposing of the underlying stream?"   Looking at the implement in dotPeak, you can see .Close() is called on the inner stream, which in turn calls .Dispose() so don't fret:



Stream Dispose

Using NextPageToken with Blogger API .NET

public List<PostLoadPosts(string id)
{
    if (string.IsNullOrEmpty(id)) throw new ArgumentException(Resources.ERROR_VALUE_NULL_OR_EMPTYnameof(id));
 
    List<Post> posts = new List<Post>();
 
    PostsResource.ListRequest listRequest = _PostService.List(id);
 
    listRequest.MaxResults = 10;
            
    PostList pageList = listRequest.Execute();
 
    do
    {
        posts.AddRange(pageList.Items);
 
        listRequest.PageToken = pageList.NextPageToken;
        pageList = listRequest.Execute();
 
    } while (!string.IsNullOrEmpty(pageList.NextPageToken));
 
 
    return posts;
}



Registry Extensions (Long--I will Explain)

public static class RegistryExtensions
{
    public static List<NodeBuildTree(this string path, RegistryHive hive, bool unpackMultiStrings = falsebool unpackByteArrays = false)
    {
        if (string.IsNullOrEmpty(path))
        {
            throw new ArgumentException(@"Value cannot be null or empty."nameof(path));
        }
 
        if (!Enum.IsDefined(typeof(RegistryHive), hive))
        {
            throw new InvalidEnumArgumentException(nameof(hive), (int)hive, typeof(RegistryHive));
        }
 
        RegistryKey registryKey = GetKeyFromHive(hive);
 
        List<Nodetree;
 
        if (path.Equals(registryKey.ToString(), StringComparison.OrdinalIgnoreCase))
        {
            tree = new List<Node>();
 
            BuildTree(registryKey, null, unpackMultiStrings, unpackByteArrays, ref tree);
            return tree;
        }
 
        using (RegistryKey subKey = registryKey.OpenSubKey(path, RegistryKeyPermissionCheck.ReadSubTree))
        {
            if (subKey == null)
            {
                throw new ArgumentException(string.Format(Resources.ERROR_0_IS_INVALID_PATH, path), nameof(path));
            }
 
            tree = new List<Node>();
 
            BuildTree(subKey, null, unpackMultiStrings, unpackByteArrays, ref tree);
        }
 
        return tree;
    }
 
    public static RegistryHive RegistryGetHive(this string path, out string parsedComponent)
    {
        if (string.IsNullOrEmpty(path)) throw new ArgumentException(@"Value cannot be null or empty."nameof(path));
 
        parsedComponent = string.Empty;
 
        int i = path.IndexOf(Path.DirectorySeparatorChar, 0);
 
        string hive;
 
        if (i == -1)
        {
            hive = path;
        }
        else
        {
            hive = path.Substring(0, i);
            parsedComponent = path.Substring(0, i + 1);
        }
 
        if (hive.Equals(@"HKEY_CLASSES_ROOT"StringComparison.OrdinalIgnoreCase))
        {
            return RegistryHive.ClassesRoot;
        }
 
        if (hive.Equals(@"HKEY_CURRENT_USER"StringComparison.OrdinalIgnoreCase))
        {
            return RegistryHive.CurrentUser;
        }
 
        if (hive.Equals(@"HKEY_LOCAL_MACHINE"StringComparison.OrdinalIgnoreCase))
        {
            return RegistryHive.LocalMachine;
        }
 
        if (hive.Equals(@"HKEY_USERS"StringComparison.OrdinalIgnoreCase))
        {
            return RegistryHive.Users;
        }
 
        if (hive.Equals(@"HKEY_CURRENT_CONFIG"StringComparison.OrdinalIgnoreCase))
        {
            return RegistryHive.CurrentConfig;
        }
 
        if (hive.Equals(@"HKEY_USERS"StringComparison.OrdinalIgnoreCase))
        {
            return RegistryHive.Users;
        }
 
        throw new ArgumentOutOfRangeException(string.Format(Resources.ERROR_INVALID_HIVE_0, hive));
    }
 
    public static List<stringRegistryGetKeySubkeys(this string path, RegistryHive hive)
    {
        if (string.IsNullOrEmpty(path)) throw new ArgumentException(@"Value cannot be null or empty."nameof(path));
        if (!Enum.IsDefined(typeof(RegistryHive), hive)) throw new InvalidEnumArgumentException(nameof(hive), (int)hive, typeof(RegistryHive));
 
        RegistryKey registryKey = GetKeyFromHive(hive);
 
        using (RegistryKey subKey = registryKey.OpenSubKey(path, RegistryKeyPermissionCheck.ReadSubTree))
        {
            if (subKey == null)
            {
                throw new ArgumentException(string.Format(Resources.ERROR_0_IS_INVALID_PATH, path), nameof(path));
            }
 
            return subKey.GetSubKeyNames().ToList();
        }
    }
 
    public static Dictionary<stringRegistryValueKindRegistryGetKeyValueInfo(this string path, RegistryHive hive)
    {
        if (string.IsNullOrEmpty(path)) throw new ArgumentException(@"Value cannot be null or empty."nameof(path));
        if (!Enum.IsDefined(typeof(RegistryHive), hive)) throw new InvalidEnumArgumentException(nameof(hive), (int)hive, typeof(RegistryHive));
 
        RegistryKey registryKey = GetKeyFromHive(hive);
 
        using (RegistryKey subKey = registryKey.OpenSubKey(path, RegistryKeyPermissionCheck.ReadSubTree))
        {
            if (subKey == null)
            {
                throw new ArgumentException(string.Format(Resources.ERROR_0_IS_INVALID_PATH, path), nameof(path));
            }
 
            List<string> valueNames = subKey.GetValueNames().ToList();
 
            return valueNames.ToDictionary(valueName => valueName, valueName => subKey.GetValueKind(valueName));
        }
    }
 
    public static List<stringRegistryGetKeyValues(this string path, RegistryHive hive)
    {
        if (string.IsNullOrEmpty(path)) throw new ArgumentException(@"Value cannot be null or empty."nameof(path));
        if (!Enum.IsDefined(typeof(RegistryHive), hive)) throw new InvalidEnumArgumentException(nameof(hive), (int)hive, typeof(RegistryHive));
 
        RegistryKey registryKey = GetKeyFromHive(hive);
 
        using (RegistryKey subKey = registryKey.OpenSubKey(path, RegistryKeyPermissionCheck.ReadSubTree))
        {
            if (subKey == null)
            {
                throw new ArgumentException(string.Format(Resources.ERROR_0_IS_INVALID_PATH, path), nameof(path));
            }
 
            return subKey.GetValueNames().ToList();
        }
    }
 
    public static T RegistryGetValue<T>(this string path, RegistryHive hive, string value, T defaultValue)
    {
        if (!Enum.IsDefined(typeof(RegistryHive), hive)) throw new InvalidEnumArgumentException(nameof(hive), (int)hive, typeof(RegistryHive));
        if (string.IsNullOrEmpty(path)) throw new ArgumentException(@"Value cannot be null or empty."nameof(path));
        if (string.IsNullOrEmpty(value)) throw new ArgumentException(@"Value cannot be null or empty."nameof(value));
 
        RegistryKey registryKey = GetKeyFromHive(hive);
 
        using (RegistryKey subKey = registryKey.OpenSubKey(path, RegistryKeyPermissionCheck.ReadSubTree))
        {
            if (subKey == null)
            {
                return defaultValue;
            }
 
            object valueObject = subKey.GetValue(value);
 
            if (valueObject == null)
            {
                return defaultValue;
            }
 
            return (T)Convert.ChangeType(valueObject, typeof(T));
        }
    }
 
    public static bool RegistryKeyExists(this string path, bool parseHive = trueRegistryHive registryHive = RegistryHive.LocalMachine)
    {
        if (string.IsNullOrEmpty(path)) throw new ArgumentException(@"Value cannot be null or empty."nameof(path));
 
        if (parseHive)
        {
            string parsedComponent;
 
            registryHive = path.RegistryGetHive(out parsedComponent);
 
            if (!string.IsNullOrEmpty(parsedComponent))
            {
                path = path.Replace(parsedComponent, string.Empty);
            }
        }
        else
        {
            if (!Enum.IsDefined(typeof(RegistryHive), registryHive))
            {
                throw new InvalidEnumArgumentException(nameof(registryHive), (int)registryHive, typeof(RegistryHive));
            }
        }
 
        RegistryKey key = GetKeyFromHive(registryHive);
 
        if (key == null)
        {
            return false;
        }
 
        if (path.Equals(key.NameStringComparison.OrdinalIgnoreCase))
        {
            return true;
        }
 
        using (RegistryKey subKey = key.OpenSubKey(path, false))
        {
            if (subKey == null)
            {
                return false;
            }
        }
 
        return true;
    }
 
    public static bool RegistrySetBool(this bool b, RegistryHive hive, string path, string value)
    {
        RegistryKey registryKey = GetKeyFromHive(hive);
 
        RegistryKey subKey = null;
 
        try
        {
            subKey = registryKey.OpenSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree) ?? 
                registryKey.CreateSubKey(path, RegistryKeyPermissionCheck.ReadWriteSubTree);
 
            if (subKey == null)
            {
                return false;
            }
 
            subKey.SetValue(value, b);
 
            return true;
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
            return false;
        }
        finally
        {
            if (subKey != null)
            {
                subKey.Close();
                subKey.Dispose();
            }
        }
    }
 
    public static Type Translate(this RegistryValueKind value)
    {
        switch (value)
        {
            case RegistryValueKind.MultiString:
            case RegistryValueKind.ExpandString:
            case RegistryValueKind.String:
                return typeof(string);
 
            case RegistryValueKind.Binary:
                return typeof(byte[]);
 
            case RegistryValueKind.DWord:
                return typeof(int);
 
            case RegistryValueKind.QWord:
                return typeof(long);
 
            case RegistryValueKind.Unknown:
            case RegistryValueKind.None:
                return typeof(object);
 
            default:
                throw new ArgumentOutOfRangeException(nameof(value), value, null);
        }
    }
 
    private static void BuildTree(RegistryKey parentKey, 
        Node parent, 
        bool unpackMultiStrings, 
        bool unpackByteArrays, 
        ref List<Node> tree)
    {
        Node node = new Node(parent, parentKey.Name);
 
        tree.Add(node);
 
        List<string> valueNames = parentKey.GetValueNames().ToList();
 
        for (int index = 0; index < valueNames.Countindex++)
        {
            string valueName = valueNames[index];
 
            object value = parentKey.GetValue(valueName);
 
            if (value == null)
            {
                continue;
            }
 
            if (value.GetType() == typeof(string[]))
            {
                if (unpackMultiStrings)
                {
                    string[] strings = (string[])value;
 
                    value = strings.Length == 1 ? strings[0] : strings.Concatenate(strings.Length@",");
                }
                else
                {
                    value = @"string[]";
                }
            }
 
            if (value.GetType() == typeof(byte[]))
            {
                value = unpackByteArrays ? BitConverter.ToString((byte[])value) : @"byte[]";
            }
 
            if (value is string && (string)value == string.Empty)
            {
                value = @"[No Value]";
            }
 
            node.ValueCollection.Add(valueName, parentKey.GetValueKind(valueName).Translate(), value);
        }
 
        foreach (string childrenKeyName in parentKey.GetSubKeyNames().ToList())
        {
            RegistryKey childKey = null;
 
            try
            {
                childKey = parentKey.OpenSubKey(childrenKeyName, RegistryKeyPermissionCheck.ReadSubTreeRegistryRights.ReadKey | RegistryRights.QueryValues);
 
                if (childKey != null)
                {
                    Node childNode = new Node(node, childKey.Name);
 
                    node.Children.Add(childNode);
 
                    BuildTree(childKey, childNode, unpackMultiStrings, unpackByteArrays, ref tree);
                }
            }
            catch (SecurityException exception)
            {
                DebugFx.WriteLine(string.Format(@"Security Exception: {0}  Key ='{1}'.", exception.CreateMessage(false), childrenKeyName));
            }
            catch (IOException exception)
            {
                DebugFx.WriteLine(string.Format(@"IO Exception: {0}  Key ='{1}'.", exception.CreateMessage(false), childrenKeyName));
            }
            catch (Exception exception)
            {
                DebugFx.WriteLine(string.Format(@"General Exception: {0}  Key ='{1}'.", exception.CreateMessage(false), childrenKeyName));
            }
            finally
            {
                if (childKey != null)
                {
                    childKey.Close();
                    childKey.Dispose();
                }
            }
        }
    }
 
    private static RegistryKey GetKeyFromHive(RegistryHive hive)
    {
        RegistryKey registryKey;
 
        switch (hive)
        {
            case RegistryHive.ClassesRoot:
                registryKey = Registry.ClassesRoot;
                break;
 
            case RegistryHive.CurrentUser:
                registryKey = Registry.CurrentUser;
                break;
 
            case RegistryHive.LocalMachine:
                registryKey = Registry.LocalMachine;
                break;
 
            case RegistryHive.Users:
                registryKey = Registry.Users;
                break;
 
            case RegistryHive.CurrentConfig:
                registryKey = Registry.CurrentConfig;
                break;
 
            case RegistryHive.PerformanceData:
            case RegistryHive.DynData:
                throw new ArgumentOutOfRangeException(nameof(hive), hive, null);
            default:
                throw new ArgumentOutOfRangeException(nameof(hive), hive, null);
        }
 
        return registryKey;
    }
}
These extensions allow you to do things like the following:


public void RegExtensionsExamples()
{
    // First, the simple stuff ==>
 
    // Get the list of sub keys of a registry key
    List<string> subkeys = @"\SOFTWARE\ShibumiWare".RegistryGetKeySubkeys(RegistryHive.LocalMachine);
 
    // Of course most of the time your key data will be in a variable so let's get fancier:
           
    // Here is full key.
    string dellCommandUpdateKey = @"HKEY_LOCAL_MACHINE\SOFTWARE\DELL\CommandUpdate";
    string parseResults;
 
    // Get the hive from the key, since we are too lazy to shorten it and provide it as a value
    RegistryHive hive = dellCommandUpdateKey.RegistryGetHive(out parseResults);
           
    // Get the version OR a default value 
    string version = dellCommandUpdateKey.RegistryGetValue<string>(hive, "ProductVersion"default(string));
 
    // Fancy, fancy==>
 
    // Builds a tree of the subgraph of ShibumiWare's software registry key
    List<Node> swTree = @"\SOFTWARE\ShibumiWare".BuildTree(RegistryHive.LocalMachine);
 
    // Builds a tree of the subgraph of Microsoft's software registry key 
    List<Node> softwareTree = @"\SOFTWARE\Microsoft".BuildTree(RegistryHive.LocalMachine);
 
    // The tree contains all sorts of goodies
    DisplayTree(softwareTree[0]);
 
    // Here are a complete list:
    dellCommandUpdateKey.RegistryGetValue();
    dellCommandUpdateKey.RegistryGetKeySubkeys();
    dellCommandUpdateKey.RegistryGetKeySubkeys();
    dellCommandUpdateKey.RegistryGetKeyValueInfo();
    dellCommandUpdateKey.RegistryGetHive();
    dellCommandUpdateKey.RegistryKeyExists();
}
 
private void DisplayTree(Node parentNode)
{
    foreach (KeyValuePair<stringTuple<Typeobject>> kvp in parentNode.ValueCollection)
    {
        Debug.WriteLine("Key {0} contains value {1} of type {2}", kvp.Key, kvp.Value.Item2, kvp.Value.Item1);
    }
 
    foreach (Node childNode in parentNode.Children)
    {
        DisplayTree(childNode);
    }
}
Now that I think about it, the reason I put most of these
extensions together was for a project called Registry Analyst, that gave you a better graphical UI into the Registry and also a command line tool for
exporting registry data for search purposes.  Searching text is much faster than searching through the registry via Win32 and many things don't change
plus you could easily do a diff between snapshots to see what changed--maybe between instances of running a particular program or even comparing the
registry from one machine to the next.  It is a lot more readable and faster than using RegEdit to do the export.   Anyway, maybe I
will get that project put together and posted.


 









No comments :

Disclaimer

Content on this site is provided "AS IS" with no warranties and confers no rights. Additionally, all content on this site is my own personal opinion and does not represent my employer's view in any way.