<?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>Dirty Motherfucking Blog &#187; batch</title>
	<atom:link href="http://www.dirty-motherfucker.org/blog/tag/batch/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dirty-motherfucker.org/blog</link>
	<description>All kinds of shit</description>
	<lastBuildDate>Tue, 17 Aug 2010 18:19:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
		<item>
		<title>Run .bat file with a set of parameters</title>
		<link>http://www.dirty-motherfucker.org/blog/2009/11/28/run-bat-file-with-a-set-of-parameters/</link>
		<comments>http://www.dirty-motherfucker.org/blog/2009/11/28/run-bat-file-with-a-set-of-parameters/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 00:39:18 +0000</pubDate>
		<dc:creator>gencha</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[.bat]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[console]]></category>

		<guid isPermaLink="false">http://www.dirty-motherfucker.org/blog/?p=287</guid>
		<description><![CDATA[I am currently working on a project of larger scale than what I am usually working on. During this project I wrote several small tools which I personally feel are somewhat interesting. I&#8217;ll try to write up a few posts about some solutions I came up with to kinda special problems. This is the first [...]]]></description>
			<content:encoded><![CDATA[<p>I am currently working on a project of larger scale than what I am usually working on. During this project I wrote several small tools which I personally feel are somewhat interesting.<br />
I&#8217;ll try to write up a few posts about some solutions I came up with to kinda special problems.<br />
This is the first one and I already feel the topic is not capturing the essence of what this tool does.</p>
<p>In this project we have a Windows domain of about 100 machines which are running our software are mainly used to display &#8220;stuff&#8221; (let&#8217;s not go into details).<br />
When I arrived on site where we deployed our product I found that some technicians where using .bat files to deploy files to machines in the domain. After deploying their files they would restart the machine remotely through Windows remote desktop feature. They would repeat that process for every machine in the domain manually until the desired group was up-to-date.<br />
Needless to say, for a programmer, this seemed unnecessarily cumbersome. This was when I wrote the first helpful tool.</p>
<p>The tool will read a .xml file which contains target IP addresses (or machine names if DNS is available) and will use them as a parameter to a supplied batch file. Alternatively it would use a list of targets supplied via the command line. Thus enabling you to run a .bat file for a large set of targets.<br />
Let&#8217;s have a look at the source:</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Xml;
using System.Diagnostics;

namespace BatchProcessor {
  class Program {

    private const   String      APPLICATION_NAME    = &quot;Batch Processor&quot;;
    private const   String      APPLICATION_VERSION = &quot;0.1&quot;;

    private static ConsoleColor defaultColor        = ConsoleColor.Gray;

    static void Main( string[] args ) {

      Console.WindowWidth = 160;
      Console.Title = String.Format( &quot;{0} {1}&quot;, APPLICATION_NAME, APPLICATION_VERSION );

      Console.ForegroundColor = ConsoleColor.Cyan;
      Console.WriteLine( String.Format( &quot;{0} {1}&quot;, APPLICATION_NAME, APPLICATION_VERSION ) );
      Console.ForegroundColor = ConsoleColor.DarkCyan;
      Console.WriteLine( &quot;CPP Studios Event GmbH 2009&quot; );
      Console.ForegroundColor = defaultColor;

      string        batchFile   = String.Empty;
      string        targetsFile = String.Empty;
      List&lt;string&gt;  targets     = new List&lt;string&gt;();

      if( args.Length &lt; 2 ) {
        errorExit( &quot;Incorrect number of arguments&quot; );
        return;
      }

      batchFile   = args[ 0 ];
      targetsFile = args[ 1 ];

      // Check if targetsFile is actually a file
      FileInfo targetsFileInfo = new FileInfo( targetsFile );
      if( !targetsFileInfo.Exists ) {
        for( int targetIndex = 1; targetIndex &lt; args.Length; ++targetIndex ) {
          targets.Add( args[ targetIndex ] );
        }

      } else {
        XmlDocument targetFile = new XmlDocument();
        try {
          Console.WriteLine( String.Format( &quot;Reading targets from {0}...&quot;, targetsFile ) );
          targetFile.Load( targetsFile );

          XmlNodeList targetNodes = targetFile.SelectNodes( &quot;/targets/target&quot; );
          foreach( XmlNode targetNode in targetNodes ) {
            targets.Add( targetNode.Attributes[ &quot;ip&quot; ].InnerText );
          }

        } catch( Exception ex ) {
          Console.ForegroundColor = ConsoleColor.Red;
          Console.WriteLine( &quot;Error while reading targets: &quot; + ex.Message );
          Console.ForegroundColor = defaultColor;
        }
      }
      Console.WriteLine( String.Format( &quot;Got {0} targets&quot;, targets.Count ) );

      foreach( String target in targets ) {
        string commandLine = String.Format( &quot;{0} {1}&quot;, batchFile, target );
        Console.ForegroundColor = ConsoleColor.DarkGreen;
        Console.WriteLine( String.Format( &quot;Executing '{0}'...&quot;, commandLine ) );
        Console.ForegroundColor = defaultColor;

        ProcessStartInfo  p     = new ProcessStartInfo( batchFile );
        Process           proc  = new Process();

        p.Arguments               = target;
        p.RedirectStandardOutput  = true;
        p.UseShellExecute         = false;
        proc.StartInfo            = p;

        proc.Start();
        StreamReader outputReader = proc.StandardOutput;

        proc.WaitForExit();
        Console.Write( outputReader.ReadToEnd() );

        Console.ForegroundColor = ConsoleColor.DarkGreen;
        Console.WriteLine( String.Format( &quot;Finished processing '{0}'.&quot;, commandLine ) );
        Console.ForegroundColor = defaultColor;
      }

      Console.ForegroundColor = ConsoleColor.Magenta;
      Console.WriteLine( &quot;Operation completed.&quot; );
      Console.ForegroundColor = defaultColor;

    }

    private static void errorExit( String errorMessage ) {
      Console.ForegroundColor = ConsoleColor.Red;
      Console.WriteLine( errorMessage );
      Console.ForegroundColor = defaultColor;
      Thread.Sleep( 5000 );
    }

  }
}
</pre>
<p>Pretty much a straight forward implementation of what I explained above.<br />
What amazed me most about the tool was the simplicity and how much can be achieved by the approach. Everyone who is capable of writing a .bat file could plug it right into the system and apply the command set to our pre-defined groups. I like to think that it turned out to be a very simple, yet versatile tool.</p>
<p>Another thing to notice is the console redirection used here. It&#8217;s pretty much what you will find if you google for &#8220;c# redirect console output&#8221; in a few seconds. Soon I noticed that it&#8217;s a very shitty way to redirect console output and leaves a lot to wish for. I will cover that topic in more detail in an upcoming post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dirty-motherfucker.org/blog/2009/11/28/run-bat-file-with-a-set-of-parameters/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
