Click here to Skip to main content
15,886,422 members
Articles / Web Development / ASP.NET

A Simple protocol to view aspx pages without IIS implemented in C#

Rate me:
Please Sign up or sign in to vote.
4.92/5 (47 votes)
17 Feb 200413 min read 383.9K   6.9K   150  
Covers how to write a Pluggable Asyncrhonous Protocol using C# and provides a useful protocol to enable local execution of ASP.NET sites.
using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;

namespace Protocol
{

	[ComVisible(false)] public interface IComRegister
	{
		void Register(Type t);
		void Unregister(Type t);
	}

	/// <summary>
	/// Registers an Asyncrhonous Pluggable Protocol of the form {Name}:Url
	/// Your class needs to provide two methods of the following types or derive from ProtocolBase.
	/// [ AsyncProtocol(Name="echo", Description="Returns the URL of the protocol as HTML content.") ]
	/// public MyComClass 
	/// {
	///		[ComRegisterFunction] 
	///		private static void RegisterProtocol(Type t)
	///		{
	///			ProtocolSupport.RegisterProtocol(t);
	///		}
	///		[ComUnregisterFunction] 
	///		private static void UnregisterProtocol(Type t)
	///		{
	///			ProtocolSupport.UnregisterProtocol(t);
	///		}
	///		
	///		//MyClass Methods...
	///	}
	/// </summary>
	[ComVisible(false), AttributeUsage(AttributeTargets.Class, AllowMultiple=true) ] 
	public class AsyncProtocolAttribute : Attribute, IComRegister
	{
		public string Name;
		public string Description;

		public void Register(Type t)
		{
			RegistryKey ProtocolKey = Registry.ClassesRoot.CreateSubKey(RegistryPath);
			ProtocolKey.SetValue(null, Description);
			ProtocolKey.SetValue("CLSID", "{" + ProtocolSupport.GetGuid(t) + "}");
			Console.WriteLine("Registered Protocol:" + Name);
		}

		public void Unregister(Type t)
		{
			try 
			{
				Registry.ClassesRoot.DeleteSubKeyTree(RegistryPath);
				Console.WriteLine("UnRegistered Protocol:" + Name);
			} 
			catch (ArgumentException)	{ /*sink this exception because we don't care if this key doesn't exist */ }
		}

		protected string RegistryPath
		{
			get { return @"PROTOCOLS\Handler\" + Name; }
		}

	}

	[ComVisible(false), AttributeUsage(AttributeTargets.Class, AllowMultiple=true) ] 
	public class ContextHandlerAttribute : Attribute, IComRegister
	{
		#region IComRegister Members

		public string Key;
		public string Name;
		public string Description;

		public void Register(Type t)
		{
			RegistryKey ProtocolKey = Registry.ClassesRoot.CreateSubKey(RegistryPath);
			ProtocolKey.SetValue(null, "{" + ProtocolSupport.GetGuid(t) + "}");
			Console.WriteLine("Registered ContextHandler:" + Key + "|" + Name);
		}

		public void Unregister(Type t)
		{
			try 
			{
				Registry.ClassesRoot.DeleteSubKeyTree(RegistryPath);
				Console.WriteLine("UnRegistered ContextHandler:" + Key + "|" + Name);
			} 
			catch (ArgumentException)	{ /*sink this exception because we don't care if this key doesn't exist */ }
		}

		protected string RegistryPath
		{
			get { return Key + @"\shellex\ContextMenuHandlers\" + Name; }
		}

		#endregion
	}
		
	/// <summary>
	/// This class provides the support for protocol registration based on the AsyncProtocolAttribute class.
	/// </summary>
	[ComVisible(false)] public class ProtocolSupport
	{
		public static void RegisterProtocol(Type t)
		{
			IComRegister[] Protocols = GetAttributes(t);
			if (Protocols == null || Protocols.Length == 0)
				return;
			foreach(IComRegister Protocol in Protocols)
				Protocol.Register(t);
		}

		public static void UnregisterProtocol(Type t)
		{
			IComRegister[] Protocols = GetAttributes(t);
			if (Protocols == null || Protocols.Length == 0)
				return;
			foreach(IComRegister Protocol in Protocols)
				Protocol.Unregister(t);
		}

		public static IComRegister[] GetAttributes(Type t)
		{
			return (IComRegister[])t.GetCustomAttributes(typeof(IComRegister), false);
		}

		public static string GetGuid(Type t)
		{
			object[] Guids = t.GetCustomAttributes(typeof(GuidAttribute), false);
			if (Guids == null || Guids.Length == 0)
				throw new Exception("All Types marked with the ProtocolAttribute must be marked with the GuidAttribute.");
			return ((GuidAttribute)Guids[0]).Value;
		}

	}
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) Standard Beagle Studios
United States United States
I co-founded Standard Beagle Studio, a software development consulting service in Austin Texas with my wife Cindy Brummer. We focus mostly on web projects, but have built some react native mobile apps, and even a windows screen saver or two.

I started my career back when ASP pages were state of the art, and IE3 was considered a web browser. I've worked with Microsoft technologies for most of that time, and have recently branched out into node, wordpress, and react native applications.

I'm a web developer, math and physics enthusiast, father of 2, and all around great guy. I live in Austin TX and love using technology to change people's lives for the better. When I manage scrape together some spare time, I build generative art at curvature of the mind.

Comments and Discussions