Click here to Skip to main content
15,885,767 members
Articles / Programming Languages / C#

Implement an Autoplay Handler

Rate me:
Please Sign up or sign in to vote.
5.00/5 (22 votes)
18 Sep 2006CPOL8 min read 117.7K   1.7K   78  
Implementing an Autoplay handler in C#.
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

using Microsoft.Win32;

/*******************************************************************************************
 *	Author: Tim Almdal
 *	Date: Sept, 2006
 *			tnalmdal (at) shaw-dot-net
 * 
 *	RegistryScript class. Parses and processes a ATL like registry
 *	Script for update application settings in the registry
 * 
 *  Copyright (c) 2006 T. ALmdal
 *
 *  Permission is hereby granted, free of charge, to any person obtaining 
 *  a copy of this software and associated documentation files (the "Software"),
 *  to deal in the Software without restriction, including without limitation 
 *  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
 *  and/or sell copies of the Software, and to permit persons to whom the 
 *  Software is furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included 
 *  in all copies or substantial portions of the Software.
 *  
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
 *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
/*******************************************************************************************/
namespace Almdal.RegistryScript {
	/// <summary>
	/// Enum of the available Registry Operations on the process key
	/// </summary>
    internal enum RegistryOperation {
        OpenKey,
        DeleteKey,
        CloseKey,
        DeleteAddKey,
        AddKey,
        AddValue,
        DeleteValue,
	}

	#region Processing Queue Item Definition
	/// <summary>
	/// Class that represents an entry on the Registy Process Queue
	/// </summary>
    internal class RegistryOpQueueItem {
        public RegistryOperation _op;
        public string _key;
        public string _value;
        public RegistryValueKind _type;

		/// <summary>
		/// Create Registry Process Key Entry with no key name.
		/// </summary>
		/// <param name="op">The Registry Operation to Perform</param>
        public RegistryOpQueueItem(RegistryOperation op) {
            _op = op;
            _key = "";
            _value = "";
            _type = RegistryValueKind.Unknown;
        }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="op">The Registry Operation to Perform</param>
		/// <param name="key">The name of the key or value to operate on</param>
        public RegistryOpQueueItem(RegistryOperation op, string key)
            : this(op) {
            _key = key;
        }

		/// <summary>
		/// Override for pretty output when debuggin
		/// </summary>
		/// <returns>A String representation</returns>
        public override string ToString() {
            StringBuilder sb = new StringBuilder(128);
            sb.Append(base.ToString()).Append('[');
            sb.Append("Op: ").Append(_op);
            sb.Append("; Key: ").Append(_key);
            sb.Append("; Value: ").Append(_value);
            sb.Append("; ValueType: ").Append(_type);
            sb.Append(']');
            return sb.ToString();
        }
	}
	#endregion

	#region Registry Key Stack Item
	/// <summary>
	/// Class the represents a registry key on a stack,  When a key is
	/// added or opened, it goes on the stack so that we have access to
	/// the current parent key.  If the key was deleted, then an entry
	/// goes on the stack, but there is no RegistryKey class associated 
	/// with it.
	/// </summary>
	internal class ReqistryOpStackItem {
        public string _keyName;
        public bool _isDeleted;
        public RegistryKey _key = null;

        public ReqistryOpStackItem(string keyName) : this(keyName, null) { }

        public ReqistryOpStackItem(string keyName, RegistryKey key) {
            _keyName = keyName;
            _key = key;
            _isDeleted = key == null;
        }
    }
	#endregion

	/// <summary>
	/// The Registry operations process queue class.
	/// </summary>
    internal class OpQueue : Queue<RegistryOpQueueItem> {
		/// <summary>
		/// Stack of registry keys
		/// </summary>
        Stack<ReqistryOpStackItem> _keyStack = new Stack<ReqistryOpStackItem>();

		/// <summary>
		/// Public method to process the entries in the process queue.
		/// </summary>
        public void ProcessRegistryQueue() {
            for (RegistryOpQueueItem qi = this.Dequeue();
                 this.Count != 0;
                 qi = this.Dequeue()) {
                switch (qi._op) {
                    case RegistryOperation.OpenKey:
                        OpenKey(qi);
                        break;
                    case RegistryOperation.DeleteAddKey:
                        DeleteAddKey(qi);
                        break;
                    case RegistryOperation.DeleteKey:
                        DeleteKey(qi);
                        break;
                    case RegistryOperation.CloseKey:
                        CloseKey(qi);
                        break;
                    case RegistryOperation.AddKey:
                        AddKey(qi);
                        break;
                    case RegistryOperation.AddValue:
                        AddValue(qi);
                        break;
                    case RegistryOperation.DeleteValue:
                        DeleteValue(qi);
                        break;
                }
            }
        }

		/// <summary>
		/// Open the specified key.  
		/// 
		/// If there is nothing on then stack then open
		/// a registry root key.  Life is simplified as we smartly used the 
		/// Registry.fieldName as the key name.  This allows us to retireve
		/// the Registry Key by reflection.
		/// 
		/// Otherwise, open the key as a sub key of the top of the registry
		/// key stack.  Before attempting to open the subkey, verify that the
		/// parent is not deleted.
		/// </summary>
		/// <param name="qi">The Registry Operations Queue entry</param>
        private void OpenKey(RegistryOpQueueItem qi) {
            RegistryKey regKey;
            if (_keyStack.Count == 0) {
                FieldInfo field = typeof(Registry).GetField(qi._key, BindingFlags.Static |
                                                                        BindingFlags.Public);
                regKey = (RegistryKey)field.GetValue(null);
            }
            else {
                if (!_keyStack.Peek()._isDeleted) {         //  the parent is not deleted then delete it
                    regKey = _keyStack.Peek()._key.OpenSubKey(qi._key, true);
                }
                else {
                    regKey = null;
                }
            }
            _keyStack.Push(new ReqistryOpStackItem(qi._key, regKey));
        }

		/// <summary>
		/// Delete the specified key and all of its childern, then readd the key
		/// </summary>
		/// <param name="qi">The Registry Operations Queue entry</param>
		private void DeleteAddKey(RegistryOpQueueItem qi) {
            RegistryKey regKey = _keyStack.Peek()._key;

            try {
                regKey.DeleteSubKeyTree(qi._key);
            } catch (ArgumentException ) {
            }
            AddKey(qi);
        }

		/// <summary>
		/// Delete the specified key and all its children from the registry
		/// </summary>
		/// <param name="qi">The Registry Operations Queue entry</param>
		private void DeleteKey(RegistryOpQueueItem qi) {
            if (!_keyStack.Peek()._isDeleted) {         //  the parent is not deleted then delete it
                RegistryKey regKey = _keyStack.Peek()._key;
                try {
                    regKey.DeleteSubKeyTree(qi._key);
                } catch (ArgumentException) {
                }
            }
            _keyStack.Push(new ReqistryOpStackItem(qi._key));
        }

		/// <summary>
		/// Close the key at the top of the Registry Key stack
		/// </summary>
		/// <param name="qi">The Registry Operations Queue entry</param>
		private void CloseKey(RegistryOpQueueItem qi) {
            ReqistryOpStackItem top = _keyStack.Pop();
            if (!top._isDeleted) {
                top._key.Close();
            }
        }

		/// <summary>
		/// Adds a key to registry.  After it is added, the entry is added to the
		/// top of the Registry Key stack.
		/// </summary>
		/// <param name="qi">The Registry Operations Queue entry</param>
		private void AddKey(RegistryOpQueueItem qi) {
            RegistryKey newKey = null;
            if (!_keyStack.Peek()._isDeleted) {         //  the parent is not deleted then delete it
                RegistryKey regKey = _keyStack.Peek()._key;
                newKey = regKey.CreateSubKey(qi._key);
            }
            _keyStack.Push(new ReqistryOpStackItem(qi._key, newKey));
        }

		/// <summary>
		/// Add specified value to the registry
		/// </summary>
		/// <param name="qi">The Registry Operations Queue entry</param>
		private void AddValue(RegistryOpQueueItem qi) {
            if (!_keyStack.Peek()._isDeleted) {         //  the parent is not deleted then delete it
				RegistryKey regKey = _keyStack.Peek()._key;
				switch (qi._type) {
					case RegistryValueKind.String:
						regKey.SetValue(string.Empty.Equals(qi._key) ? null : qi._key, qi._value, qi._type);
						break;
					case RegistryValueKind.Binary:
						throw new NotImplementedException("Registry value type '" + qi._type + "' isnot implemented");
					case RegistryValueKind.DWord:
						int dword = Convert.ToInt32(qi._value);
						regKey.SetValue(string.Empty.Equals(qi._key) ? null : qi._key, dword, qi._type);
						break;
					case RegistryValueKind.MultiString:
						throw new NotImplementedException("Registry value type '" + qi._type + "' isnot implemented");
					default:
						throw new NotImplementedException("Registry value type '" + qi._type + "' isnot implemented");
				}
            }
        }

		/// <summary>
		/// Delete the specified valuefrom the registry
		/// </summary>
		/// <param name="qi">The Registry Operations Queue entry</param>
		private void DeleteValue(RegistryOpQueueItem qi) {
            if (!_keyStack.Peek()._isDeleted) {         //  the parent is not deleted then delete it
                RegistryKey regKey = _keyStack.Peek()._key;
                regKey.DeleteValue(qi._key, false);
            }
        }
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions