<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="/feed.xslt" media="screen"?>

<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>C# test.net</title>
	<atom:link href="http://csharptest.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://csharptest.net/</link>
	<description>another random site full of random stuff</description>
	<lastBuildDate>Wed, 16 May 2012 00:56:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>WCF replacement for cross process/machine communication</title>
		<link>http://csharptest.net/1177/wcf-replacement-for-cross-processmachine-communication/</link>
		<comments>http://csharptest.net/1177/wcf-replacement-for-cross-processmachine-communication/</comments>
		<pubDate>Tue, 15 May 2012 21:09:58 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[Protocol Buffers]]></category>
		<category><![CDATA[RpcLibrary]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1177</guid>
		<description><![CDATA[I ran across another post of someone looking to get rid of WCF on StackOverflow today. The post titled &#8220;WCF replacement for cross process/machine communication&#8221; goes into the typical complaints about configuration of WCF. I actually think this is the least of the issues I&#8217;ve had with WCF. Whatever your reason for looking to abandon <a href='http://csharptest.net/1177/wcf-replacement-for-cross-processmachine-communication/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I ran across another post of someone looking to get rid of WCF on StackOverflow today.  The post titled &#8220;<a href="http://stackoverflow.com/questions/10608355/wcf-replacement-for-cross-process-machine-communcation" title="WCF replacement for cross process/machine communication" target="_blank">WCF replacement for cross process/machine communication</a>&#8221; goes into the typical complaints about configuration of WCF.  I actually think this is the least of the issues I&#8217;ve had with WCF.  Whatever your reason for looking to abandon WCF, this post is for you.  A step-by-step walk-through to get up and running with protobuffers over Win32 rpc.</p>
<h3>Step 1 &#8211; Gathering dependencies</h3>
<p>For this post I&#8217;m going to be using VStudio 2008.  The primary reason is to show the explicit use of NuGet rather than depending on Visual Studio to do it for us.  Now let&#8217;s get started.  Start by creating a new project in Visual Studio, for this I&#8217;m going to use a simple command-line application named &#8220;SampleProtoRpc&#8221;.</p>
<p>After you have created the project, right-click the project and select &#8220;New Folder&#8221; and type the name &#8220;Depends&#8221;.  Now visit the <a href="http://nuget.codeplex.com/releases" title="http://nuget.codeplex.com/releases" target="_blank">NuGet project page</a> and download the &#8220;NuGet.exe Command Line bootstrapper&#8221;.  It should be a single file, &#8220;NuGet.exe&#8221;.  Place this file in the newly created &#8220;Depends&#8221; directory.  From a command-prompt, run NuGet.exe to ensure that you are up and running.</p>
<p>Now right-click the project and select the &#8220;Properites&#8221; from the bottom.  In the properties window, click the &#8220;Build Events&#8221; tab on the left.  In the &#8220;Pre-build event command line:&#8221; text box enter the following text:</p>
<pre>
"$(ProjectDir)Depends\NuGet.exe" INSTALL Google.ProtocolBuffers.Rpc -OutputDirectory "$(ProjectDir)Depends" -ExcludeVersion -Version 1.11.1016.3
</pre>
<p>You can update the version to the latest by checking the current version at <a href="http://nuget.org/packages/Google.ProtocolBuffers.Rpc" title="http://nuget.org/packages/Google.ProtocolBuffers.Rpc" target="_blank">http://nuget.org/packages/Google.ProtocolBuffers.Rpc</a>.  The reason to use a fixed version is to prevent NuGet from constantly checking with the server to see if it has the latest version.  By pinning the version number NuGet.exe will make a quick check and continue if it exists.  </p>
<p>Click &#8220;Build&#8221; and view the Output window, it should contain something like the following text:</p>
<pre>------ Build started: Project: SampleProtoRpc, Configuration: Debug Any CPU ------
"E:\Projects\Templates\SampleProtoRpc\Depends\NuGet.exe" INSTALL Google.ProtocolBuffers.Rpc -OutputDirectory "E:\Projects\Templates\SampleProtoRpc\Depends" -ExcludeVersion -Version 1.11.1016.3
Attempting to resolve dependency 'CSharpTest.Net.RpcLibrary (≥ 1.11.924.348)'.
Attempting to resolve dependency 'Google.ProtocolBuffers (≥ 2.4.1.473)'.
Successfully installed 'CSharpTest.Net.RpcLibrary 1.11.924.348'.
Successfully installed 'Google.ProtocolBuffers 2.4.1.473'.
Successfully installed 'Google.ProtocolBuffers.Rpc 1.11.1016.3'.
SampleProtoRpc -> E:\Projects\Templates\SampleProtoRpc\bin\Debug\SampleProtoRpc.exe
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========</pre>
<p>Lastly we need to add the dependencies to the project.  Right-click the &#8220;References&#8221; folder in the project and select &#8220;Add References&#8230;&#8221;.  Click on the &#8220;Browse&#8221; tab in the resulting &#8220;Add Reference&#8221; dialog box.  For each of the following files navigate to the directory and select the file:</p>
<ul>
<li>Depends\Google.ProtocolBuffers\lib\net20\Google.ProtocolBuffers.dll</li>
<li>Depends\CSharpTest.Net.RpcLibrary\lib\net20\CSharpTest.Net.RpcLibrary.dll</li>
<li>Depends\Google.ProtocolBuffers.Rpc\lib\net20\Google.ProtocolBuffers.Rpc.dll</li>
</ul>
<p>Don&#8217;t worry about these being &#8216;net20&#8242; assemblies, it will work fine in 3.5.  If you insist upon native 4.0 images, the first two packages contain net40 versions; however, the Google.ProtocolBuffers.Rpc does not at this time.  You will need to pull the source and build a 4.0 version for that library.</p>
<h3>Step 2 &#8211; Defining a Protocol</h3>
<p>Now that we have a project containing the correct dependencies we need to add a protocol definition file.  This is a very easy format to write in, if you need help see the <a href="https://developers.google.com/protocol-buffers/docs/proto" title="Google Protocol Buffers Language Guide" target="_blank">Google Protocol Buffers Language Guide</a>.  For now let&#8217;s get started by right-clicking the project, and selecting &#8220;Add&#8221; -> &#8220;New Item&#8230;&#8221;.  Select the &#8220;General&#8221; tab on the left, and then pick the &#8220;Text File&#8221; option from the right-hand list.  In the &#8220;Name&#8221; field, enter &#8220;Sample.proto&#8221; and click the &#8220;Add&#8221; button.  </p>
<p>Once you have created the file, select &#8220;File&#8221; -> &#8220;Save As&#8230;&#8221; from the menu.  Next to the &#8220;Save&#8221; button click on the drop-down arrow and choose &#8220;Save with Encoding&#8221;.  Answer &#8220;Yes&#8221; when prompted to overwrite the file.  From the &#8220;Encoding:&#8221; list, choose the option &#8220;US-ASCII &#8211; Codepage 20127&#8243; near the end of the list and then click &#8220;OK&#8221;.</p>
<p>Now we can type a protocol buffer definition in this file.  For now we are going to use the following:</p>
<pre>
package Sample;
option optimize_for = SPEED;

message MyRequest {
  required string message = 1;
}

message MyResponse {
}

service MyService {
  rpc Send (MyRequest) returns (MyResponse);
}
</pre>
<p>And this will be our first service.  To generate the source, we are going to add another pre-build event.  Right-click the project and select &#8220;Properties&#8221; again.  On the &#8220;Build Events&#8221; pane add the following line:</p>
<pre>
"$(ProjectDir)Depends\Google.ProtocolBuffers\tools\ProtoGen.exe" --proto_path="$(ProjectDir)\" -output_directory="$(ProjectDir)\" -cls_compliance=false -service_generator_type=IRPCDISPATCH "$(ProjectDir)Sample.proto"
</pre>
<p>You should now be able to build the project successfully.  Once completed, right-click the project and choose &#8220;Add&#8221; -> &#8220;Existing Item&#8230;&#8221;, then select the &#8220;Sample.cs&#8221; that should appear next to the &#8220;Sample.proto&#8221; file we created.  Admittingly this is a crufty integration at best.  </p>
<p>If you are not opposed to it, I would recommend using CmdTool.exe with a configuration similar to <a href="http://help.csharptest.net/?CmdToolIntegrateProtoGen.html" title="Sample CmdTool Integration" target="_blank">this example</a>.  CmdTool.exe is available in <a href="http://code.google.com/p/csharptest-net/downloads/list" title="Download CmdTool.exe" target="_blank">one of these downloads</a>, you just download, run &#8220;CmdTool.exe Register&#8221; and save the configuration example in the same directory as the project.  That&#8217;s about it, you now have all the source generated to do the work.</p>
<h3>Step 3 &#8211; Implementing the Service</h3>
<p>Before we can go much further we must implement our service interface.  Right-click the project and add a new Class file so we can create our implementation, I just called mine &#8220;Implementation&#8221;.  The interface has already been defined for us, it&#8217;s name will be our service&#8217;s name prepended with an &#8216;I&#8217;.  Here is a first-pass implementation that simply writes the message to the console.</p>
<pre class="brush:csharp">
    class Implementation : IMyService
    {
        #region IMyService Members
        public MyResponse Send(MyRequest myRequest)
        {
            using (WindowsIdentity user = WindowsIdentity.GetCurrent())
            {
                Console.WriteLine("{0} says: {1}", user.Name, myRequest.Message);
                return MyResponse.DefaultInstance;
            }
        }
        #endregion
    }
</pre>
<h3>Step 4 &#8211; Setting up the Listener</h3>
<p>Time to start playing with our server-side listener.  For this example we are going to allow lrpc, tcp, or named pipes.  The static IID defines the interface we want to talk to.  We can host several interfaces from this process, but this example will only use one.  You will notice we create the generated server proxy &#8220;MyService.ServerStub&#8221; by handing it an implementation of the IMyService interface.  This server stub can then be used to create the RpcServer instance.  Once we add at least one protocol and call StartListening we are ready to receive calls.  The setup is trivial, so without further explanation here is our new &#8216;Program&#8217; class:</p>
<pre class="brush:csharp">
    class Program
    {
        static readonly Guid IID = Marshal.GenerateGuidForType(typeof(IMyService));

        static void Main(string[] args)
        {
            switch (args[0].ToLower())
            {
                case "listen":
                    {
                        using (RpcServer.CreateRpc(IID, new MyService.ServerStub(new Implementation()))
                            .AddAuthNegotiate()
                            .AddProtocol("ncacn_ip_tcp", "8080")
                            .AddProtocol("ncacn_np", @"\pipe\MyService")
                            .AddProtocol("ncalrpc", "MyService")
                            .StartListening())
                        {
                            Console.WriteLine("Waiting for connections...");
                            Console.ReadLine();
                        }
                        break;
                    }
            }
        }
    }
</pre>
<h3>Step 4 &#8211; Sending a Message</h3>
<p>Now that we have a working server we need to write a client.  The reason for the Main() method above to switch on arg[0] for &#8216;listen&#8217; is that we are going to use the same program for a client.  The client case statement below adds support for an LRPC client call:</p>
<pre class="brush:csharp">
                case "send-lrpc":
                    {
                        using (MyService client = new MyService(
                            RpcClient.ConnectRpc(IID, "ncalrpc", null, "MyService")
                            .Authenticate(RpcAuthenticationType.Self)))
                        {
                            MyResponse response = client.Send(
                                MyRequest.CreateBuilder().SetMessage("Hello via LRPC!").Build());
                        }
                        break;
                    }
</pre>
<p>Once we have added this switch case to the Main routine we wrote we now run one process with the &#8216;listen&#8217; argument, and another one with the &#8216;send-lrpc&#8217; argument.  We should see the following output in the server process:</p>
<pre>
Waiting for connections...
DOMAIN\user says: Hello via LRPC!
</pre>
<p>You may now create two additional case labels, one for &#8220;send-tcp&#8221;, and one for &#8220;send-np&#8221;.  The only difference between them will be the parameters to the RpcClient.ConnectRpc() api.  For TCP/IP we will use RpcClient.ConnectRpc(IID, &#8220;ncacn_ip_tcp&#8221;, @&#8221;localhost&#8221;, &#8220;8080&#8243;), and for named-pipes we would use RpcClient.ConnectRpc(IID, &#8220;ncacn_np&#8221;, @&#8221;\\localhost&#8221;, @&#8221;\pipe\MyService&#8221;).  Go ahead and fill those in or not at your choosing.  </p>
<h3>Step 5 &#8211; Authentication</h3>
<p>By default the RPC server will allow any user (even anonymous users) to connect.  This may work for your needs, this may not.  Usually you will want to impersonate the caller and then verify they have access to some resource or are a member of a specific group, etc.  To do this in a generic way so that we do not have to place the impersonation code in each method we are going to implement the Google.ProtocolBuffers.IRpcServerStub interface.  So let&#8217;s create a new class now called Impersonation and it&#8217;s going to look a lot like the following:</p>
<pre class="brush:csharp">
    class Impersonation : IRpcServerStub
    {
        private readonly IRpcServerStub _stub;

        public Impersonation(IRpcServerStub stub)
        {
            _stub = stub;
        }

        public IMessageLite CallMethod(string methodName, ICodedInputStream input, ExtensionRegistry registry)
        {
            using(RpcCallContext.Current.Impersonate())
            {
                return _stub.CallMethod(methodName, input, registry);
            }
        }

        public void Dispose()
        {
            _stub.Dispose();
        }
    }
</pre>
<p>Once that has been added we will update our server&#8217;s listen routine as follows:</p>
<pre class="brush:csharp">
                case "listen":
                    {
                        using (RpcServer.CreateRpc(IID, new Impersonation(new MyService.ServerStub(new Implementation())))
                            .AddAuthNegotiate()
                            ... etc ...
</pre>
<p>Now every call into every method of MyService implementation on the server will be impersonating the client user.  The Rpc layer will also ensure that they are NOT an anonymous user.</p>
<h3>Zipping it all up&#8230;</h3>
<p><strong>Server Options:</strong> There are numerous extensibility points on the server and client.  There are a few worth covering here.  The following is a brief outline of the most important configuration options.</p>
<ul>
<li><b>RpcServer.EnableMultiPart()</b> &#8211; Allows unlimited message lengths to be received over tcp/np connections.  By default Windows limits these to around 1mb.  To circumvent this limitation the server and client can be configured to send messages in multiple parts.  Both client and server must enable this for this to work, and doing so will enable server-side connection state.</li>
<li><b>RpcServer.ExceptionDetails</b> &#8211; An enumeration value that determines how much exception detail to return to the client.  The default, FullDetails, returns all information in the exception including the stack trace.</li>
<li><b>RpcServer.ExtensionRegistry</b> &#8211; Allows registration of proto-buffer &#8216;extensions&#8217; on both your service and on the transport messages defined in <a href="http://code.google.com/p/protobuf-csharp-rpc/source/browse/proto/google/protobuf/csharp_rpc_messages.proto" target="_blank">csharp_rpc_messages.proto</a>.  This can be used as a side-channel to flow information from the client to server and back again.</li>
<li><b>RpcCallContext.Current</b></li>
<p> &#8211; This class provides context information about the caller, protocol, authentication, etc.</p>
<li><b>RpcSession.EnableSessions()</b></li>
<p> &#8211; Enables session state, accessed via RpcCallContext.Session for the current call.
</p></ul>
<p><strong>Client Options:</strong> The following controls the client options:</p>
<ul>
<li><b>RpcClient.EnableMultiPart()</b> &#8211; Allows unlimited message lengths to be sent over tcp/np connections.  By default Windows limits these to around 1mb.  To circumvent this limitation the server and client can be configured to send messages in multiple parts.  Both client and server must enable this for this to work, and doing so will enable server-side connection state.</li>
<li><b>RpcClient.ExceptionTypeResolution</b> &#8211; This enumeration controls the exception type resolution when an exception is returned from a server.  The default, OnlyUseLoadedAssemblies, will only resolve types that are defined in assemblies that have already been loaded into the client process.</li>
<li><b>RpcClient.ExtensionRegistry</b> &#8211; Just as for the server, this allows proto-buffer &#8216;extensions&#8217; to be registered and used when receiving response messages.</li>
<li><b>RpcClient.CallContext</b> &#8211; Provides access to the call context instance associated with this connection.  Used with the extension registry this allows you to customize side-channel communications between the client and server.</li>
</ul>
<p><strong>Connection Caching</strong><br />
It should be noted that it is acceptable and generally useful to cache the RpcClient connection; however, you should be aware that a connection can be closed.  RpcClient connections will not retry a failed call and will not attempt to reconnect to a server once disconnected.  Due to this it is advisable that if you are caching client connections you should create an implementation of Google.ProtocolBuffers.IRpcDispatch.  Delegate the actual RpcClient.ConnectRpc() call and configuration to this object so that it can reconnect at will.  Finally use this object as as the parameter to the MyService() constructor instead of directly using the RpcClient.ConnectRpc() result.</p>
<table>
<tbody>
<tr>
<td width="75"><img src="http://csharptest.net/images/winzip.png" alt="zip" width="50" height="50"/></td>
<td><a title="/downloads/projects/SampleProtoRpc.zip" href="http://csharptest.net/downloads/projects/SampleProtoRpc.zip">Download the Sample RPC Project</a><br />
The project zip file is completely stand-alone.  Just extract the contents and open the solution to build.
</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Separation of Concerns &#8211; Edit then Publish</title>
		<link>http://csharptest.net/1160/separation-of-concerns-edit-then-publish/</link>
		<comments>http://csharptest.net/1160/separation-of-concerns-edit-then-publish/</comments>
		<pubDate>Wed, 02 May 2012 17:28:49 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[HttpClone]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1160</guid>
		<description><![CDATA[Recently I ran across an article on the subject of Content Management Systems and their inability to separate content editing from content publishing. The article titled &#8220;EditingPublishingSeparation&#8221; by Martin Fowler is worth a read. I completely agree with his assertion that, from an architecture point of view, the editing and publishing of content should be <a href='http://csharptest.net/1160/separation-of-concerns-edit-then-publish/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Recently I ran across an article on the subject of Content Management Systems and their inability to separate content editing from content publishing.  The article titled &#8220;<a href="http://martinfowler.com/bliki/EditingPublishingSeparation.html" title="EditingPublishingSeparation" target="_blank">EditingPublishingSeparation</a>&#8221; by Martin Fowler is worth a read.</p>
<p>I completely agree with his assertion that, from an architecture point of view, the editing and publishing of content should be separated.  I would however take the assertion much farther than that.  Websites should NOT be capable of editing themselves.  The mere idea of this is absurd IMHO.  I&#8217;ve written CMS systems before back in the late 90&#8242;s, and even then it was obvious.  You can not secure a self-editing website.</p>
<h3>Why is a self-editing website a bad idea?</h3>
<p><strong>1. The group take down.</strong> To say most CMS systems have a vulnerability or two is putting it mildly.  Attackers love to take these vulnerabilities and then proceed to use automated software to seek out sites using that CMS and exploit them.  This allows them to inexpensively disperse malware to a large audience in a very short period of time.  This, IMHO, is the worst thing about running a CMS solution.  Nobody specifically targeted your site, it just happened to be running on software they knew how to attack.  No provocation needed, you got taken down with 10,000 other unfortunate people.</p>
<p><strong>2. It runs in the browser.</strong>  The issue here is that some form of logon allows users to modify the content on the web server.  This means that the user&#8217;s horribly insecure browser environment is entirely in control of &#8216;production&#8217; content.  Thus a simple XSS script, a malicious browser plugin, or other common vulnerability can allow an attacker to modify content.  Browsers are the worst place to be editing content.  Even with the advent of Windows Live Writer and other rich-client authoring tools you still occasionally need to log into the website.  So these tools help, but they do not fix the problem.</p>
<p><strong>3. Preview is not a preview.</strong>  Most all the of the CMS systems out there will allow you to preview the content before publishing it.  Most of them get it wrong.  It seems CMS systems are more and more moving to a &#8220;wysiwyg&#8221; display editing where they modify the output HTML so that you can edit it, even in preview.  This then gives you no assurance about how it will actually format and display since the authoring widgets on screen change the HTML being rendered.  Furthermore while previewing a single page is possible many CMS systems will not allow you to preview entirely new sections and navigation elements.  Lastly previewing an entire redesign of the site&#8217;s look-and-feel, navigation structure, etc is also not possible.</p>
<p><strong>4. My web server runs DRY.</strong>  CMS systems often fail to appropriately cache the rendered HTML.  This produces lags in performance as you server must reprocess the same content against the template over and over again.  I prefer my sever to run as DRY as possible, Don&#8217;t Repeat Yourself.  There is just no point in reprocessing the content for every request.</p>
<p><strong>5. User provided content.</strong>  IMHO, user authored content does not belong on your sever.  This is one of the driving factors behind #4 and is simply not necessary.  Using Facebook or another discussion server is easy.  If you need something more fancy that what is freely available, go build it.  Stand up a completely different site on a different domain with a completely different authentication model.  Users should never log in to your site.</p>
<p><strong>6. XCopy backup and deployment.</strong>  Asside from backup and deployment there is also the issue with applying a version control system to most CMS systems.  This is one of my biggest pet-peeves with CMS systems.  They absolutely love to rely on a database back-end.  Although some newer CMS solutions can use embeded sql servers, most do not support it and this is not an option if you are farming the content across several servers. I suspect most CMS sites are not being backed up regularly and if the server is lost or it&#8217;s drive corrupted their likely to loose most if not all of their site.</p>
<h3>What are my alternatives?</h3>
<p><strong>1. Find a better CMS.</strong>  I&#8217;m not aware of a single CMS system in operation today that avoids the issues above.  Please correct me in the comments if this is inaccurate, I&#8217;d love to know if one exists.</p>
<p><strong>2. Using a CDN (Content Distribution Network).</strong>  These are often very powerful tools and can be configured to avoid many of the issues mentioned above.  If you are looking for one I would consider <a href="http://www.cloudflare.com/" title="CloudFlare" target="_blank">CloudFlare</a> a viable starting point.</p>
<p><strong>3. HttpClone or similar product.</strong>  I&#8217;m sure there are other solutions that have similar capabilities, but honestly I love using HttpClone.  I use WordPress on the back-end and have a deployment script that automates the process end-to-end.  Whether I&#8217;m publishing the result to a test server or to production it&#8217;s relatively easy once you get it working.  The hard part was the configuration of the crawler to identify content I wanted removed or changed, and indexing for search.  Once that was complete I wrote a simple batch file to do the deployment that looks roughly like:</p>
<pre>
@ECHO OFF
HttpClone.exe crawlsite http://csharptest.net/
HttpClone.exe copysite http://csharptest.net/ http://csharptest.net /overwrite
HttpClone.exe optimize http://csharptest.net
HttpClone.exe index http://csharptest.net
HttpClone.exe addrelated http://csharptest.net
HttpClone.exe publish http://csharptest.net
mysqldump.exe -u root -ppassword --create-options --skip-extended-insert --databases csharptest --result-file=csharptest.sql
</pre>
<p>Basically what this does is crawls my locally running copy of this website (admin.csharptest.net) and captures the results.  Then it crawls all the pages and changes references from admin.csharptest.net to csharptest.net overwriting the content that was previously there.  Then it performs a series of steps: optimizing the content, creating the search index, and injecting related article links.  Finally it packages and publishes all the content to the remote site, and then backs up the database.  The entire site is instantly switched to the new content once it is ready.  For small edits I can choose to publish the content directly to production, or more often I push to a local site to then verify the content package.</p>
<p>Obviously the most vulnerable part of the process is the code on the server that allows publication.  This is why the entire thing requires the client and server to know each-other&#8217;s public key.  They negotiate a session key, transfer the file, and sign/verify every request and response.  This code uses the <a href="http://csharptest.net/browse/src/Library/Crypto" title="Client/Server SecureTransfer" target="_blank">CSharpTest.Net.Crypto.SecureTransfer</a> class from my library if you are interested in the details.  </p>
<p>The benefit to both client and server using a public/private key is that an observer knowing only one of the two keys can learn very little about the content being transferred.  It should be obvious that if an attacker obtains the servers private key they can replace the server (assuming some form of DNS poisoning or the like); however, they will not be able to then forward it to the actual server and still be able to read the content.  Again it should be obvious that if someone were to obtain my client private key they can publish new or modified content to the server since this is the only form of authentication.  I will add that even with my client private key they still can not upload anything that is executable on the server.  This leaves my server secure and in-tact and all that is needed for me to recover is replacing the client key and republishing the content.</p>
<p>I wish the guys at WordPress or another CMS would just do this out of the box.</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dispelling Myths about B+Trees</title>
		<link>http://csharptest.net/1144/dispelling-myths-about-btrees/</link>
		<comments>http://csharptest.net/1144/dispelling-myths-about-btrees/</comments>
		<pubDate>Tue, 10 Apr 2012 23:51:15 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[BPlusTree]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[b+tree]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1144</guid>
		<description><![CDATA[I&#8217;ve recently seen some comments about various aspects of btree/b+tree structures that are troublesome. They are, IMHO, just plain wrong. Let&#8217;s look at a few of these and see if we can shed some light on b+trees and their implementations. 1. Items in a tree node must be presorted. FALSE This is simply not true, <a href='http://csharptest.net/1144/dispelling-myths-about-btrees/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently seen some comments about various aspects of btree/b+tree structures that are troublesome. They are, IMHO, just plain wrong. Let&#8217;s look at a few of these and see if we can shed some light on b+trees and their implementations.</p>
<p><strong>1. Items in a tree node must be presorted.</strong><br />
<em>FALSE</em> This is simply not true, a btree can decide to sort the items in a node, or to perform a linear search. Neither approach change more than the small constants in the big-O, it&#8217;s still O(n log(n)). The BPlusTree keeps it&#8217;s children sorted since the memory-move cost is nothing compared to the disk IO.</p>
<p><strong>2. Split/Join of a node requires reorganizing it&#8217;s ancestors</strong><br />
<em>FALSE</em> While this is the most common approach it is also the most naive. Reorganization of the tree from the bottom-up is not only expensive but more complicated than the top-down approach. The BPlusTree uses a top-down reorg that says simply &#8220;If I&#8217;m inserting and this node is full, split&#8221; all the way down the tree. This means that at any given time I only need two nodes &#8216;locked&#8217; for write, me and my parent. Once I&#8217;m sure that this node is not full I can release my parent&#8217;s lock and move down the tree. Not only does this strategy allow multiple concurrent writers, but it also prevents deadlocks. By using this top-down approach locks are always acquired at the root and traverse down so that a deadlock is simply impossible.</p>
<p><strong>3. Nodes can have at most order-1 items</strong><br />
<em>FALSE</em> This is also a naive implementation detail where leaf nodes (or all nodes) have a vacant slot. It&#8217;s most commonly used when using a bottom-up reorganization so that you always have room to insert a split node. It is simply not necessary with either bottom-up or top-down reorganization, it&#8217;s just easier. BPlusTree uses all the space available in a node, only when inserting and already full will it split the node.</p>
<p><strong>4. Nodes can have no fewer than order/2 items</strong><br />
<em>FALSE</em> The minimum items in a node is 1.  When you calculate the lookup time with a minimum of 1 (<em>let b = 1</em>) you get <em>O</em>(log<sub><em>b</em></sub><em>n</em>) or <em>O</em>(<em>n).  So you never </em><em>want</em> a minimum value of 1, but you can do it.  Based on my own testing the best value for the minimum node count in BPlusTree is 1/3 of the order (or max).</p>
<p><strong>5. The order of a btree is the same at all levels</strong><br />
<em>FALSE</em> The BPlusTree supports having a different order for hierarchy nodes than that of it&#8217;s leaf nodes.  The reason is simple.  Disk-based B+Trees optimize disk access based on what will fit in a &#8216;page&#8217;.  Using 8kb as a page size, at the leaf node this is 8192 / (sizeof(key) + sizeof(value)).  At all other locations in the hierarchy this is 8192 / (sizeof(key) + c) where c is some constant size of data used to reference a child node.  This means that if I am storing 1kb records with a 4-byte key I want no more than 8 records in a leaf, whereas I can have as many as 680 children in a non-leaf node.  Now we can  <em>let b = 680</em> for <em>O</em>(log<sub><em>b</em></sub><em>n</em>), meaning we can find the leaf node of a 1,000,000 item tree in approximately 3 operations.</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to generate password using a specific set of characters</title>
		<link>http://csharptest.net/1074/how-to-generate-password-using-a-specific-set-of-characters/</link>
		<comments>http://csharptest.net/1074/how-to-generate-password-using-a-specific-set-of-characters/</comments>
		<pubDate>Wed, 21 Mar 2012 22:44:48 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[cryptography]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1074</guid>
		<description><![CDATA[Sometimes it is necessary to generate a password. This might be done to create a secure account on a machine, or to reset a user&#8217;s password via email (although a one-time use security token is a much better answer). Another possible use is to generate passwords for your own use on a website. There are <a href='http://csharptest.net/1074/how-to-generate-password-using-a-specific-set-of-characters/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Sometimes it is necessary to generate a password.  This might be done to create a secure account on a machine, or to reset a user&#8217;s password via email (although a one-time use security token is a much better answer).  Another possible use is to generate passwords for your own use on a website.  There are lots of ways to achieve this, but the method below would be my approach&#8230;</p>
<pre class="brush:csharp">
/// &lt;summary>
/// Creates a pseudo-random password containing the number of character classes
/// defined by complexity, where 2 = alpha, 3 = alpha+num, 4 = alpha+num+special.
/// &lt;/summary>
public static string GeneratePassword(int length, int complexity)
{
    System.Security.Cryptography.RNGCryptoServiceProvider csp =
        new System.Security.Cryptography.RNGCryptoServiceProvider();
    // Define the possible character classes where complexity defines the number
    // of classes to include in the final output.
    char[][] classes =
    {
        @"abcdefghijklmnopqrstuvwxyz".ToCharArray(),
        @"ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray(),
        @"0123456789".ToCharArray(),
        @" !""#$%&#038;'()*+,./:;&lt;>?@[\]^_{|}~".ToCharArray(),
    };

    complexity = Math.Max(1, Math.Min(classes.Length, complexity));
    if(length &lt; complexity)
        throw new ArgumentOutOfRangeException("length");

    // Since we are taking a random number 0-255 and modulo that by the number of
    // characters, characters that appear earilier in this array will recieve a
    // heavier weight. To counter this we will then reorder the array randomly.
    // This should prevent any specific character class from recieving a priority
    // based on it's order.
    char[] allchars = classes.Take(complexity).SelectMany(c => c).ToArray();
    byte[] bytes = new byte[allchars.Length];
    csp.GetBytes(bytes);
    for (int i = 0; i &lt; allchars.Length; i++)
    {
        char tmp = allchars[i];
        allchars[i] = allchars[bytes[i]%allchars.Length];
        allchars[bytes[i]%allchars.Length] = tmp;
    }

    // Create the random values to select the characters
    Array.Resize(ref bytes, length);
    char[] result = new char[length];

    while(true)
    {
        csp.GetBytes(bytes);
        // Obtain the character of the class for each random byte
        for (int i = 0; i &lt; length; i++)
            result[i] = allchars[bytes[i]%allchars.Length];

        // Verify that it does not start or end with whitespace
        if (Char.IsWhiteSpace(result[0]) || Char.IsWhiteSpace(result[(length - 1) % length]))
            continue;

        string testResult = new string(result);
        // Verify that all character classes are represented
        if (0 != classes.Take(complexity).Count(c => testResult.IndexOfAny(c) &lt; 0))
            continue;

        return testResult;
    }
}
</pre>
<p>Essentially this method starts by creating a randomly ordered set of characters to choose from.  The reason this is randomly ordered is that we will offset into this array by taking a random number from 0-255 modulo the length of the array.  Because of the modulo operation this can weight the first set of characters higher so we randomize it.</p>
<p>Once we have a randomly ordered set of characters to choose from we use the <a href="http://msdn.microsoft.com/en-us/library/5f45t420.aspx" target="_blank">RNGCryptoServiceProvider</a>.<a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.getbytes.aspx" target="_blank">GetBytes</a> to populate a byte array with random values.  Each random byte will be used to select a character in the output array.</p>
<p>Lastly we make a few assertions about the result.  Since a space &#8216; &#8216; can be a viable password character we make sure that the password neither starts with or ends with whitespace.  Having whitespace at the beginning or end would not only be confusing, but some input forms will automatically remove the trailing whitespace.  The second thing we verify is that each requested character class is represented by at least one character.  This ensures that an alpha-numeric password will contain at least one number and one letter.</p>
<p>This brings us to the &#8216;how long of a password to use&#8217; kind of question.  The following is a chart to display how many password characters are required to produce an equivelent key in bit-length:</p>
<table>
<thead>
<tr>
<td />
<td>case insensitive<br />(26 chars)</td>
<td>case sensitive<br />(52 chars)</td>
<td>alpha + numeric<br />(62 chars)</td>
<td>alpha + numeric + special<br />(92 chars)</td>
</tr>
</thead>
<tr>
<td>*56-bit</td>
<td>12</td>
<td>10</td>
<td>9</td>
<td>7</td>
</tr>
<tr>
<td>*64-bit</td>
<td>14</td>
<td>12</td>
<td>11</td>
<td>10</td>
</tr>
<tr>
<td>128-bit</td>
<td>28</td>
<td>23</td>
<td>22</td>
<td>20</td>
</tr>
<tr>
<td>256-bit</td>
<td>55</td>
<td>45</td>
<td>43</td>
<td>40</td>
</tr>
</table>
<p>*56-bit keys are capable of being brute forced in just a few hours on current specialized hardware.  Distributed systems are also capable of cracking 56-bit encryption.  128-bit keys are considered a minimum key space for today&#8217;s cryptographic algorithms.</p>
<p>The table is actually somewhat surprising to me in how little difference the added numeric and special characters make.  To make a password as secure as the AES/128-bit algorithm you need 23 upper and lower case characters.  Saving one keystroke by adding numbers to the mix just doesn&#8217;t seem all that worth while to me.  When you look at most people using just 8-12 characters for what they consider a &#8216;good&#8217; password it almost makes you laugh.</p>
<p>It seems to me that most password complexity rules requiring special characters and numbers make little sense.  I guess it prevents dictionary attacks to a degree, but clearly the length of the password is much more important.</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Back from extended vacation in SkyRim</title>
		<link>http://csharptest.net/1090/back-from-extended-vacation-in-skyrim/</link>
		<comments>http://csharptest.net/1090/back-from-extended-vacation-in-skyrim/</comments>
		<pubDate>Sun, 11 Mar 2012 04:39:52 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Home]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1090</guid>
		<description><![CDATA[I&#8217;m sure you havn&#8217;t missed me too much, but I&#8217;ve been away on extended vacation in Dragon&#8217;s Reach. SkyRim was a blast, and the most fun I&#8217;ve had playing a game since the original Portal. Now&#8230; back to the real world :(]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m sure you havn&#8217;t missed me too much, but I&#8217;ve been away on extended vacation in Dragon&#8217;s Reach.  SkyRim was a blast, and the most fun I&#8217;ve had playing a game since the original Portal.  Now&#8230; back to the real world :(</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to build a multi-protocol REST service with protocol buffers, xml, and json in 10 minutes or less using protobuf-csharp-port</title>
		<link>http://csharptest.net/1062/build-a-rest-service-protocol-buffers-xml-json-using-protobuf-csharp-port/</link>
		<comments>http://csharptest.net/1062/build-a-rest-service-protocol-buffers-xml-json-using-protobuf-csharp-port/</comments>
		<pubDate>Tue, 22 Nov 2011 19:19:29 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[Protocol Buffers]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[protobuffer]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[rpc]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1062</guid>
		<description><![CDATA[In this post we are going to explore some great new features introduced in the latest release of the protobuf-csharp-port project. We are going to build both an IIS service to handle requests as well as a sample client. Let&#8217;s get started. Prerequisites Let&#8217;s start by fetching a copy of the protobuf-csharp-port binaries. We can <a href='http://csharptest.net/1062/build-a-rest-service-protocol-buffers-xml-json-using-protobuf-csharp-port/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>In this post we are going to explore some great new features introduced in the latest release of the <a href="http://code.google.com/p/protobuf-csharp-port/" target="_blank">protobuf-csharp-port</a> project.  We are going to build both an IIS service to handle requests as well as a sample client.  Let&#8217;s get started.</p>
<p><strong>Prerequisites</strong><br />
Let&#8217;s start by fetching a copy of the <a href="http://code.google.com/p/protobuf-csharp-port/downloads/list" target="_blank">protobuf-csharp-port binaries</a>.  We can manually download these and unpack them, use NuGet installed in VS2010, or download the <a href="http://nuget.codeplex.com/releases/view/58939" target="_blank">NuGet Bootstrapper</a>.  I&#8217;m going to use the later approach and download NuGet.exe and run the following command:</p>
<pre>
C:\Projects\ProtoService>NuGet.exe install google.protocolbuffers -x
Successfully installed 'Google.ProtocolBuffers 2.4.1.473'.
</pre>
<p><strong>Service Definition</strong><br />
With our only dependencies out of the way we are going to need to define some messages and a service.  We will start with a new project in visual studio, for ease of demonstration I&#8217;ve created an ASP.NET project.  To create our service definition we are going to create an empty text file and save it with a &#8220;.proto&#8221; extension.  Be sure to use the File->Save As&#8230; menu on this text file, click the down arrow next to the Save button and select &#8220;Save with Encoding&#8230;&#8221;.  Near the bottom choose &#8220;US-ASCII &#8211; Codepage 20127&#8243;.  This is required by the protoc compiler as it does not support text BOM (<a href="http://en.wikipedia.org/wiki/Byte_order_mark" target="_blank">Byte order mark</a>).  Now that we have a text file let&#8217;s create a message for the request and response and the service using the <a href="http://code.google.com/apis/protocolbuffers/docs/proto.html" target="_blank">protobuffer definition language</a>:</p>
<pre>
package ProtoService;

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}
message SearchResponse {
  repeated group Result = 1 {
    required string url = 2;
    optional string title = 3;
    repeated string snippets = 4;
  }
}
message ErrorResult {
  required string error_text = 536870911; //max field-id
}
service SearchService {
  rpc Search (SearchRequest) returns (SearchResponse);
}
</pre>
<p><strong>Code Generation</strong><br />
Now with this saved to &#8220;ProtoService.proto&#8221; we can run the ProtoGen.exe command-line tool we downloaded with NuGet earlier.  ProtoGen will automatically detect that it has been given a &#8220;.proto&#8221; text file and run the protoc.exe compiler from the same directory as ProtoGen.exe.  If you&#8217;re including files and setting options defined by google or the csharp port you will need to have the google directory from {Package}\content\protos copied to the location of your proto files.  Since this is a stand-alone proto and not including others we don&#8217;t need to create a directory structure.  Ready to build, let&#8217;s run ProtoGen now to create our generated code:</p>
<pre>
C:\Projects\ProtoService>Google.ProtocolBuffers\tools\ProtoGen.exe -service_generator_type=IRPCDISPATCH ProtoService.proto
</pre>
<p>The service_generator_type tells the ProtoGen what type of service classes/interfaces we are interested in, the value IRPCDISPATCH generates both interfaces and client/server stubs.  There are lots of other options both for protoc and protogen, running ProtoGen.exe /? will list all of them.  In addition this can be done directly from VStudio 2005~2010 via the <a href="http://help.csharptest.net/?CmdToolOverview.html">CmdTool.exe</a> integration <a href="http://help.csharptest.net/?CmdToolIntegrateProtoGen.html">described here for ProtoGen.exe</a>.</p>
<p><strong>Project References</strong><br />
Now we should find that ProtoService.cs has been created for us.  Let&#8217;s now add this generated source file to our project and reference the two assemblies we need.  Both of our required dependencies are located in Google.ProtocolBuffers\lib\net35, called Google.ProtocolBuffers.dll and Google.ProtocolBuffers.Serialization.dll.  After we have added the two references and the generated source file we should able to compile the project.  Note: if you get some warnings about CLSCompliant you can either attribute your project as CLSCompliant(true) or add the option &#8220;-cls_compliance=false&#8221; to the protogen.exe command line above.  </p>
<p><strong>Service Implementation</strong><br />
The first code we will write will be our service implementation.  The code generator has defined an interface for us to implement called ISearchService.  Let&#8217;s stub out that implementation now in a class called ServiceImplementation:</p>
<pre class="brush:csharp">
class ServiceImplmentation : ISearchService
{
    public SearchResponse Search(SearchRequest searchRequest)
    {
        // Create the response builder
        return SearchResponse.CreateBuilder()
            // Add a result to the response
            .AddResult(
                SearchResponse.Types.Result.CreateBuilder()
                .SetUrl("http://example.com")
                .Build()
                )
            // Build the result message
            .Build();
    }
}
</pre>
<p>Of course you&#8217;re service implementation will be a lot more complicated than this, but this will suffice for demonstration purposes.  Go ahead and build your project and then let&#8217;s move on to creating the IIS handler.</p>
<p><strong>IIS Handler</strong><br />
Our <a href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandler.aspx" target="_blank">IHttpHandler</a> implementation could be reduced to a single line call to <a href="http://help.protobuffers.net/?Google.ProtocolBuffers.Serialization~Google.ProtocolBuffers.Extensions~HttpCallMethod.html" target="_blank">HttpCallMethod</a> if we chose.  The following implementation adds handling of GET requests by parsing of uri query string values and some rudimentary exception handling.</p>
<p>Uri encoded requests are allowed for simple messages (non-nested simple types) and allow us to test right from a browser.  This also allows javascript to use a GET request and pass parameters.  The MIME type constant &#8216;ContentFormUrlEncoded&#8217; is defined as &#8220;application/x-www-form-urlencoded&#8221; which is also the mime type used by HTML forms.  This means that web clients can also simply post an HTML form to the service to execute a method, the constraint of simple types remains for forms as well.  </p>
<pre class="brush:csharp">
class ServiceHandler : IHttpHandler
{
    public bool IsReusable { get { return true; } }
    public void ProcessRequest(HttpContext context)
    {
        MessageFormatOptions defaultOptions = new MessageFormatOptions();
        // Capture the request stream and content-type
        Stream requestStream = context.Request.InputStream;
        string requestType = context.Request.ContentType;

        if (context.Request.HttpMethod == "GET")
        {
            // If the call is an HTTP/GET, we will use URI encoding and the query string
            requestType = MessageFormatOptions.ContentFormUrlEncoded;
            requestStream = new MemoryStream(Encoding.UTF8.GetBytes(context.Request.Url.Query));
        }

        // Parse the HTTP accept header to determine the content-type of the response
        context.Response.ContentType = (context.Request.AcceptTypes ?? new string[0])
                                       .Select(m => m.Split(';')[0])
                                       .FirstOrDefault(m => defaultOptions.MimeInputTypes.ContainsKey(m))
                                       ?? defaultOptions.DefaultContentType;

        // Create the server-side stub to dispatch the call by method name
        using (IRpcServerStub stub = new SearchService.ServerStub(new ServiceImplmentation()))
        {
            try
            {
                // The URI's last path segment will be used for the method name
                string[] path = context.Request.Url.Segments;
                // Use the extension method defined in Google.ProtocolBuffers.Extensions to process
                // the request and write the response back to the client.
                stub.HttpCallMethod(
                        path[path.Length - 1],
                        defaultOptions,
                        requestType,
                        requestStream,
                        context.Response.ContentType,
                        context.Response.OutputStream
                    );
            }
            catch(Exception error)
            {
                // If something fails we will create an ErrorResult and serialze it with the requested
                // content-type obtained earlier while returning an HTTP 500 error.
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                ErrorResult.CreateBuilder()
                    .SetErrorText(error.Message)
                    .Build()
                    .WriteTo(defaultOptions, context.Response.ContentType, context.Response.OutputStream);
            }
        }
    }
}</pre>
<p><strong>IIS Handler Configuration</strong><br />
The IIS 7x handler configuration is very straight-forward.  We are binding the path to be a &#8216;child&#8217; of our service description proto file &#8220;ProtoService.proto&#8221;.  This, combined with the mimeMap below, allows the user to discover our service definition so that they can interact with it.  So it&#8217;s time to get working, build the project and update the web.config with the following:</p>
<pre class="brush:xml">
  &lt;system.webServer>
    &lt;staticContent>
      &lt;mimeMap fileExtension=".proto" mimeType="text/plain"/>
    &lt;/staticContent>
    &lt;handlers>
      &lt;add name="SearchService" preCondition="integratedMode" verb="GET,POST" path="/ProtoService.proto/*"
           type="ProtoService.ServiceHandler, ProtoService, Version=1.0, Culture=neutral" />
    &lt;/handlers>
  &lt;/system.webServer>
</pre>
<p><strong>Getting Results</strong><br />
Make sure you are running in IIS, this will not work in Cassini.  Open up your browser (NOT IE) and enter the URL: <a href="http://localhost/protoservice.proto/Search?query=asdf" target="_blank">http://localhost/protoservice.proto/Search?query=asdf</a> You should see the following XML response:</p>
<pre class="brush:xml">
&lt;root>
  &lt;result>
    &lt;url>http://example.com&lt;/url>
  &lt;/result>
&lt;/root>
</pre>
<p>If you type something that doesn&#8217;t make sense, or generates an error, (ie. http://localhost/protoservice.proto/BadMethodName) you will see an error message like this:</p>
<pre class="brush:xml">
&lt;root>
&lt;error_text>Method 'ProtoService.ISearchService.BadMethodName' not found.&lt;/error_text>
&lt;/root>
</pre>
<p><strong>Client Proxy</strong><br />
Now that we have a working service, building a simple client proxy for C# binary protobuffers is really easy.  First we need an implementation of the client proxy dispatch interface, <a href="http://help.protobuffers.net/?Google.ProtocolBuffers~Google.ProtocolBuffers.IRpcDispatch_members.html" target="_blank">IRpcDispatch</a>.  I&#8217;m going to use the <a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx" target="_blank">WebClient</a> here simply because it&#8217;s easy; however, production systems more often use the <a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx" target="_blank">HttpWebRequest</a> class.</p>
<pre class="brush:csharp">
class HttpProxy : IRpcDispatch
{
    readonly Uri _baseUri;
    public HttpProxy(Uri baseUri) { _baseUri = baseUri; }

    public TMessage CallMethod&lt;TMessage, TBuilder>(string method, IMessageLite request, IBuilderLite&lt;TMessage, TBuilder> response)
        where TMessage : IMessageLite&lt;TMessage, TBuilder>
        where TBuilder : IBuilderLite&lt;TMessage, TBuilder>
    {
        WebClient client = new WebClient();
        client.Headers[HttpRequestHeader.ContentType] = MessageFormatOptions.ContentTypeProtoBuffer;
        client.Headers[HttpRequestHeader.Accept] = MessageFormatOptions.ContentTypeProtoBuffer;
        byte[] result = client.UploadData(new Uri(_baseUri, method), request.ToByteArray());
        return response.MergeFrom(result).Build();
    }
}
</pre>
<p>Once we have this defined we can now instantiate and call the proxy.</p>
<pre class="brush:csharp">
SearchRequest result;
SearchResponse result;
using(SearchService svc = new SearchService(new HttpProxy(new Uri("http://localhost/protoservice.proto/"))))
    result = svc.Search(SearchRequest.CreateBuilder().SetQuery("bar").Build());

foreach (SearchResponse.Types.Result r in result.ResultList)
    Console.WriteLine(r.Url);
</pre>
<p><strong>Alternative Client Formats</strong><br />
This proxy uses protobuffers but it could easily be adapted to use json or xml just by changing the content-type and and accept headers and serializing accordingly.  To Serialize a protobuffer message as xml or json the following extensions can be used:</p>
<pre class="brush:csharp">
//XML
string xmlResult = client.UploadString(new Uri(_baseUri, method), request.ToXml());
return response.MergeFromXml(
    System.Xml.XmlReader.Create(new StringReader(xmlResult)))
    .Build();

//JSON
string jsonResult = client.UploadString(new Uri(_baseUri, method), request.ToJson());
return response.MergeFromJson(jsonResult).Build();
</pre>
<p>Lastly there are two more extension methods that can do this by simply providing a stream and a mime-type.  This is demonstrated above in the catch block of our http handler.  Here are the extension method prototypes that can be used:</p>
<pre class="brush:csharp">
public static void WriteTo(this IMessageLite message, MessageFormatOptions options, string contentType,
                           Stream output);

public static TBuilder MergeFrom&lt;TBuilder>(this TBuilder builder, MessageFormatOptions options,
                                           string contentType, Stream input) where TBuilder : IBuilderLite;
</pre>
<p><strong>Closing Remarks</strong><br />
I&#8217;m very biased here since I wrote most of this capability; however, I am constantly amazed at how easy protobuffers are to use.  Google&#8217;s Protocol Buffers are very powerful and extremely fast.  I&#8217;ve been using them for two years now and I can&#8217;t imagine writing a serialization or remoting solution without them.</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Managed anti-debugging &#8211; how to prevent users from attaching a debugger</title>
		<link>http://csharptest.net/1051/managed-anti-debugging-how-to-prevent-users-from-attaching-a-debugger/</link>
		<comments>http://csharptest.net/1051/managed-anti-debugging-how-to-prevent-users-from-attaching-a-debugger/</comments>
		<pubDate>Sun, 20 Nov 2011 04:43:39 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[Other]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1051</guid>
		<description><![CDATA[Keeping in line with our previous post &#8220;How to prevent users from killing your service or process&#8221; and continuing down the road of securing our service this post looks at the prevention of debugging. There are a lot of anti-debugging posts out there, most of them written in C++ and assembly and are therefor of <a href='http://csharptest.net/1051/managed-anti-debugging-how-to-prevent-users-from-attaching-a-debugger/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Keeping in line with our previous post &#8220;<a href="http://csharptest.net/?p=1043">How to prevent users from killing your service or process</a>&#8221; and continuing down the road of securing our service this post looks at the prevention of debugging.  There are a lot of anti-debugging posts out there, most of them written in C++ and assembly and are therefor of little use to the managed world.  One of the most complete I&#8217;ve seen is from Symantec &#8220;<a href="http://www.symantec.com/connect/articles/windows-anti-debug-reference">Windows Anti-Debug Reference | Symantec Connect Community</a>&#8221; and an interesting one on stackoverflow &#8220;<a href="http://stackoverflow.com/questions/573115">What is your favourite anti-debugging trick?</a>&#8220;.  These both fall short on providing any solution that is both easy to implement and built with managed code.  </p>
<p>Let&#8217;s face it nothing is going to be bullet proof in this arena, and certainly not the solution I&#8217;m going to suggest.  Yet it is easy and will prevent someone from attaching a debugger after the program is running.  I&#8217;m really not concerned with trying to prevent a debug-session from startup.  Why?  Because you can&#8217;t.  The debugger can jump past any code you have that tries to verify that a debugger is not currently active.  Besides this it provides me very little value, I want to protect an actively running process (a service).  If the user has the rights to stop it in the first place (i.e. they are an admin) then there isn&#8217;t anything I can do to stop them from debugging.  </p>
<p>What I want is to prevent someone from attaching a debugger to this service to protect potentially sensitive information.  How?  Well as it turns out the easiest way to prevent a debug session from starting is with a debug session.  So what we need is to debug ourselves!  Oh wait you can&#8217;t :( but what you can do is easily spawn another process to debug this process while we debug that new process.  This reciprocal or circular debug session will prevent either process from being debugged.  Further, any attempt to kill either process will immediately terminate the other process thus thwarting an effort to kill one debugger so that you can attach one.</p>
<p>To accomplish this in managed code we have two choices, either using the managed debugger API or the native win32 debugger API.  It turns out that the managed debugger is excessively complicated and requires an extraordinary amount of COM code to pull it off (<a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&#038;id=19621" target="_blank">see the mdbg sample</a>)  So I chose to go with a raw win32 debug session and see if we could pull that off easily with a few PInvoke calls.  Sure enough, this is really easy.</p>
<p>So let&#8217;s jump in and take a look at the debugging API calls we are going to need&#8230;</p>
<pre class="brush:csharp">
const int DBG_CONTINUE = 0x00010002;
const int DBG_EXCEPTION_NOT_HANDLED = unchecked((int)0x80010001);

enum DebugEventType : int
{
    CREATE_PROCESS_DEBUG_EVENT = 3, //Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure.
    CREATE_THREAD_DEBUG_EVENT = 2, //Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure.
    EXCEPTION_DEBUG_EVENT = 1, //Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure.
    EXIT_PROCESS_DEBUG_EVENT = 5, //Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure.
    EXIT_THREAD_DEBUG_EVENT = 4, //Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure.
    LOAD_DLL_DEBUG_EVENT = 6, //Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure.
    OUTPUT_DEBUG_STRING_EVENT = 8, //Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure.
    RIP_EVENT = 9, //Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure.
    UNLOAD_DLL_DEBUG_EVENT = 7, //Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure.
}

[StructLayout(LayoutKind.Sequential)]
struct DEBUG_EVENT
{
    [MarshalAs(UnmanagedType.I4)]
    public DebugEventType dwDebugEventCode;
    public int dwProcessId;
    public int dwThreadId;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
    public byte[] bytes;
}

[DllImport("Kernel32.dll", SetLastError = true)]
static extern bool DebugActiveProcess(int dwProcessId);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern bool WaitForDebugEvent([Out] out DEBUG_EVENT lpDebugEvent, int dwMilliseconds);
[DllImport("Kernel32.dll", SetLastError = true)]
static extern bool ContinueDebugEvent(int dwProcessId, int dwThreadId, int dwContinueStatus);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool IsDebuggerPresent();
</pre>
<p>The structure DEBUG_EVENT above is actually only 96 bytes in total and the bytes 12 to 96 are actually a union.  I did not need any real details about the specifics so I chose to use slam a blob here and not worry about it.  The byte array could be reduced in theory to 84 bytes but I really didn&#8217;t care since we are only going to create a single one of these.  The rest is pretty strait-forward PInvoke junk, nothing fancy.  </p>
<p>Using the methods above to debug a process looks something like the following code:</p>
<pre class="brush:csharp">
// Start a thread to perform the debug loop
new Thread(DebuggerThread) { IsBackground = true, Name = "DebuggerThread" }
    .Start(processId);
// Debugging thread main loop
static void DebuggerThread(object arg)
{
    DEBUG_EVENT evt = new DEBUG_EVENT();
    evt.bytes = new byte[1024];
    // Attach to the process we provided the thread as an argument
    if (!DebugActiveProcess((int)arg))
        throw new Win32Exception();

    while (true)
    {
        // wait for a debug event
        if (!WaitForDebugEvent(out evt, -1))
            throw new Win32Exception();
        // return DBG_CONTINUE for all events but the exception type
        int continueFlag = DBG_CONTINUE;
        if (evt.dwDebugEventCode == DebugEventType.EXCEPTION_DEBUG_EVENT)
            continueFlag = DBG_EXCEPTION_NOT_HANDLED;
        // continue running the debugee
        ContinueDebugEvent(evt.dwProcessId, evt.dwThreadId, continueFlag);
    }
}</pre>
<p>Frankly I had no idea how trivial this was to do.  Once I had this working I was able to quickly build a method that takes my program arguments and detects if it is a parent or child process and act appropriately.  For the child we need only debug our parent process, for the parent we need to both spawn the child and debug it.  Ideally this would be done as a single step since it is possible to start a process as a debugee; however, I didn&#8217;t bother to figure out how to do that.  If you know and don&#8217;t mind sharing please drop a comment.  Since I do know how to start a process and I know how to debug an active process I chose that approach.  It doesn&#8217;t seem like it would be any more or less secure, but I could be wrong on that point.  Anyway the following is what my process start-up looks like&#8230;</p>
<pre class="brush:csharp">
static void Main(string[] args)
{
    NativeDebug.DebugSelf(args);
    ... stuff ...
}
public static void DebugSelf(string[] args)
{
    Process self = Process.GetCurrentProcess();
    // Child process?
    if (args.Length == 2 &#038;&#038; args[0] == "--debug-attach")
    {
        int owner = int.Parse(args[1]);
        Process pdbg = Process.GetProcessById(owner);
        new Thread(KillOnExit) { IsBackground = true, Name = "KillOnExit" }.Start(pdbg);
        //Wait for our parent to debug us
        WaitForDebugger();
        //Start debugging our parent process
        DebuggerThread(owner);
        //Now is a good time to die.
        Environment.Exit(1);
    }
    else // else we are the Parent process...
    {
        ProcessStartInfo psi =
            new ProcessStartInfo(Environment.GetCommandLineArgs()[0], "--debug-attach " + self.Id)
                {
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    ErrorDialog = false,
                    WindowStyle = ProcessWindowStyle.Hidden
                };
        // Start the child process
        Process pdbg = Process.Start(psi);
        if (pdbg == null)
            throw new ApplicationException("Unable to debug");
        // Monitor the child process
        new Thread(KillOnExit) {IsBackground = true, Name = "KillOnExit"}.Start(pdbg);
        // Debug the child process
        new Thread(DebuggerThread) {IsBackground = true, Name = "DebuggerThread"}.Start(pdbg.Id);
        // Wait for the child to debug us
        WaitForDebugger();
    }
}
static void WaitForDebugger()
{
    DateTime start = DateTime.Now;
    while (!IsDebuggerPresent())
    {
        if ((DateTime.Now - start).TotalMinutes > 1)
            throw new TimeoutException("Debug operation timeout.");
        Thread.Sleep(1);
    }
}
static void KillOnExit(object process)
{
    ((Process)process).WaitForExit();
    Environment.Exit(1);
}
</pre>
<p>So we&#8217;ve written about 100 lines of code or so and spent almost no time at all getting it up and running, a good ROI for this kind of stuff.  It worked quite well even running under the NETWORK SERVICE account as a service.  It certainly stops me from debugging it although I&#8217;m certainly not what I&#8217;d call an accomplished hacker.  Given the time and effort to put this together I&#8217;d have to call it a win for active debugger prevention.  The down side of course is that there are now two processes running and trying to tell them apart is difficult at first launch.  </p>
<p>If you&#8217;re going to do something like this, I would suggest adding an &#8216;if (!IsDebuggerPresent())&#8217; to the else clause of our DebugSelf method above.  This would allow you to launch with a debugger but not to attach one at a later time.  Have fun with it and as with any code on this site, &#8220;Don&#8217;t blame me&#8221;.  I didn&#8217;t make you use it ;)  </p>
<p>My own intentions for this are to make a reasonable effort to secure a service running in a controlled but insecure environment.  I would never ship something like this to a customer and hope you would not either.  Preventing a consumer from accessing software they purchased is not at all what I&#8217;m after.  IMHO if information is on their machine it is theirs to debug and view all they want. </p>
<p>One more thing, in case you are wondering this was not my idea.  I read about doing this in a security article some years ago but I can&#8217;t seem to locate it.</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to prevent users from killing your service or process</title>
		<link>http://csharptest.net/1043/how-to-prevent-users-from-killing-your-service-process/</link>
		<comments>http://csharptest.net/1043/how-to-prevent-users-from-killing-your-service-process/</comments>
		<pubDate>Sat, 19 Nov 2011 22:53:45 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[Other]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=1043</guid>
		<description><![CDATA[Before I say another word, I have read &#8220;The arms race between programs and users&#8221; and wholeheartedly agree. You can not, and should not, attempt to stop an Administrator from killing your process or stopping your service. That is not what we are trying to do here, we are trying to prevent Joe User from <a href='http://csharptest.net/1043/how-to-prevent-users-from-killing-your-service-process/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Before I say another word, I have read &#8220;<a href="http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx" target="_blank">The arms race between programs and users</a>&#8221; and wholeheartedly agree.  You can not, and should not, attempt to stop an Administrator from killing your process or stopping your service.  That is not what we are trying to do here, we are trying to prevent Joe User from disrupting our process.</p>
<p>So let&#8217;s get started, to do this we want to adjust our process&#8217; access control list.  The individual rights we can grant and deny are discussed on MSDN in the articled titled &#8220;<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx" target="_blank">Process Security and Access Rights</a>&#8220;.  Though most of that article is about creating a process with specific rights, in this case we want to modify the rights of our current process.  To do this we are going to PInvoke <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa446641(v=vs.85).aspx" target="_blank">GetKernelObjectSecurity</a> to obtain the DACL (Discretionary Access Control List), modify it using the <a href="http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.rawsecuritydescriptor.aspx" target="_blank">RawSecurityDescriptor</a>, and finally write it back using the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa379578(v=vs.85).aspx" target="_blank">SetKernelObjectSecurity</a> API.  This should be somewhat familiar to those of you that followed that part of building our service.</p>
<p><strong>Step 1 &#8211; Obtaining the process DACL</strong></p>
<pre class="brush:csharp">[DllImport("advapi32.dll", SetLastError = true)]
static extern bool GetKernelObjectSecurity(IntPtr Handle, int securityInformation, [Out] byte[] pSecurityDescriptor,
                                           uint nLength, out uint lpnLengthNeeded);

public static RawSecurityDescriptor GetProcessSecurityDescriptor(IntPtr processHandle)
{
    const int DACL_SECURITY_INFORMATION = 0x00000004;
    byte[] psd = new byte[0];
    uint bufSizeNeeded;
    // Call with 0 size to obtain the actual size needed in bufSizeNeeded
    GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, psd, 0, out bufSizeNeeded);
    if (bufSizeNeeded &lt; 0 || bufSizeNeeded > short.MaxValue)
        throw new Win32Exception();
    // Allocate the required bytes and obtain the DACL
    if (!GetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION,
                                        psd = new byte[bufSizeNeeded], bufSizeNeeded, out bufSizeNeeded))
        throw new Win32Exception();
    // Use the RawSecurityDescriptor class from System.Security.AccessControl to parse the bytes:
    return new RawSecurityDescriptor(psd, 0);
}</pre>
<p>And you thought that was going to be hard?  Of course we also need to be able to save the DACL.  So&#8230;</p>
<p><strong>Part 2 &#8211; Updating the process DACL</strong></p>
<pre class="brush:csharp">[DllImport("advapi32.dll", SetLastError = true)]
static extern bool SetKernelObjectSecurity(IntPtr Handle, int securityInformation, [In] byte[] pSecurityDescriptor);

public static void SetProcessSecurityDescriptor(IntPtr processHandle, RawSecurityDescriptor dacl)
{
    const int DACL_SECURITY_INFORMATION = 0x00000004;
    byte[] rawsd = new byte[dacl.BinaryLength];
    dacl.GetBinaryForm(rawsd, 0);
    if (!SetKernelObjectSecurity(processHandle, DACL_SECURITY_INFORMATION, rawsd))
        throw new Win32Exception();
}</pre>
<p>Cool, that was easy, so we are ready now right?  Not quite, we still need to get the process handle.  A simple thing for our own process:</p>
<p><strong>Part 3 &#8211; Getting the current process</strong></p>
<pre class="brush:csharp">[DllImport("kernel32.dll")]
public static extern IntPtr GetCurrentProcess();</pre>
<p>It just gets easier and easier.  Since this is the current process there (AFAIK) is not any reason to duplicate handle and request additional permissions.  This handle should have access to do anything.  So the only thing left before we can modify the permissions is to define what those permissions are.</p>
<p><strong>Part 4 &#8211; Process access rights</strong></p>
<pre class="brush:csharp">[Flags]
public enum ProcessAccessRights
{
    PROCESS_CREATE_PROCESS =0x0080, //	Required to create a process.
    PROCESS_CREATE_THREAD = 0x0002, //	Required to create a thread.
    PROCESS_DUP_HANDLE = 0x0040, //	Required to duplicate a handle using DuplicateHandle.
    PROCESS_QUERY_INFORMATION = 0x0400, //	Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob).
    PROCESS_QUERY_LIMITED_INFORMATION = 0x1000, //	Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION. Windows Server 2003 and Windows XP/2000:  This access right is not supported.
    PROCESS_SET_INFORMATION = 0x0200, //	Required to set certain information about a process, such as its priority class (see SetPriorityClass).
    PROCESS_SET_QUOTA = 0x0100, //	Required to set memory limits using SetProcessWorkingSetSize.
    PROCESS_SUSPEND_RESUME = 0x0800, //	Required to suspend or resume a process.
    PROCESS_TERMINATE = 0x0001, //	Required to terminate a process using TerminateProcess.
    PROCESS_VM_OPERATION = 0x0008, //	Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).
    PROCESS_VM_READ = 0x0010, //	Required to read memory in a process using ReadProcessMemory.
    PROCESS_VM_WRITE = 0x0020, //	Required to write to memory in a process using WriteProcessMemory.
    DELETE = 0x00010000, //	Required to delete the object.
    READ_CONTROL = 0x00020000, //	Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right.
    SYNCHRONIZE = 0x00100000, //	The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state.
    WRITE_DAC = 0x00040000, //	Required to modify the DACL in the security descriptor for the object.
    WRITE_OWNER = 0x00080000, //	Required to change the owner in the security descriptor for the object.
    STANDARD_RIGHTS_REQUIRED = 0x000f0000,
    PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF),//	All possible access rights for a process object.
}</pre>
<p><strong>Part 5 &#8211; Put it all together</strong></p>
<pre class="brush:csharp">// Get the current process handle
IntPtr hProcess = GetCurrentProcess();
// Read the DACL
var dacl = GetProcessSecurityDescriptor(hProcess);
// Insert the new ACE
dacl.DiscretionaryAcl.InsertAce(
    0,
    new CommonAce(
        AceFlags.None,
        AceQualifier.AccessDenied,
        (int)ProcessAccessRights.PROCESS_ALL_ACCESS,
        new SecurityIdentifier(WellKnownSidType.WorldSid, null),
        false,
        null)
);
// Save the DACL
SetProcessSecurityDescriptor(hProcess, dacl);</pre>
<p>The ace we&#8217;ve added now will try to deny access to the &#8220;Everyone&#8221; group (aka WorldSid) to do anything with our process.  We need not fear that we are interrupting an administrator&#8217;s ability to perform any action they desire.  They will have any access required that&#8217;s why we call them administrators :)  As I said in the beginning, we are not trying to stop Administrators, we just want to make sure they are an administrator if they plan to modify or kill this process.</p>
<p>We could of course be more discrete about the rights we are trying to deny, that is entirely up to you.</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a Windows Service &#8211; Part 7: Finishing touches</title>
		<link>http://csharptest.net/990/building-a-windows-service-part-7-finishing-touches/</link>
		<comments>http://csharptest.net/990/building-a-windows-service-part-7-finishing-touches/</comments>
		<pubDate>Sat, 19 Nov 2011 16:07:00 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Home]]></category>
		<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=990</guid>
		<description><![CDATA[Continued from &#8220;Building a Windows Service – Part 6: Adding resources and event logging&#8221; So let&#8217;s recap our goals for this project: Building a service that can also be used from the console Proper event logging of service startup/shutdown and other activities Allowing multiple instances by using command-line arguments Self installation of service and event <a href='http://csharptest.net/990/building-a-windows-service-part-7-finishing-touches/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Continued from &#8220;<a href="http://csharptest.net/?p=977">Building a Windows Service – Part 6: Adding resources and event logging</a>&#8221;</p>
<p>So let&#8217;s recap our goals for this project:</p>
<ul>
<li>Building a service that can also be used from the console</li>
<li>Proper event logging of service startup/shutdown and other activities</li>
<li>Allowing multiple instances by using command-line arguments</li>
<li>Self installation of service and event log</li>
<li>Proper event logging of service exceptions and errors</li>
<li>Controlling of start-up, shutdown and restart options</li>
<li>Handling custom service commands, power, and session events</li>
<li>Customizing service security and access control</li>
</ul>
<p>Yep, we are on the mark there and have demonstrated most of these in the past few posts. The goal not stated directly has always been to to create a new project template. We had a bit of cleaning up to do before we could deal with that. I&#8217;m not going to cover this clean up in the same level of detail as before, but here are a few words about how this has changed from the previous posts:</p>
<ol>
<li>I&#8217;ve added an application icon and manifest. This brought to light that the generator for the win32 resources was not preserving the manifest, nor was it correctly locating the icon when I moved the resources file. To get this working I&#8217;ve built a custom version of the CSharpTest.Net.Generators executable.</li>
<li>For all the good it does, I&#8217;ve added an UnhandledException event listener on the AppDomain to attempt to log the exception. As you probably know this is unreliable at best ;)</li>
<li>I&#8217;ve split all the resources into three parts, messages that are written, exceptions that log, and normal non-logging string resources. These have been to a Resources folder and all resource/event specific stuff is now located there.</li>
<li>The remainder of the service stub class, &#8220;ServiceImplementation&#8221; has been filled out to include power and session events, custom commands, etc. The appropriate logging and plumbing has been introduced into the ServiceProcess class to support these new methods.</li>
<li>There are a couple of other small changes and always bugs, and I&#8217;ve had to fix a few from the previous posts.</li>
</ol>
<p>The end result is a clean easy to use project template for Visual Studio 2008. This can easily be upgraded to 2010 if you desire. The project is currently using the 2.0 Framework to allow the greatest flexibility, but obviously once you create the project from the template it can be changed.</p>
<table>
<tbody>
<tr>
<td width="75"><img src="http://csharptest.net/images/winzip.png" alt="zip" width="50" height="50" /></td>
<td><a title="/downloads/projects/ServiceTemplate.zip" href="http://csharptest.net/downloads/projects/ServiceTemplate.zip">Download the Visual Studio Service Project Template</a><br />
To use the template place it in the following path for 2008:<br />
<span style="font-family:courier new; courier">%UserProfile%\My Documents\Visual Studio 2008\Templates\ProjectTemplates\Visual C#</span>
</td>
</tr>
</tbody>
</table>
<p>Once installed, create a new project, locate the template &#8220;ServiceTemplate&#8221; and create a project.  Since the project name is used heavily throughout the template you should avoid names that contain non-alpha-numeric text or are longer than 64 characters.  You can always rename the project file, assembly, and default namespace later, but start with a simple name.  After the project has been created there are two things to do from the command line.  Assuming a working directory at the root of the project the following commands should be run:</p>
<pre>C:\Projects\MyService> Tools\CmdTool.exe register
C:\Projects\MyService> Tools\CmdTool.exe build MyService.csproj
Generating C:\Projects\MyService\Resources\Exceptions.resx
Generating C:\Projects\MyService\Resources\FormatString.resx
Generating C:\Projects\MyService\Resources\Messages.resx
</pre>
<p>Now you can build and run the project with the &#8216;install&#8217; command and away you go.  Modify the ServiceImplementation class to provide the service implementation.  Adjust the default IsolateDomain, and ShadowCopy settings to your desired defaults.  Don&#8217;t forget if you want to debug service start-up you can run the command &#8220;start {servicename} DEBUG!&#8221; and, if the service is not running, a debug break-point will be triggered.</p>
<p>It&#8217;s not often I have to create a windows service, yet each time it takes me several days to work all this out.  I hope this will save you some time as well, enjoy.</p>
<p>
PS: If you&#8217;ve missed any of the previous posts, here they are:</p>
<ul>
<li><a href="http://csharptest.net/?p=837">Building a Windows Service – Part 1: Getting started</a></li>
<li><a href="http://csharptest.net/?p=850">Building a Windows Service – Part 2: Adding a Service to a Console Application</a></li>
<li><a href="http://csharptest.net/?p=858">Building a Windows Service – Part 3: Creating a Service Installer</a></li>
<li><a href="http://csharptest.net/?p=955">Building a Windows Service – Part 4: Extending the Service Installer</a></li>
<li><a href="http://csharptest.net/?p=968">Building a Windows Service – Part 5: Adding command-line installation</a></li>
<li><a href="http://csharptest.net/?p=977">Building a Windows Service – Part 6: Adding resources and event logging</a></li>
<li><a href="http://csharptest.net/?p=990">Building a Windows Service &#8211; Part 7: Finishing touches</a></li>
</ul>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a Windows Service – Part 6: Adding resources and event logging</title>
		<link>http://csharptest.net/977/building-a-windows-service-part-6-adding-resources-and-event-logging/</link>
		<comments>http://csharptest.net/977/building-a-windows-service-part-6-adding-resources-and-event-logging/</comments>
		<pubDate>Sat, 19 Nov 2011 16:06:45 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://csharptest.net/?p=977</guid>
		<description><![CDATA[Continued from &#8220;Building a Windows Service – Part 5: Adding command-line installation&#8221; So we have a working service it&#8217;s time to start adding some logging. Proper event logging is critical to monitoring services so we are not going to use .NET&#8217;s typical excuse for events. Rather we are going to build a &#8216;real&#8217; message dll <a href='http://csharptest.net/977/building-a-windows-service-part-6-adding-resources-and-event-logging/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Continued from &#8220;<a href="http://csharptest.net/?p=968">Building a Windows Service – Part 5: Adding command-line installation</a>&#8221;</p>
<p>So we have a working service it&#8217;s time to start adding some logging.  Proper event logging is critical to monitoring services so we are not going to use .NET&#8217;s typical excuse for events.  Rather we are going to build a &#8216;real&#8217; message dll from our server, register it as a message event source, and have a real event log.  Sounds crazy I know, but all the hard work has already been done by <a href="http://help.csharptest.net/?CSharpTest.Net.GeneratorsOverview.html" target="_blank">CSharpTest.Net.Generators.exe</a>.  We are also going to use <a href="http://help.csharptest.net/?CmdToolOverview.html" target="_blank">CmdTool.exe</a> to integrate integrate into Visual Studio.</p>
<p>The first thing we are going to need to do is to pull three binaries from my library (<a href="http://code.google.com/p/csharptest-net/downloads/list" title="CSharpTest.Net Library Downloads" target="_blank">available here</a>).  The three we are after are CmdTool.exe, CSharpTest.Net.Generators.exe, and CSharpTest.Net.Library.dll which the Generators assembly depends upon.  I&#8217;m going to just create a folder in the project directory called &#8220;Tools&#8221; and add these files there.  If you&#8217;ve never used CmdTool before you will need to register it by running &#8220;CmdTool.exe Register&#8221; from an administrative command prompt.</p>
<p><strong>Creating CmdTool.config</strong><br />
To use CmdTool for our resources we need a configuration file that tells it what to do.  This is fairly trivial and is explained in some detailed here: &#8220;<a href="http://help.csharptest.net/?CmdToolConfiguration.html" target="_blank">CmdTool.exe Configuration</a>&#8220;.  So we are going to copy/paste <a href="http://help.csharptest.net/?CmdToolIntegrationResX.html" target="_blank">this default configuration</a> and save it into a file called &#8220;CmdTool.config&#8221; in the root of our project.  Here is our configuration file:</p>
<pre class="brush:xml">
&lt;?xml version="1.0" encoding="utf-8" ?>
&lt;CmdTool xsi:noNamespaceSchemaLocation="http://csharptest.net/downloads/schema/CmdTool.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  &lt;match filespec="*.resx">
    &lt;generator debug="false">
      &lt;execute exe=".\Tools\CSharpTest.Net.Generators.exe" />
      &lt;arg value="ResX"/>
      &lt;arg value="-input=$(InputPath)"/>
      &lt;arg value="-namespace=$(Namespace)"/>
      &lt;arg value="-class=$(ClassName)"/>
      &lt;arg value="-public=true"/>
      &lt;arg value="-partial=true"/>
      &lt;arg value="-test=true"/>
      &lt;arg value="-sealed=true"/>
      &lt;arg value="-base=System.ApplicationException"/>
      &lt;arg value="-rxns=$(DefaultNamespace)"/>

      &lt;std-output extension=".Designer.cs"/>
    &lt;/generator>
  &lt;/match>
&lt;/CmdTool>
</pre>
<p><img src="http://csharptest.net/wp-content/uploads/2011/11/SolutionExplore1.png" alt="" title="SolutionExplore1" width="341" height="376" class="alignright size-full wp-image-981" /><br />
Once our configuration is there we need to create standard Resources.resx file just as you always would.  In order for CmdTool to find the configuration file above it must be in the same directory, or a parent directory, of the resource file.  I&#8217;m just adding the Resources.resx file in the root of the project.</p>
<p>After we&#8217;ve added the Resources.resx file to the project we now need to modify the &#8220;Custom Tool&#8221; property for the solution item.  Right-click on the resx file and select &#8220;Properties&#8221;.  You should the option there, just type &#8216;CmdTool&#8217; in the value next to Custom Tool.  Make sure you&#8217;ve registered CmdTool or you will get an error.  The end result should look like this:<br />
<img src="http://csharptest.net/wp-content/uploads/2011/11/CustomToolSetting.png" alt="" title="CustomToolSetting" width="341" height="170" class="alignnone size-full wp-image-983" /></p>
<p>Once this is changed, you&#8217;re output window should display &#8220;Generating C:\{some path}\Resources.resx&#8221; with the full path to the location of the resx file.  Once that is working we already have a lot of bang for our buck.  Creating a resource string like &#8220;String1&#8243;, &#8220;{0}&#8221; will now create a static method with the signature &#8216;string Resources.String1(object _0)&#8217;.  That is neat, we can even create exceptions just by renaming &#8220;String1&#8243; to &#8220;String1Exception&#8221; and presto-magic happens and you have a complete exception class.  I can&#8217;t live without this thing, I&#8217;ve used it sparingly in the open but I use it extensively in my day job as well as private projects.  We have over 250 custom exceptions, each have a unique HRESULT that can be written to the Event Log and monitored.  This is what we are after, Adding support for the event logging part.</p>
<p>Before we go any farther with this you should be very familiar with <a href="http://msdn.microsoft.com/en-us/library/bb401631.aspx" target="_blank">what is an HRESULT</a>, what it&#8217;s composite parts are, and what their constraints are.  Most of this is documented in the help for <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd996906(v=vs.85).aspx" target="_blank">Message Text Files</a> which is exactly what we are going to be generating.</p>
<p>So let&#8217;s get started turning our resx into an event log writer.  Step 1, we need to add some information, the easiest way is to just copy/paste the following settings into the &#8220;View Source&#8221; xml view:</p>
<pre class="brush:xml">
  &lt;assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  &lt;data name=".EventCategory" type="System.Int32, mscorlib">
    &lt;value>1&lt;/value>
    &lt;comment>General&lt;/comment>
  &lt;/data>
  &lt;assembly alias="System" name="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  &lt;data name=".EventSource" type="System.Uri, System">
    &lt;value>ServiceTemplate/ServiceTemplate&lt;/value>
  &lt;/data>
  &lt;data name=".AutoLog" type="System.Boolean, mscorlib">
    &lt;value>True&lt;/value>
  &lt;/data>
  &lt;data name=".AutoLogMethod" type="System.Uri, System">
    &lt;value>EventLogging.WriteEvent&lt;/value>
  &lt;/data>
  &lt;data name=".Facility" type="System.Int32, mscorlib">
    &lt;value>256&lt;/value>
    &lt;comment>General&lt;/comment>
  &lt;/data>
  &lt;data name=".HelpLink" type="System.Uri, System">
    &lt;value>http://example.com/?HResult={0:x8}&lt;/value>
  &lt;/data>
  &lt;data name=".NextMessageId" type="System.Int32, mscorlib">
    &lt;value>2&lt;/value>
  &lt;/data>
  &lt;data name=".EventMessageFormat" xml:space="preserve">
    &lt;value>
More Information: {1}
Excpetion Type: {2}
Base Type: {3}
Stack Trace: {4}
{5}&lt;/value>
  &lt;/data>
</pre>
<p>Once the above has been inserted into the resx file you can verify proper behavior by adding any resource string.  When you save the resx file, a Comment value should magically appear, something like &#8220;#MessageId=1&#8243;.  Do not change or remove, these ids should not be reused to avoid confusion with old event logs, the &#8220;.NextMessageId&#8221; controls the next id that will be assigned.  Occasionally, if you&#8217;re custom exception crazy, you may run into source merge conflicts.  At that point you need to make sure all messages have a unique id (it will fail if this is not the case) and that the &#8220;.NextMessageId&#8221; value is higher than all existing ids.  </p>
<p>The &#8220;.AutoLogMethod&#8221; above, &#8220;EventLogging.WriteEvent&#8221; is to allow us to customize the values provided to the event log.  This method is called when either a method is called to format a string, or when an exception is constructed (not thrown).  Because we are augmenting the data in the message with the &#8220;.EventMessageFormat&#8221; above we are required to write this method.  We could simply remove both the &#8220;.AutoLogMethod&#8221; and &#8220;.EventMessageFormat&#8221; and it would just create the log and write it for us.  By customizing this however we can get some fixed fields on our exceptions that will help in monitoring and triggering of alerts.  So here is our custom EventLogging class that will provide some fixed values and also provide a serialized exception as the binary data for the event.</p>
<pre class="brush:csharp">
public class EventLogging
{
    private static readonly Dictionary&lt;string, EventLog> _logs = new Dictionary&lt;string,EventLog>(StringComparer.Ordinal);

    public static void WriteEvent(string eventLog, string eventSource, int category, EventLogEntryType eventType, long eventId, object[] arguments, Exception error)
    {
        EventLog log;
        lock(_logs)
        {
            if(!_logs.TryGetValue(eventLog + '.' + eventSource, out log))
                _logs.Add(eventLog + '.' + eventSource, log = new EventLog(eventLog, ".", eventSource));
        }

        const int fixedCount = 6;
        object[] fullargs = new object[arguments.Length + fixedCount];
        int ix = 0;
        fullargs[ix++] = eventId.ToString("x8");
        fullargs[ix++] = error == null ? null : error.HelpLink;
        fullargs[ix++] = error == null ? null : error.GetType().ToString();
        fullargs[ix++] = error == null ? null : error.GetBaseException().GetType().ToString();
        fullargs[ix++] = error == null ? null : error.StackTrace;
        fullargs[ix++] = new StackTrace(3).ToString();
        Array.Copy(arguments, 0, fullargs, fixedCount, arguments.Length);

        byte[] data = null;
        if (error != null)
        {
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter ser = new BinaryFormatter();
                    ser.Serialize(ms, error);
                    data = ms.ToArray();
                }
            }
            catch { }
        }

        lock(log)
            log.WriteEvent(new EventInstance(eventId, category, eventType), data, fullargs);
    }
}
</pre>
<p>Now we can build again, and the biggest thing left is getting these .NET resources turning into Win32 message resources.  We have two options here, option 1 is to produce a stand-alone message dll.  This can work well in some cases, but I really want an all-in-one approach here so I&#8217;m going to embed the messages into this managed assembly.  File versions, app icons, etc should survive; however, be aware that this tool builds a win32 resource that must later be bound to this project.  To get the generator producing resources we just need to add a pre-build event.</p>
<pre>
$(ProjectDir)Tools\CSharpTest.Net.Generators.exe ProjectResX "$(ProjectPath)" /name=Messages\Resources "/tools=$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows@CurrentInstallFolder)Bin"
</pre>
<p>Here I&#8217;m using the Windows SDK versions of RC.exe and MC.exe which are both required.  You could optionally change the tools path to another location if desired so long as both of these tools exist.  After you define the pre-build event above build the project.  Assuming that worked there is a new directory below the project file called &#8220;Messages&#8221;.  This Messages directory contains two C# files we need to add to this project, Resources.Constants.cs, and Resources.InstallUtil.cs.  Include these by clicking the &#8220;Show All Files&#8221; option and right-click to select &#8220;Include in Project&#8221;.  Now we need to manually add an entry to our project.  First right-click the project and select &#8220;Unload Project&#8221;.  Then right-click again and select &#8220;Edit XXX.csproj&#8221; to view the file in XML.  At the end of the first PropertyGroup element we need to add the following:</p>
<pre class="brush:xml">
  &lt;PropertyGroup>
    ...
    &lt;Win32Resource>$(ProjectDir)Messages\Resources.res&lt;/Win32Resource>
  &lt;/PropertyGroup>
</pre>
<p><img src="http://csharptest.net/wp-content/uploads/2011/11/ExeWithMessages.png" alt="" title="ExeWithMessages" width="335" height="154" class="alignright size-full wp-image-985" /> This can be done in the project properties dialog, however, if you have assigned an icon, manifest, or something it will be erased.  This ensures those properties remain although you will not be able to edit them.  Now rebuild the project.  You can verify that the resources are properly being created by using the File -> Open -> File&#8230; command and selecting the .exe file you just built.  You should see at least the resources depicted to the right.</p>
<p>Now that we&#8217;ve built it we can simply run the .exe file with the &#8216;install&#8217; argument to register both the service and the event log/source.  Before we do that it would be nice to have something in that event log to see.  So let&#8217;s start with adding a resource string for service startup and shutdown.  I&#8217;m going to start with the following messages in the resources.resx file:</p>
<pre>
<table>
<tr>
<td>ServiceStartFailedException</td>
<td>The service {0} failed to start.</td>
<td>#MessageId=1</td>
</tr>
<tr>
<td>ServiceStarted</td>
<td>The service {0} started successfully.</td>
<td>#MessageId=2</td>
</tr>
<tr>
<td>ServiceStopped</td>
<td>The service {0} has stopped.</td>
<td>#MessageId=3</td>
</tr>
</table>
</pre>
<p>Now we are going to update the service process to add the logging:</p>
<pre class="brush:csharp">
protected override void OnStart(string[] args)
{
    try
    {
        OnStop();
        _service = new ServiceImplementation();

        List<string> allarguments = new List</string><string>(_arguments);
        if (args != null &#038;&#038; args.Length > 0)
            allarguments.AddRange(args);

        _service.Start(allarguments);
        Resources.ServiceStarted(ServiceName);
    }
    catch(Exception e)
    {
        throw new ServiceStartFailedException(ServiceName, e);
    }
}

protected override void OnStop()
{
    if (_service == null)
        return;
    try
    {
        _service.Stop();
        _service.Dispose();
        _service = null;
    }
    finally
    {
        Resources.ServiceStopped(ServiceName);
    }
}
</string></pre>
<p>Once this has been added we will build and run the following to install, start, and stop the service.  After that we are going to the Win7/Win2008 command-line tool to export the log to xml so we can peek at the events.</p>
<pre>
ServiceTemplate.exe
net start ServiceTemplate
net stop ServiceTemplate
Wevtutil.exe qe ServiceTemplate /f:RenderedXml
</pre>
<p>The output of Wevtutil.exe should display something like the following:</p>
<pre class="brush:xml">
&lt;Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
  &lt;System>
    &lt;Provider Name='ServiceTemplate'/>
    &lt;EventID Qualifiers='16640'>3&lt;/EventID>
    &lt;Level>4&lt;/Level>
    &lt;Task>1&lt;/Task>
    &lt;Keywords>0x80000000000000&lt;/Keywords>
    &lt;TimeCreated SystemTime='2011-11-17T22:10:47.000000000Z'/>
    &lt;EventRecordID>3&lt;/EventRecordID>
    &lt;Channel>ServiceTemplate&lt;/Channel>
    &lt;Computer>HOSTNAME&lt;/Computer>
    &lt;Security/>
  &lt;/System>
  &lt;EventData>
    &lt;Data>41000003&lt;/Data>
    &lt;Data>&lt;/Data>
    &lt;Data>&lt;/Data>
    &lt;Data>&lt;/Data>
    &lt;Data>&lt;/Data>
    &lt;Data>
      at ServiceTemplate.Service.ServiceProcess.OnStop()
      at System.ServiceProcess.ServiceBase.DeferredStop()
      at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]&amp; outArgs)
      at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
      at System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(Object o)
      at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
      at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
      at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
    &lt;/Data>
    &lt;Data>ServiceTemplate&lt;/Data>
  &lt;/EventData>
  &lt;RenderingInfo Culture='en-US'>
    &lt;Message>
      The service ServiceTemplate has stopped.

      More Information:
      Excpetion Type:
      Base Type:
      Stack Trace:
      at ServiceTemplate.Service.ServiceProcess.OnStop()
      at System.ServiceProcess.ServiceBase.DeferredStop()
      at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]&amp; outArgs)
      at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
      at System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(Object o)
      at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
      at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
      at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
    &lt;/Message>
    &lt;Level>Information&lt;/Level>
    &lt;Task>General&lt;/Task>
    &lt;Opcode>&lt;/Opcode>
    &lt;Channel>&lt;/Channel>
    &lt;Provider>&lt;/Provider>
    &lt;Keywords>
      &lt;Keyword>Classic&lt;/Keyword>
    &lt;/Keywords>
  &lt;/RenderingInfo>
&lt;/Event>
</pre>
<p>Of course you may not want that much detail in your event log for informational messages like this one.  The easiest way to achieve that is to separate the errors from the exceptions by creating another resx file with a different facility id (It can use the same event log/source, or a new one).  For some uses this much detail is more than you want even for exceptions, but it should be obvious enough now how to modify this to prune out the data you don&#8217;t want.  Our service is fairly complete now, it installs, run, logs, etc.  We have a little more work to do in the service behavior itself to support some nice-to-have things like pause/continue, custom messages, etc.  </p>
<p>Continued on &#8220;<a href="http://csharptest.net/?p=990">Building a Windows Service – Part 7: Finishing touches</a>&#8220;</p>
]]></content:encoded>
			
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
