<?xml version="1.0" encoding="UTF-8"?>
<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>BrianMackey.NET</title>
	<atom:link href="http://brianmackey.net/Blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://brianmackey.net/Blog</link>
	<description>.NET and other development adventures</description>
	<lastBuildDate>Thu, 25 Feb 2010 17:39:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Sharing DLLs with multiple programs without versioning issues</title>
		<link>http://brianmackey.net/Blog/?p=249</link>
		<comments>http://brianmackey.net/Blog/?p=249#comments</comments>
		<pubDate>Thu, 25 Feb 2010 03:13:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=249</guid>
		<description><![CDATA[Modern day internal .NET applications combine services, console applications, unit tests, winforms and asp.net web applications. These applications often share Assemblies (DLLs). With so many exe&#8217;s, updating our applications can be quite a challenge. For one thing, Visual Studio is designed to output a program with one top level exe file. Modern day applications consist [...]]]></description>
			<content:encoded><![CDATA[<p>Modern day internal .NET applications combine services, console applications, unit tests, winforms and asp.net web applications.  These applications often share Assemblies (DLLs).  With so many exe&#8217;s, updating our applications can be quite a challenge.  For one thing, Visual Studio is designed to output a program with one top level exe file.  Modern day applications consist of many exe&#8217;s.  Its far too easy for our applications to get out of synch. </p>
<p>If only we could store all our assemblies in a single folder, say &#8220;C:\References&#8221; and have our applications use the assemblies in that folder.  Well we can, but it requires more work than you think.</p>
<p>Let&#8217;s look into a simple example.  [The example is intended to display the core issue with assembly versioning, not give lesson in architecture]  We have two programs:  Program1.exe and Program2.exe.  Both programs reference &#8220;C:\References\BusinessLayer.dll&#8221;.  Two Visual Studio Builds produce:</p>
<p>C:\OutputDirectory\Bin\Debug\Program1.exe<br />
C:\OutputDirectory\Bin\Debug\BusinesLayer.dll (v1.0)<br />
AND<br />
C:\OutputDirectory2\Bin\Debug\Program2.exe<br />
C:\OutputDirectory2\Bin\Debug\BusinesLayer.dll (v1.0)</p>
<p>Now, we update Program2.exe with some new functionality.  We also update BusinessLayer.dll and deploy it to &#8220;C:\References&#8221;.  A Visual Studio Build of Program2 produces:</p>
<p>C:\OutputDirectory2\Bin\Debug\Program2.exe<br />
C:\OutputDirectory2\Bin\Debug\BusinesLayer.dll (v1.1)</p>
<p>Program 1 still looks like:<br />
C:\OutputDirectory\Bin\Debug\Program1.exe<br />
C:\OutputDirectory\Bin\Debug\BusinesLayer.dll (v1.0)</p>
<p>Woops, we are out of sync.  Visual Studio does NOT use our original reference location after the build!  It makes a copy of the file FROM that location.   </p>
<p>Ok, so Team Foundation Server (TFS) setup for Continous Integration can solve this right?  Yes, but TFS requires alot of maintenance and setup for each solution.  There&#8217;s gotto be another way (and cheaper).</p>
<p>MSDN tells us <a href="http://support.microsoft.com/default.aspx/kb/837908">how to load an assembly outside the bin directory</a>.  Our options are GAC, a config file or source code.  </p>
<p>GAC:  Managing assemblies in the GAC can get a little tricky.  Not to mention, Referencing Assemblies from the GAC requires adding registry entries, so lets shelve that idea.<br />
Config file:  A config file is nice, but requires adding a version#.  That just shifts our sync problem to config files&#8230;so lets drop that idea.  </p>
<p>What about source code?  </p>
<p>If we take the source code from MSDN and wrap it up in an assembly, we can add direct referencing capability to all our applications by deploying this assembly to the GAC.  The following code allows one to do just that.  Simply take this code and make a DLL out of it.  Then, deploy it to the GAC.  OR <a href="http://brianmackey.net/BlogFiles/BMackeyUtilities.zip">download</a> the one I made and drag-drop it to C:\windows\assembly</p>
<pre lang="x-c#">using System;
using System.Reflection;

namespace BMackeyUtilities
{
    public class Utility
    {
        public static void ImportAssemblies()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
        }
        private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
        {
            //This handler is called only when the common language runtime tries to bind to the assembly and fails.

            //Retrieve the list of referenced assemblies in an array of AssemblyName.
            Assembly MyAssembly, objExecutingAssemblies;
            string strTempAssmbPath = "";

            objExecutingAssemblies = Assembly.GetEntryAssembly();//.GetExecutingAssembly();//Get the exe assembly
            AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

            //Loop through the array of referenced assembly names.
            foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
            {
                //Check for the assembly names that have raised the "AssemblyResolve" event.
                if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
                {
                    //Build the path of the assembly from where it has to be loaded.
                    strTempAssmbPath = "C:\\References\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
                    break;
                }

            }
            //Load the assembly from the specified path.
            MyAssembly = Assembly.LoadFrom(strTempAssmbPath);

            //Return the loaded assembly.
            return MyAssembly;
        }
    }
}
</pre>
<p>Going back to Program1.exe and Program2.exe.  I add myAssemblyInGac.dll to both programs.  See <a href="http://www.eggheadcafe.com/PrintSearchContent.asp?LINKID=1175">how to add a reference to a file in the gac</a> (just add a registry key to HKLM\SOFTWARE\MICROSOFT\.NETFRAMEWORK\AssemblyFolders\<MYREFERENCEFOLDER> and set the &#8220;Default&#8221; string value to C:\References).  Then, add the following line of code to the first line in Main() in all your programs:</p>
<pre lang="x-c#">
BMackeyUtilities.Utility.ImportAssemblies();
</pre>
<p>Now, everytime I update BusinessLayer.dll and copy it to &#8220;C:\References&#8221;, both of my programs are in sync. Imagine the time and frustration this saves with 10+ exe&#8217;s!  </p>
<p>I know this is alot to swallow so hit me up with questions/comments!!</p>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=249</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Factory Design pattern &#8211; simple example</title>
		<link>http://brianmackey.net/Blog/?p=247</link>
		<comments>http://brianmackey.net/Blog/?p=247#comments</comments>
		<pubDate>Thu, 18 Feb 2010 00:12:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=247</guid>
		<description><![CDATA[Factory patterns can be used to select classes at runtime without specifying a class name. In order to achieve this awesome task, we actually work with an Interface rather than the types that implement the interface. using System; using FactoryPattern; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { RunFactory(); } private static [...]]]></description>
			<content:encoded><![CDATA[<p>Factory patterns can be used to select classes at runtime without specifying a class name.  In order to achieve this awesome task, we actually work with an Interface rather than the types that implement the interface.</p>
<pre lang="x-c#">using System;
using FactoryPattern;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            RunFactory();
        }

        private static void RunFactory()
        {
            IType[] objects = new IType[2];
            objects[0] = AFactory.MakeType(AFactory.Types.Type1);
            objects[1] = AFactory.MakeType(AFactory.Types.Type2);

            foreach (IType t in objects)
            {
                Console.WriteLine("Name: {0}",t.Name);
                t.DoSomething();
            }
        }
    }
}
namespace FactoryPattern
{
    public class AFactory
    {
        public enum Types { Type1, Type2 };

        public static IType MakeType(Types type)
        {
            switch (type)
            {
                case Types.Type1:
                    return new Type1();
                case Types.Type2:
                    return new Type2();
                default:
                    return new Type1();
            }
        }
    }
    public interface IType
    {
        string Name { get; set; }
        void DoSomething();
    }
    public class Type1 : IType
    {
        private string _name;

        public Type1():this("default")//call Type1(string) constructor
        {
        }

        public Type1(string Name)
        {
            _name = Name;
        }

        #region IType Members

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public void DoSomething()
        {
            Console.WriteLine("Did something");
        }

        #endregion
    }

    public class Type2 : IType
    {
        private string _name;

        public Type2():this("default2")
        {
        }

        public Type2(string Name)
        {
            _name = Name;
        }

        #region IType Members

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }

        public void DoSomething()
        {
            Console.WriteLine("Did something else");
        }

        #endregion
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=247</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>working with C# and C++</title>
		<link>http://brianmackey.net/Blog/?p=219</link>
		<comments>http://brianmackey.net/Blog/?p=219#comments</comments>
		<pubDate>Wed, 17 Feb 2010 01:46:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=219</guid>
		<description><![CDATA[Today a programmer asked &#8220;how can I make my unmanaged C++ DLL into a managed C++ DLL so C# can use it&#8221;. First of all, C# can call unmanaged C++/ANSI with PInvoke via DLLImport. This is important to note because making Ansi C++ into managed C++ (CLI) can be a pretty intensive task. Here&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>Today a programmer asked &#8220;how can I make my unmanaged C++ DLL into a managed C++ DLL so C# can use it&#8221;.  First of all, C# can call unmanaged C++/ANSI with PInvoke via <a href="http://msdn.microsoft.com/en-us/library/aa984739(VS.71).aspx">DLLImport.</a>  This is important to note because making Ansi C++ into managed C++ (CLI) can be a pretty intensive task.  </p>
<p>Here&#8217;s a simple example of a C++ DLL and a C# assembly interoperating.</p>
<p>&#8211;Inside C++ expose a method to C# with<br />
extern &#8220;C&#8221; __declspec(dllexport) short Add(long a, long b);</p>
<p>&#8211;in C# import the C++ method with<br />
[DllImport(@"C:\Users\Brian\Documents\Visual Studio 2008\Projects\ManagedCpp\Win32TestsTry2\Win32Tests\Win32Tests\Debug\UnmanagedDll.dll", CharSet = CharSet.Ansi)]<br />
static extern short Add(int a, int b);</p>
<p>Now C# can call the C++ just like this:<br />
short answer = Add(1, 1);</p>
<p>Feel free to download the <a href="http://www.brianmackey.net/BlogFiles/Win32Tests.zip">C++ </a>and <a href="http://www.brianmackey.net/BlogFiles/ConsoleApplication1.zip">C#</a> full solution files (Visual studio 2008) I use for this post.</p>
<p>Note, C# and C++/CLI (managed) DLL&#8217;s (technically assemblies) can certainly work together too. From the C# project, simply add a reference to the C++ assembly.  </p>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=219</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Pragmatic Bookshelf and avoid Programming by Coincidence &#8211; terribad idea</title>
		<link>http://brianmackey.net/Blog/?p=205</link>
		<comments>http://brianmackey.net/Blog/?p=205#comments</comments>
		<pubDate>Wed, 17 Feb 2010 00:31:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=205</guid>
		<description><![CDATA[Today I read a piece off &#8220;The Pragmatic Bookshelf&#8221; entitled &#8220;Programming By Coincidence&#8220;. I am honestly scared that people desire staff with the mindset this article recommends. The article begins with a metaphor relating programming to war. Basically, programming becomes crossing a &#8220;minefield&#8221; where the best solution is to stab every square inch of ground [...]]]></description>
			<content:encoded><![CDATA[<p>Today I read a piece off &#8220;<a href="http://www.pragprog.com/">The Pragmatic Bookshelf</a>&#8221; entitled &#8220;<a href="http://www.pragprog.com/the-pragmatic-programmer/extracts/coincidence">Programming By Coincidence</a>&#8220;.  I am honestly scared that people desire staff with the mindset this article recommends.</p>
<p>The article begins with a metaphor relating programming to war.  Basically, programming becomes crossing a &#8220;minefield&#8221; where the best solution is to stab every square inch of ground with a bayonette in order to avoid death.   If I viewed programming in this way I would never get past &#8220;hello world&#8221; without writing a hundred unit tests for every possible spelling variation, disability, language barrier, and hardware incompatability.  Not to mention, I&#8217;d be shot by the enemy before crossing any reasonably sized territory.</p>
<p>The fact of the matter is that we all &#8220;program by necessity&#8221;.  We shouldn&#8217;t program for every risk in every scenerio.  We should be aware of our shortcuts and take the ones that cost the least.  Be mindful of the software development triangle while avoiding rigidity.</p>
<p>They go on to say<br />
&#8220;Don’t code blindfolded. Attempting to build an application you don’t fully understand, or to use a technology you aren’t familiar with, is an invitation to be misled by coincidences.&#8221;  </p>
<p>I am reminded of <a href="http://uncyclopedia.wikia.com/wiki/Star_Wars_(programming)">Star Wars Programming:</a><br />
&#8220;All requirements documentation must be agreed to before any design or coding and must be cast in stone with formal signatures and harsh penalty clauses for failure to deliver (see Death Star).&#8221;</p>
<p>In order to fully understand an application, we must take the time to plan the requirements and fully understand all technolgies involved from beginning to end.  This is impractical.  Oftentimes, a single businessman does not fully understand all processes within the company. Meeting a representative of each position is also impractical.  Often, scheduling does not a programmer to learn all jobs.  Therefore, we usually build programs with an incomplete picture of that which we are automating.</p>
<p>So what can we do?  Unfortunetly, a programmer cannot solve all these problems alone.  We depend on our superiors to accept our input at face value.  The good news is that we have a common interest in creating a successful product.  Management should regard programmers as people they work with rather than people that need to be governed.  Most programmers want to write great code. Communication needs to be open and often.  Programmers and Managers should work together to determine the best approach for a product on a regular basis.  </p>
<p>Programmers should be flexible as well.  Few enjoy re-writes, but its a necessary task.  Write manageable and maintainable code. Management should watch out for turnover and check references on contractors.  I&#8217;ve seen programmers who write unmaintainable code only to exit the company when the time comes to maintain it.  Its difficult (especially for a new hire) to explain why code that worked fine until now, is complete garbage.  </p>
<p>There&#8217;s so many things that can and do go wrong.  The most important thing a business can do is hire honest programmers and listen to them when they say &#8220;that&#8217;s a bad idea&#8221; in regards to technical problems.  While, programmers need to keep in mind that businesses have a limited budget and tight schedule.</p>
<p>Above all, strive for perfection with no real expectation of achieving it.  </p>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=205</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where do app.config files go?</title>
		<link>http://brianmackey.net/Blog/?p=197</link>
		<comments>http://brianmackey.net/Blog/?p=197#comments</comments>
		<pubDate>Wed, 17 Feb 2010 00:05:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=197</guid>
		<description><![CDATA[An app.config file is a great way to store data that may need to be updated without requiring a recompilation. But, where do app.config files go? In class library solutions/DLLs, in executeable files, in either? With one exception, app.config files should be added to the project that produces the executable file. When you build the [...]]]></description>
			<content:encoded><![CDATA[<p>An app.config file is a great way to store data that may need to be updated without requiring a recompilation.  But, where do app.config<br />
files go?  In class library solutions/DLLs, in executeable files, in either?  </p>
<p>With one exception, app.config files should be added to the project that produces the executable file.  When you build the project with the executeable the app.config<br />
will be output in the form &#8220;ProjectName.exe.config&#8221;.  While it is possible to add an app.config to a class library; its a bad idea.  The app.config file will not be visible to the executeable<br />
or even the class library within the context of the exe Process.  </p>
<p>#Dont do this<br />
It is possible to output an app.config in a class library project and have it useable within an exe.  Rename the config file and set the &#8220;copy to output directory&#8221; to &#8220;copy always&#8221;.  For example, rename the app.config to &#8220;FutureExeProjectName.exe.config&#8221;.  This is bad practice.  You are hard coding a library to a single exe, so there&#8217;s hardly any reason to have a library in the first place.  Libraries are for sharing right?? Not to mention, that you will run into some interesting troubleshooting if you decide to consume the library with another exe in the future.</p>
<p>The exception to the rules comes with visual studio&#8217;s &#8220;test project&#8221; template.  These &#8220;test project&#8221;/unit test projects are actually class Libraries.<br />
These class libraries can be treated just as if they were an exe.  MSTest actually handles the execution, but this is invisible to us.</p>
<p>To recap:<br />
1.  Always add app.config to the executeable project.<br />
2.  If you are unit testing with the &#8220;test project&#8221; template, then consider the test project the executeable project.<br />
3.  Don&#8217;t add app.config anywhere else.</p>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=197</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gathering ipaddress and other network information from IPConfig with C#</title>
		<link>http://brianmackey.net/Blog/?p=189</link>
		<comments>http://brianmackey.net/Blog/?p=189#comments</comments>
		<pubDate>Wed, 10 Feb 2010 23:15:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=189</guid>
		<description><![CDATA[IPConfig offers some great information about our network cards. But, its not very friendly to use when you are programming. You could parse the output using a regular expression, but this is kinda sloppy and sensitive to any future upgrades or textual differences between operating systems. Instead, we can use WMI queries to ask the [...]]]></description>
			<content:encoded><![CDATA[<p>IPConfig offers some great information about our network cards.  But, its not very friendly to use when you are programming.  You could parse the output using a regular expression, but this is kinda sloppy and sensitive to any future upgrades or textual differences between operating systems.  Instead, we can use WMI queries to ask the operating system for information about our network cards.  I&#8217;ve written a program that does just that.</p>
<p>&#8220;NetConnectionID&#8221; from Win32_NetworkAdapter is the same name you will see in IPConfig &#8220;Local Area Connection&#8221;, for example.  You can relate Win32_NetworkAdapter to Win32_NetworkAdapterConfiguration with the &#8220;Index&#8221;.  This is exactly what I&#8217;ve done below.  From there, you can query anything you want from the Properties list for the <a href="http://msdn.microsoft.com/en-us/library/aa394216(VS.85).aspx">Win32_NetworkAdapter</a> or <a href="http://msdn.microsoft.com/en-us/library/aa394217(VS.85).aspx">Win32_NetworkAdapterConfiguration</a> see the links for a full list of properties available.</p>
<pre lang="x-c#">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Configuration;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            const string a1 = "Local Area Connection";
            const string a2 = "Local Area Connection 2";

            AdapterInfo adapter1 = new AdapterInfo(a1);
            AdapterInfo adapter2 = new AdapterInfo(a2);
            AdapterInfo[] adapters = new AdapterInfo[2];
            adapters[0] = adapter1;
            adapters[1] = adapter2;

            try
            {
                ManagementObjectSearcher getAdapterNames =
                    new ManagementObjectSearcher("root\\CIMV2",
                    "SELECT Index, NetConnectionID FROM Win32_NetworkAdapter WHERE NetConnectionID = '" + adapter1 + "' OR NetConnectionID = '" + adapter2 + "'");

                foreach (ManagementObject queryObj in getAdapterNames.Get())
                {
                    string ncid = (string)queryObj["NetConnectionID"];
                    UInt32 index = (UInt32)queryObj["Index"];
                    if(ncid == adapter1.ToString())
                    {
                        adapter1.Index = index;
                    }
                    else if (ncid == adapter2.ToString())
                    {
                        adapter2.Index = index;
                    }
                }
                //view list of all available properties for Win32_NetworkAdapterConfiguration at http://msdn.microsoft.com/en-us/library/aa394217(VS.85).aspx
                ManagementObjectSearcher getIPSubnet =
                    new ManagementObjectSearcher("root\\CIMV2",
                    "SELECT IPAddress, IPSubnet, Index FROM Win32_NetworkAdapterConfiguration WHERE Index = " + adapter1.Index + " OR Index = " + adapter2.Index);

                foreach (ManagementObject ipsub in getIPSubnet.Get())
                {
                    UInt32 index = (UInt32)ipsub["Index"];
                    string[] ipAddress = (string[])ipsub["IPAddress"];
                    string[] subnet = (string[])ipsub["IPSubnet"];

                    if (ipAddress == null || subnet == null)
                        continue;

                    if(index == adapter1.Index)
                    {
                        adapter1.IPAddress = ipAddress[0];
                        adapter1.SubnetMask = subnet[0];
                    }
                    else if(index == adapter2.Index)
                    {
                        adapter2.IPAddress = ipAddress[0];
                        adapter2.SubnetMask = subnet[0];
                    }
                }
                foreach (AdapterInfo adapter in adapters)
                {
                    Console.WriteLine("NetConnectionID: {0}\nIndex: {1}\nIPAddress: {2}\nSubnetMask: {3}", adapter.NetConnectionID, adapter.Index, adapter.IPAddress, adapter.SubnetMask);
                }
            }
            catch (ManagementException e)
            {
                Console.WriteLine("An error occurred while querying for WMI data: " + e.Message);
            }

        }
        class AdapterInfo
        {
            public string NetConnectionID { get; set; }
            public UInt32 Index { get; set; }
            public string IPAddress { get; set; }
            public string SubnetMask { get; set; }
            public AdapterInfo(string Name)
            {
                NetConnectionID = Name;
            }
            public override string ToString()
            {
                return this.NetConnectionID;
            }
        }

    }

}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=189</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to check permissions for a web service or other service account</title>
		<link>http://brianmackey.net/Blog/?p=187</link>
		<comments>http://brianmackey.net/Blog/?p=187#comments</comments>
		<pubDate>Wed, 10 Feb 2010 00:36:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=187</guid>
		<description><![CDATA[I recently ran into a suspected permission issues with a web service&#8217;s account. Being that the service account did not have the &#8220;logon locally&#8221; account priviledge I had to find another way to test my theory. I implemented some code I found on MSDN. I programmatically logged into another user account. The account info is [...]]]></description>
			<content:encoded><![CDATA[<p>I recently ran into a suspected permission issues with a web service&#8217;s account.  Being that the service account did not have the &#8220;logon locally&#8221; account priviledge I had to find another way to test my theory.  I implemented some code I found on MSDN.  I programmatically logged into another user account.  The account info is input via the command line and executes arbitrary code with the other account.  Sure enough, the code failed with impersonation, a programmatic runas if you will.  </p>
<pre lang="x-c#">using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.IO;

[assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)]
[assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
public class TestAuthentication
{
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
    public static void Main(string[] args)
    {
        IntPtr tokenHandle = new IntPtr(0);
        IntPtr dupeTokenHandle = new IntPtr(0);
        try
        {
            string userName, domainName;
            // Get the user token for the specified user, domain, and password using the
            // unmanaged LogonUser method.
            // The local machine name can be used for the domain name to impersonate a user on this machine.
            Console.Write("Enter the name of the domain on which to log on: ");
            domainName = Console.ReadLine();

            Console.Write("Enter the username on {0} that you wish to impersonate: ", domainName);
            userName = Console.ReadLine();

            Console.Write("Enter the password for {0}: ", userName);

            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token.
            const int LOGON32_LOGON_INTERACTIVE = 2;

            tokenHandle = IntPtr.Zero;

            // Call LogonUser to obtain a handle to an access token.
            bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                ref tokenHandle);

            Console.WriteLine("LogonUser called.");

            if (false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                Console.WriteLine("LogonUser failed with error code : {0}", ret);
                throw new System.ComponentModel.Win32Exception(ret);
            }

            Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
            Console.WriteLine("Value of Windows NT token: " + tokenHandle);

            // Check the identity.
            Console.WriteLine("Before impersonation: "
                + WindowsIdentity.GetCurrent().Name);
            // Use the token handle returned by LogonUser.
            WindowsIdentity newId = new WindowsIdentity(tokenHandle);
            WindowsImpersonationContext impersonatedUser = newId.Impersonate();

            // Check the identity.
            Console.WriteLine("After impersonation: "
                + WindowsIdentity.GetCurrent().Name);

            CheckAccessForImpersonatedUser();

            // Stop impersonating the user.
            impersonatedUser.Undo();

            // Check the identity.
            Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name);

            // Free the tokens.
            if (tokenHandle != IntPtr.Zero)
                CloseHandle(tokenHandle);

        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception occurred. " + ex.Message);
        }

    }

    private static void CheckAccessForImpersonatedUser()
    {
         //Perform an action to test priviledges
        bool ret = File.Exists(@"C:\myfile.txt");//This will report false if you dont have the correct permissions
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=187</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Synchronizing Threads using Wait Handles</title>
		<link>http://brianmackey.net/Blog/?p=182</link>
		<comments>http://brianmackey.net/Blog/?p=182#comments</comments>
		<pubDate>Sun, 07 Feb 2010 18:28:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=182</guid>
		<description><![CDATA[Synchronizing threads can be done in many ways. Static counters, locks, and wait handles to name a few. In this example I review the use of wait handles. Wait Handles can keep threads from running until they receive a signal to do so. There are two types of wait handle classes in .NET: AutoResetEvent and [...]]]></description>
			<content:encoded><![CDATA[<p>Synchronizing threads can be done in many ways.  Static counters, locks, and wait handles to name a few.  In this example I review the use of wait handles.  Wait Handles can keep threads from running until they receive a signal to do so.  There are two types of wait handle classes in .NET: <a href="http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx"> AutoResetEvent </a>and <a href="http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent.aspx">ManualResetEvent</a>.  The classes use a whole set of terminology with very similar meanings that I feel is best described with a diagram:</p>
<p><img src="http://brianmackey.net/BlogImages/EventWaitHandlesDiagram.jpg" alt="Wait Handles Diagram" /></p>
<p>I&#8217;ll leave you with a fairly simple code example to demonstrate the basic usage of AutoResetEvent.  </p>
<pre lang="x-c#">class Program
    {
        static AutoResetEvent[] ares;

        static void Main(string[] args)
        {
            ares = new AutoResetEvent[] { new AutoResetEvent(false), new AutoResetEvent(false) };//Create an event for each thread

            Thread htxThread = new Thread(GetCompanyXCustomers);
            htxThread.Start();

            Thread txtThread = new Thread(GetCompanyYCustomers);
            txtThread.Start();

            WaitHandle.WaitAll(ares);//Wait until we get all the customers

            //continue work
        }

        private static void GetCompanyXCustomers()
        {
            Thread.Sleep(2000);//do work
            Console.WriteLine("Company X customers received");
            ares[0].Set();//signal finished
        }

        private static void GetCompanyYCustomers()
        {
            Thread.Sleep(4000);//do work
            Console.WriteLine("Company Y customers received");
            ares[1].Set();//signal finished
        }

    }</pre>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=182</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to communicate across different sql server instances</title>
		<link>http://brianmackey.net/Blog/?p=180</link>
		<comments>http://brianmackey.net/Blog/?p=180#comments</comments>
		<pubDate>Sun, 07 Feb 2010 14:56:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=180</guid>
		<description><![CDATA[I recently had the requirement to synchronize two tables in two different sql server instances. After a little research I discovered that this can be done with a linked server. After setting up a linked server one can call another database instance with the same familiar T-SQL syntax. SELECT * FROM [SERVER\MyInstanceName].[DatabaseName].[TableName] (or just [SERVER] [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the requirement to synchronize two tables in two different sql server instances.  After a little research I discovered that this can be done with a <a href="http://msdn.microsoft.com/en-us/library/ms188279.aspx">linked server.</a>  After setting up a linked server one can call another database instance with the same familiar T-SQL syntax. </p>
<p>SELECT * FROM [SERVER\MyInstanceName].[DatabaseName].[TableName] (or just [SERVER] for the default instance).  </p>
<p>Getting the initial linked server setup can be a little challenging, but the following code syntax worked for me:</p>
<pre lang="x-sql">EXEC  sp_addlinkedserver @server= [SERVER\sqlexpress], @srvproduct= '', @provider= N'SQLNCLI', @datasrc= [SERVER\sqlexpress]
		EXEC sp_addlinkedsrvlogin
			@rmtsrvname = [SERVER\sqlexpress]
			, @useself = 'FALSE'
			, @locallogin = NULL
			, @rmtuser = 'sa'
			, @rmtpassword = 'uuuu'
</pre>
<p>This will ensure the same SQL account is used across all linked database calls.  </p>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=180</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Writing Drivers for Windows</title>
		<link>http://brianmackey.net/Blog/?p=177</link>
		<comments>http://brianmackey.net/Blog/?p=177#comments</comments>
		<pubDate>Sat, 02 Jan 2010 16:02:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C programming]]></category>

		<guid isPermaLink="false">http://brianmackey.net/Blog/?p=177</guid>
		<description><![CDATA[I&#8217;ve recently become interested in writing drivers for windows. Windows now offers a free windows driver kit (WDK). The download is an ISO. I used PowerISO to mount the ISO locally (pretty much like Mac OSX lets you do out of the box). As any beginner should do, I&#8217;m reading through the documentation (part of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently become interested in writing drivers for windows.  Windows now offers a free <a href="http://www.microsoft.com/whdc/devtools/WDK/default.mspx">windows driver kit (WDK)</a>.  The download is an ISO.  I used <a href="http://download.cnet.com/PowerISO/3000-2646_4-10439118.html?tag=mncol">PowerISO</a> to mount the ISO locally (pretty much like Mac OSX lets you do out of the box).</p>
<p>As any beginner should do, I&#8217;m reading through the documentation (part of the WDK download).  I&#8217;ll post the next intersting tidbit that comes along.</p>
]]></content:encoded>
			<wfw:commentRss>http://brianmackey.net/Blog/?feed=rss2&amp;p=177</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
