<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>My .NET Blog</title>
	<atom:link href="http://mydotnet.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mydotnet.wordpress.com</link>
	<description>My .NET 2.0, 3.0 and 3.5 stuff</description>
	<lastBuildDate>Mon, 18 May 2009 17:27:37 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='mydotnet.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/17c253b565df79042b968ea23cce6ef3?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>My .NET Blog</title>
		<link>http://mydotnet.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://mydotnet.wordpress.com/osd.xml" title="My .NET Blog" />
		<item>
		<title>Syntax Highlighting in a RichTextBox</title>
		<link>http://mydotnet.wordpress.com/2009/05/18/syntax-highlighting-in-a-richtextbox/</link>
		<comments>http://mydotnet.wordpress.com/2009/05/18/syntax-highlighting-in-a-richtextbox/#comments</comments>
		<pubDate>Mon, 18 May 2009 17:24:32 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[WinForms]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[highlighting]]></category>
		<category><![CDATA[richtextbox]]></category>
		<category><![CDATA[syntax]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=73</guid>
		<description><![CDATA[Rich Text Box control is one of the best controls from which we can derive multiple uses. One such usage is building a code editor. Let me take SQL for example as the language I want to code in. It looks good to see keywords in different color than my normal text. It gives me [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=73&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Rich Text Box control is one of the best controls from which we can derive multiple uses. One such usage is building a code editor. Let me take SQL for example as the language I want to code in. It looks good to see keywords in different color than my normal text. It gives me the visual effect that can definitely improve my productivity.</p>
<p>Recently I also got to do some thing like this, where in I was asked to build a Rich Text Box which can colorize the text as you type in. Interesting stuff.</p>
<p>I started with trying to handle the TextChanged event and colorizing the text, but it didn&#8217;t turned out as expected. As I type and if word matches for colorization, it gets colored but since I keep typing that words get replace with my new text. Pretty bad. Huh! Well! Then I tried to understand the windows messaging model behind the scene of the TextChanged event and understood that till I complete the colorization, any new messages should be locked for processing. This way I reached the output I wanted to reach.</p>
<p>Below is the code you need to start with&#8230;you can enhance the code as per your needs.</p>
<p>Create a new class, lets name it SyntaxRTB, and derive it from RichTextBox class</p>
<pre>class SyntaxRTB: System.Windows.Forms.RichTextBox
{
 [DllImport("user32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
 private static extern int LockWindowUpdate(int hWnd);

 protected override void OnTextChanged(System.EventArgs e)
 {
 base.OnTextChanged(e);
 ColorTheKeyWords();
}

private void ColorTheKeyWords()
{
 int SelectionAt = this.SelectionStart;
 LockWindowUpdate(this.Handle.ToInt32());
 Match m = Regex.Match(this.Text, "\\b(select)\\b", RegexOptions.IgnoreCase);
 if (m.Success)
 {
 this.SelectionStart = m.Index;
 this.SelectionLength = m.Length;
 this.SelectionColor = Color.Blue;
 }
 this.SelectionStart = SelectionAt;
 this.SelectionLength = 0;
 this.SelectionColor = Color.Black;

LockWindowUpdate(0);
}
}</pre>
<p>Compile your code and start using the new Rich Text Box.</p>
<p>The key here is, as soon as the Text Changes we should stop Windows from sending a message otherwise it will affect the next keystroke and the next keystroke will erase the word being formatted. So once our formatting is completed, we unlock the update and this way our next keystroke gets processed normally.</p>
<p>One more thing is, always use Regular Expressions to match your words for coloring. This is because of performance and even perfect text matching.</p>
<p>I have shown only one key word (Select) here to demonstrate the syntax coloring. You can build from here on and keep a list of keywords to color and may be use different color for each word.</p>
<p>Possibilities are unlimited. Happy Coding!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=73&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2009/05/18/syntax-highlighting-in-a-richtextbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>
	</item>
		<item>
		<title>Dynamic Windows Service &#8211; Dynamic Name, Dynamic Configuration</title>
		<link>http://mydotnet.wordpress.com/2009/02/02/dynamic-windows-service-dynamic-name-dynamic-configuration/</link>
		<comments>http://mydotnet.wordpress.com/2009/02/02/dynamic-windows-service-dynamic-name-dynamic-configuration/#comments</comments>
		<pubDate>Mon, 02 Feb 2009 18:02:50 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[dynamic]]></category>
		<category><![CDATA[dynamic name]]></category>
		<category><![CDATA[dynamic windows service]]></category>
		<category><![CDATA[windows service]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=57</guid>
		<description><![CDATA[ONE single Windows Service EXE and Multiple Installations and all with Different Names and Configurations.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=57&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>If customers knew all technology, there would have been no innovation. Since customers don&#8217;t know technology, they keep asking for things which we generally think not possible, but once they ask we get in the research and proof-of-concepts and finally find that yes it is Possible!!</p>
<p>Dynamic Windows Service was one such area for me. ONE single EXE and Multiple Installations and all with Different Names and Configuration. Yes possible!!</p>
<p><strong><span style="color:#993300;">The problem:</span></strong></p>
<p>I had to give one single EXE to my clients and another installer EXE which could multiple install the same EXE all with different names and configurations.</p>
<p>This was easy but the real problem was Service Installer was able to install my windows service with different names, but when I use to start my service, (from with in service EXE) it had no clues which instance was started and thus ran with its default name. Now if it ran with the default name, I cannot read different configurations, since I don&#8217;t know which instance is running.</p>
<p>The Solutions:</p>
<p><span style="color:#993300;"><strong>Solution Number 1:</strong></span></p>
<p>My Service EXE name is: oneservice.exe</p>
<p>I use installutil.exe to install it. I got to .NET Command prompt and type:</p>
<pre><span style="color:#000080;">installutil</span> oneservice.exe</pre>
<p>This would always take ONE name, the default one and thus will do ONE EXE ONE SERVICE installation.</p>
<p><strong><span style="color:#993366;">Result:</span> </strong>Not dynamic at all.</p>
<p><span style="color:#993300;"><strong>Solution Number 2:</strong></span></p>
<p>Modify your Project Installer Class in order to add a parameter during installation which would take the service name and install the service with this name.</p>
<p>How? Here it is:</p>
<p>In your ProjectInstaller_OnBeforeInstall</p>
<p>and</p>
<p>ProjectInstaller_OnBeforeUnInstall</p>
<p>use</p>
<pre>this.Context.Parameters["SName"]</pre>
<p>to read the command line parameters of installutil</p>
<p>and accordingly assign it to ServiceName.</p>
<p>Write this one line in your service OnStart Method</p>
<pre><span style="color:#3366ff;">System</span>.Diagnostics.EventLog.WriteEntry("Hi from Service: "+ this.ServiceName, this.ServiceName);</pre>
<p>Again use installutil.exe and supply values to the parameter:</p>
<pre>installutil /SName=FirstService oneservice.exe</pre>
<pre>installutil /SName=SecondService oneservice.exe</pre>
<p>Now, once the service is started, goto the Services console (services.msc) and start both the services.</p>
<p>Now go to Event Viewer to check the Event Entry and you will find that both the entries say &#8220;Hi from Service: Service1&#8243;.</p>
<p>Oops! I named them as FirstService and SecondService respectively but here it is not reflected. What happened?</p>
<p>Understand this, ProjectInstaller class just assigns a &#8220;install time&#8221; name to the service and not the &#8220;run-time&#8221; name. So even if to people it looks two different services, to it self its the two services with the same name. If you do not plan to use different configurations and just want two different instance to run simultaneously, this should be your solution. For others, please read on.</p>
<p><span style="color:#993366;"><strong>Result:</strong></span> Dynamic to some extent, but not fully.</p>
<p><span style="color:#993300;"><strong>Solution Number 3:</strong></span></p>
<p>Modify the Project Installer class to read the ServiceName from a configuration file.</p>
<p>Modify the Service to read the ServiceName from the same configuration file.</p>
<p>use installutil again</p>
<pre>installutil oneservice.exe</pre>
<p>[Internally it will read ServiceName from Configuration file and install a different named service]</p>
<p>The problem with this one is: since you have ServiceName in configuration file, you have keep as many copies of EXEs in multiple folders as many services you want because once the service reads one file it acquires a name and if it reads another it converts to another.</p>
<p><span style="color:#993366;"><strong>Result:</strong></span> Pretty Dynamic but not what we want, as we want to keep a single EXE only.</p>
<p><span style="color:#993300;"><strong>Solution Number 4:</strong></span></p>
<p>Now if you want a Solution Number 3 with Single EXE what you should. You should make your service some how read the name of the instance. How? Can we pass on a parameter to our Main Method and that parameter would be the ServiceName. Yes, this looks like the solution.</p>
<p>So when you start your service, you supply the parameter</p>
<p>oneservice.exe FirstService</p>
<p>Read this args[0] and assign it to the ServiceName. Yes this is the solution, but wait, how will you achieve this with installutil. Remember this is the one we always use for installing services. Probing installutil with the following command</p>
<pre>installutil /SName=FisrtService oneservice.exe FirstService</pre>
<p>or</p>
<pre>installutil /SName=FirstService "oneservice.exe FirstService"</pre>
<p>returned me errors saying that it was not able to find FirstService file in the current directory.</p>
<p>Now, I thought that my Solution Number 1, 2 and 3 didn&#8217;t worked and what they have in common is installutil, so I finally figured out that its the installutil which is stopping me from becoming dynamic and not my own service.</p>
<p>So I finally settled down to use sc.exe [Service Controller]</p>
<p>Its pretty simple and straight forward and not need to even modify the ProjectInstaller code.</p>
<p>Just use the following command</p>
<pre>sc create FirstService binPath= "c:\OneService.exe FirstService"</pre>
<p>and see your services console. The name of the service reads FirstService</p>
<p>Start your service and see your Event Viewer it reads &#8220;Hi from Service: First Service&#8221;</p>
<p>To remove use:</p>
<pre>sc delete FirstService</pre>
<p>Ah! Finally we have found the solution.</p>
<p><span style="color:#993366;"><strong>Result:</strong></span> Totally Dynamic!!</p>
<p>So until some one suggests me a better method, I will be using Solution number 4 for writing fully dynamic services.</p>
<p><span style="color:#993300;"><strong>Dynamic Configuration:</strong></span></p>
<p>You can have one configuration per instance of the service with the name of the service itself. So your config file names would be FirstService.xml.</p>
<p>In your service OnStart method</p>
<p>read the configuration file as</p>
<pre><span style="color:#0000ff;">string </span>configFile = <span style="color:#0000ff;">this</span>.ServiceName + <span style="color:#993300;">"</span>.xml<span style="color:#993300;">"</span>;</pre>
<p>and then read the further values as you would read any XML file and start your service to work accordingly.</p>
<p>Cheers!!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/57/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=57&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2009/02/02/dynamic-windows-service-dynamic-name-dynamic-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>
	</item>
		<item>
		<title>What&#8217;s new in Visual Studio 2010?</title>
		<link>http://mydotnet.wordpress.com/2009/01/13/whats-new-in-visual-studio-2010/</link>
		<comments>http://mydotnet.wordpress.com/2009/01/13/whats-new-in-visual-studio-2010/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 17:31:18 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[.net 4.0]]></category>
		<category><![CDATA[visual studio 2010]]></category>
		<category><![CDATA[vs2010]]></category>
		<category><![CDATA[whats new]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=51</guid>
		<description><![CDATA[Recently I attended a demo on Visual Studio 2010 Team System. I felt luck to be amongst one of the first to preview the product and even suggest changes, if I felt worth.
So, what new in Visual Studio 2010?

UML: Now draw UML diagram right from your Visual Studio. No need to buy another tool or [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=51&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Recently I attended a demo on Visual Studio 2010 Team System. I felt luck to be amongst one of the first to preview the product and even suggest changes, if I felt worth.</p>
<p>So, what new in Visual Studio 2010?</p>
<ol>
<li>UML: Now draw UML diagram right from your Visual Studio. No need to buy another tool or go to Visio to do that.</li>
<li>Application Architecture Re-engineering: You have a ready made code-solution, now you have to explain it to some one but have documents. VS2010 will help you to draw an application architecture using you application code. This way you get a big picture of your application and also all linkages between different classes. Good for new joiners in an existing team.</li>
<li>Stuff for Manual Testers: Manual tester can breathe a lot better with VS2010 tools, log in all your test cases and select the test case to run and click record and then execute your test case as usual and see what you get. If test case passes, you get evidence (most clients in service based companies want that) as videos or if the test case fails, you get the steps to reproduce as videos. Cool, isn&#8217;t it?</li>
<li>Besides these a lot more in Unit Testing side.</li>
<li>A lot more features and integration with SharePoint.</li>
<li>Above all brings in .NET 4.0</li>
</ol>
<p>Expect more guys!!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/51/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/51/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/51/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=51&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2009/01/13/whats-new-in-visual-studio-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Oracle TNS Names for your Connect to Database Form</title>
		<link>http://mydotnet.wordpress.com/2008/12/25/getting-oracle-tns-names-for-your-connect-to-database-form/</link>
		<comments>http://mydotnet.wordpress.com/2008/12/25/getting-oracle-tns-names-for-your-connect-to-database-form/#comments</comments>
		<pubDate>Thu, 25 Dec 2008 14:24:27 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[tns names]]></category>
		<category><![CDATA[tnsnames.ora]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=45</guid>
		<description><![CDATA[Shows how to get TNS names from various version of Oracle in your .NET application.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=45&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Until recently I was asking my users to type in the TNS name of the Oracle Service they want to connect to. This was a bit tedious for them as they have to first remember all TNS names they want to use, secondly they have to keep them handy to paste in the connect form.</p>
<p>So, I decided to give them some relief. I queried the internet and came across various methods, some worked, some failed, and some were working only for certain versions of Oracle. So, ultimately I decided to make my own version which can work with 9i, and 10g and here it goes.</p>
<p>I query the Registry to know the path of TNSNames.ora file.</p>
<p>I found that different version of Oracle store ORACLE_HOME at different places</p>
<p>10g<br />
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_Ora10gClient<br />
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraClient10g_home1<br />
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb10g_client<br />
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\KEY_OraDb10g_home1</p>
<p>9i<br />
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE</p>
<p>So, I decided to read all of them starting with the word KEY_ in case of 10g and ORACLE in case of 9i<br />
and then iterate through each one&#8217;s child to find if it contains ORACLE_HOME and where ever this is found, take the value and add NETWORK/ADMIN/TNSNames.ora, and see if a file exists. If yes, parse the file for TNS Name else just keep iterating.</p>
<p>So, this is the first function, GetTnsNames browse through the registry.</p>
<p>GetTNSFromOracleHome, just arranges them in to one arraylist from one TnsNames.ora files</p>
<p>ExtractTnsNamesFromTnsNamesOra, parses the TnsNames.ora file.</p>
<p><!--[if gte mso 9]&gt;  Normal 0   false false false        MicrosoftInternetExplorer4  &lt;![endif]--><!--[if gte mso 9]&gt;   &lt;![endif]--><!--  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0in; 	margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:"Times New Roman";} @page Section1 	{size:8.5in 11.0in; 	margin:1.0in 1.25in 1.0in 1.25in; 	mso-header-margin:.5in; 	mso-footer-margin:.5in; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --><!--[if gte mso 10]&gt; &lt;!   /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0in 5.4pt 0in 5.4pt; 	mso-para-margin:0in; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} --> <!--[endif]--></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;color:blue;">public</span><span style="font-size:10pt;font-family:&quot;"> <span style="color:teal;">ArrayList</span> GetTnsNames()</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">ArrayList</span> tnsNames = <span style="color:blue;">new</span> <span style="color:teal;">ArrayList</span>();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">string</span> oracleHome = <span style="color:maroon;">&#8220;&#8221;</span>;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">RegistryKey</span> masterKey = <span style="color:teal;">Registry</span>.LocalMachine.OpenSubKey(<span style="color:maroon;">@&#8221;SOFTWARE\ORACLE&#8221;</span>);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (masterKey == <span style="color:blue;">null</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">return</span> <span style="color:blue;">null</span>;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">string</span>[] subKeyName = masterKey.GetSubKeyNames();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">for</span> (<span style="color:blue;">int</span> i = 0; i &lt; subKeyName.Length; i++)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// Oracle 10g version</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span> </span><span style="color:blue;">if</span> (subKeyName[i].StartsWith(<span style="color:maroon;">&#8220;KEY_&#8221;</span>))</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">try</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">RegistryKey</span> subKey = masterKey.OpenSubKey(subKeyName[i]);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>oracleHome = subKey.GetValue(<span style="color:maroon;">&#8220;ORACLE_HOME&#8221;</span>).ToString();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>subKey.Close();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>tnsNames.AddRange(FillTNS(oracleHome));</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">catch</span> (<span style="color:teal;">NullReferenceException</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">//Since ORACLE_HOME may not be there</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// Oracle 9i version</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">try</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>oracleHome = masterKey.GetValue(<span style="color:maroon;">&#8220;ORACLE_HOME&#8221;</span>).ToString();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>tnsNames.AddRange(GetTNSFromOracleHome(oracleHome));</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">catch</span> (<span style="color:teal;">NullReferenceException</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">//Since ORACLE_HOME may not be there</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>masterKey.Close();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">return</span> tnsNames;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span> </span>}</span></p>
<p><!--[if gte mso 9]&gt;  Normal 0   false false false        MicrosoftInternetExplorer4  &lt;![endif]--><!--[if gte mso 9]&gt;   &lt;![endif]--><!--  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0in; 	margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:"Times New Roman";} @page Section1 	{size:8.5in 11.0in; 	margin:1.0in 1.25in 1.0in 1.25in; 	mso-header-margin:.5in; 	mso-footer-margin:.5in; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --><!--[if gte mso 10]&gt; &lt;!   /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0in 5.4pt 0in 5.4pt; 	mso-para-margin:0in; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} --> <!--[endif]--></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;color:blue;">private</span><span style="font-size:10pt;font-family:&quot;"> <span style="color:teal;">ArrayList</span> </span><span style="font-size:10pt;font-family:&quot;">GetTNSFromOracleHome</span><span style="font-size:10pt;font-family:&quot;">(<span style="color:blue;">string</span> oracleHome)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">ArrayList</span> cbTNSNames = <span style="color:blue;">new</span> <span style="color:teal;">ArrayList</span>();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">string</span>[] tnsNames = ExtractTnsNamesFromTnsNamesOra(oracleHome);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (tnsNames != <span style="color:blue;">null</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">for</span> (<span style="color:blue;">int</span> i = 0; i &lt; tnsNames.Length; i++)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (!<span style="color:blue;">string</span>.IsNullOrEmpty(tnsNames[i]))</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>cbTNSNames.Add(tnsNames[i]);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">return</span> cbTNSNames;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p><!--[if gte mso 9]&gt;  Normal 0   false false false        MicrosoftInternetExplorer4  &lt;![endif]--><!--[if gte mso 9]&gt;   &lt;![endif]--><!--  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal 	{mso-style-parent:""; 	margin:0in; 	margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:12.0pt; 	font-family:"Times New Roman"; 	mso-fareast-font-family:"Times New Roman";} @page Section1 	{size:8.5in 11.0in; 	margin:1.0in 1.25in 1.0in 1.25in; 	mso-header-margin:.5in; 	mso-footer-margin:.5in; 	mso-paper-source:0;} div.Section1 	{page:Section1;} --><!--[if gte mso 10]&gt; &lt;!   /* Style Definitions */  table.MsoNormalTable 	{mso-style-name:"Table Normal"; 	mso-tstyle-rowband-size:0; 	mso-tstyle-colband-size:0; 	mso-style-noshow:yes; 	mso-style-parent:""; 	mso-padding-alt:0in 5.4pt 0in 5.4pt; 	mso-para-margin:0in; 	mso-para-margin-bottom:.0001pt; 	mso-pagination:widow-orphan; 	font-size:10.0pt; 	font-family:"Times New Roman"; 	mso-ansi-language:#0400; 	mso-fareast-language:#0400; 	mso-bidi-language:#0400;} --> <!--[endif]--></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;color:blue;">private</span><span style="font-size:10pt;font-family:&quot;"> <span style="color:blue;">string</span>[] </span><span style="font-size:10pt;font-family:&quot;">ExtractTnsNamesFromTnsNamesOra</span><span style="font-size:10pt;font-family:&quot;">(<span style="color:blue;">string</span> oracleHomePath)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">StringBuilder</span> output = <span style="color:blue;">new</span> <span style="color:teal;">StringBuilder</span>();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">string</span> fileLine;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">Stack</span> parens = <span style="color:blue;">new</span> <span style="color:teal;">Stack</span>();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// open tnsnames.ora</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">StreamReader</span> sr = <span style="color:blue;">null</span>;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">try</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>sr = <span style="color:blue;">new</span> <span style="color:teal;">StreamReader</span>(oracleHomePath + <span style="color:maroon;">&#8220;\\NETWORK\\ADMIN\\tnsnames.ora&#8221;</span>);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">catch</span> (System.IO.<span style="color:teal;">FileNotFoundException</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">return</span> <span style="color:blue;">null</span>;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (sr == <span style="color:blue;">null</span>) <span style="color:blue;">return</span> <span style="color:blue;">null</span>;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"> </span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// Read the first line of the file</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>fileLine = sr.ReadLine();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// loop through, reading each line of the file</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">while</span> (fileLine != <span style="color:blue;">null</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// if the first non whitespace character is a #, ignore the line</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// and go to the next line in the file</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (fileLine.Length &gt; 0 &amp;&amp; !<span style="color:blue;">string</span>.IsNullOrEmpty(fileLine.Trim()) &amp;&amp; fileLine.Trim().Substring(0, 1) != <span style="color:maroon;">&#8220;#&#8221;</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// Read through the input line character by character</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">char</span> lineChar;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">for</span> (<span style="color:blue;">int</span> i = 0; i &lt; fileLine.Length; i++)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>lineChar = fileLine[i];</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (lineChar == <span style="color:maroon;">&#8216;(&#8216;</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// if the char is a ( push it onto the stack</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>parens.Push(lineChar);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">else</span> <span style="color:blue;">if</span> (lineChar == <span style="color:maroon;">&#8216;)&#8217;</span>)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// if the char is a ), pop the stack</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>parens.Pop();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">else</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span> </span><span style="color:green;">// if there is nothing in the stack, add the character to the ouput</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (parens.Count == 0)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>output.Append(lineChar);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// Read the next line of the file</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>fileLine = sr.ReadLine();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// Close the stream reader</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>sr.Close();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// Split the output string into a string[]</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">string</span>[] split = output.ToString().Split(<span style="color:maroon;">&#8216;=&#8217;</span>);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:green;">// trim each string in the array</span></span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">for</span> (<span style="color:blue;">int</span> i = 0; i &lt; split.Length; i++)</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>split[i] = split[i].Trim();</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:teal;">Array</span>.Sort(split);</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">return</span> split;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal">
<p class="MsoNormal"><span style="font-size:10pt;font-family:&quot;">Enjoy!!<br />
</span></p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/45/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/45/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/45/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=45&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2008/12/25/getting-oracle-tns-names-for-your-connect-to-database-form/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating State Machine Workflows &#8211; Step by Step Windows Application &#8211; Part II</title>
		<link>http://mydotnet.wordpress.com/2008/09/21/creating-state-machine-workflows-step-by-step-windows-application-part-ii/</link>
		<comments>http://mydotnet.wordpress.com/2008/09/21/creating-state-machine-workflows-step-by-step-windows-application-part-ii/#comments</comments>
		<pubDate>Sat, 20 Sep 2008 19:26:56 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[workflow]]></category>
		<category><![CDATA[State Machine]]></category>
		<category><![CDATA[Windows Workflow Foundation]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=33</guid>
		<description><![CDATA[In Part I, we learnt how to create a state machine workflow from a restaurant story. Now let&#8217;s learn how to host this state machine in a Windows Forms application. Since a workflow by its own cannot work, it needs to be hosted in some type of application which can be a Windows, Web, or [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=33&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>In Part I, we learnt how to create a state machine workflow from a restaurant story. Now let&#8217;s learn how to host this state machine in a Windows Forms application. Since a workflow by its own cannot work, it needs to be hosted in some type of application which can be a Windows, Web, or a Windows Service.</p>
<p>Let&#8217;s start:</p>
<p>1. Open Visual Studio, Load the same State Machine Workflow project which we made in Part I.</p>
<p>2. Right click on the solution and add a new Windows Project to the solution. Name its as <em>OrderSystemUser</em>.</p>
<p>3. Right click on the OrderSystemUser project&#8217;s Reference and click Add Reference and add the OrderSystemStateMachine we made in Part I. Also add System.Workflow.Activities, System.Workflow.ComponentModel, and System.Workflow.Runtime.</p>
<p>4. Now add a Windows Form to it by the Name OrderManager.</p>
<p>5. To the OrderManager Form add a DataViewGrid to view the workflows and design rest of the form as shown in the picture below.</p>
<div id="attachment_35" class="wp-caption alignnone" style="width: 466px"><a href="http://mydotnet.files.wordpress.com/2008/09/ordermanager.jpg"><img class="size-full wp-image-35" title="OrderManager" src="http://mydotnet.files.wordpress.com/2008/09/ordermanager.jpg?w=456&#038;h=215" alt="Order Manager" width="456" height="215" /></a><p class="wp-caption-text">Order Manager</p></div>
<p>Order Number Textbox is for putting a new OrderNumber and Place Order is for Placing the Order.</p>
<p>Set Order Processed is for the chef to click when he completes making the coffee.</p>
<p>Set Goods Delivered is for the Waiter to click when he completes delivering the coffee.</p>
<p>Now let&#8217;s look more in to the code:</p>
<p>Define a Object Reference to WorkflowRuntime and OrderSystem (the IOrderSystem implementation class) at the top of your class</p>
<p>In your Form load method instantiate workflowRuntime and OrderSystem.</p>
<p>Also define one ExternalDataExchangeService and add this service to your workflowruntime object and to this ExternalDataExchangeService add your OrderSystem service.</p>
<p>Now add all event handlers for:</p>
<p>WorkflowCompleted, WorkflowTerminated, WorkflowIdled, WorkflowCreated and so on which ever you are interested in.</p>
<p>How to Add persistence service to it:</p>
<p>1. First of run the Sql Scripts provided by the Runtime on you Sql database. (Find Sql Scripts in c:WindowsMicrosoft.NETFramework&lt;Framework Version&gt;Windows Workflow FoundationSQLEN)</p>
<p>2. Once every thing completes successfully, generate a connection string to your Sql Database.</p>
<p>3. Add the following line to your code:</p>
<p>workflowRuntime.AddService(new SqlWorkflowPersistenceService(connString, true, new TimeSpan(0,2,0), new TimeSpan(0,0,20)));</p>
<p>4. Now your workflows are persistable in Sql Server.</p>
<p>Once you are done with this just add handler to your buttons:</p>
<pre>private void btnPlace_Click(object sender, EventArgs e)
{
   int orderNumber;
   try
   {
      orderNumber = Convert.ToInt32(txtOrderNumber.Text);
   }
   catch (FormatException)
   {
      MessageBox.Show("Not a valid Number. Try Again");
      return;
   }

   Dictionary&lt;string, object&gt; wfArgs = new Dictionary&lt;string, object&gt;();
   wfArgs.Add("OrderNumber", orderNumber);
   WorkflowInstance workflowInstance = workflowRuntime.CreateWorkflow(
                         typeof(StateMachineLab.OrderWorkflow), wfArgs);

   workflowInstance.Start();
}

private void btnOrderProcessed_Click(object sender, EventArgs e)
{
   Guid workflowId =
        (Guid)dgvOrders.CurrentRow.Cells["WorkflowId"].Value;
   int orderNumber =
        Convert.ToInt32(dgvOrders.CurrentRow.Cells["OrderNumber"].Value);
   OrderEventArgs oe = new OrderEventArgs(workflowId, orderNumber);

   os.OnOrderProcessed(oe);
}

private void btnGoodsDelivered_Click(object sender, EventArgs e)
{
   Guid workflowId =
        (Guid)dgvOrders.CurrentRow.Cells["WorkflowId"].Value;
   int orderNumber =
       Convert.ToInt32(dgvOrders.CurrentRow.Cells["OrderNumber"].Value);
   OrderEventArgs oe = new OrderEventArgs(workflowId, orderNumber);

   os.OnGoodsDelivered(oe);
}

protected override void OnFormClosing(FormClosingEventArgs e)
{
   if (workflowRuntime != null)
   {
      workflowRuntime.Dispose();
   }
   base.OnFormClosing(e);
}</pre>
<p>And you are done with your workflow Windows Host Application. Go ahead and run it.</p>
<p>Here is the full OrderManager Class for your convenience</p>
<pre>    public partial class OrderManager : Form
    {
        public OrderManager()
        {
            InitializeComponent();
        }

        WorkflowRuntime workflowRuntime;
        OrderSystem os = new OrderSystem();
        private void OrderManager_Load(object sender, EventArgs e)
        {
            workflowRuntime = new WorkflowRuntime();
            ExternalDataExchangeService exchangeService = new ExternalDataExchangeService();
            workflowRuntime.AddService(exchangeService);
            string connString = string.Format("Initial Catalog={0};Data Source={1};
            Integrated Security={2};","master", @"Sunil-LaptopSQLEXPRESS", "SSPI");
            workflowRuntime.AddService(new SqlWorkflowPersistenceService(connString, true,
            new TimeSpan(0,2,0), new TimeSpan(0,0,20)));
            exchangeService.AddService(os);
            workflowRuntime.WorkflowCompleted += new EventHandler(workflowRuntime_WorkflowCompleted);
            workflowRuntime.WorkflowTerminated += new EventHandler(workflowRuntime_WorkflowTerminated);
            workflowRuntime.WorkflowIdled += new EventHandler(workflowRuntime_WorkflowIdled);
            workflowRuntime.WorkflowCreated += new EventHandler(workflowRuntime_WorkflowCreated);
            workflowRuntime.WorkflowPersisted += new EventHandler(workflowRuntime_WorkflowPersisted);
            workflowRuntime.WorkflowLoaded += new EventHandler(workflowRuntime_WorkflowLoaded);
            workflowRuntime.WorkflowUnloaded += new EventHandler(workflowRuntime_WorkflowUnloaded);
        }

        void workflowRuntime_WorkflowUnloaded(object sender, WorkflowEventArgs e)
        {
            StateMachineWorkflowInstance se = new StateMachineWorkflowInstance(workflowRuntime,
            e.WorkflowInstance.InstanceId);
            this.UpdateUI(e.WorkflowInstance.InstanceId, se.CurrentStateName, "Unloaded");
        }

        void workflowRuntime_WorkflowLoaded(object sender, WorkflowEventArgs e)
        {
            StateMachineWorkflowInstance se = new StateMachineWorkflowInstance(workflowRuntime,
            e.WorkflowInstance.InstanceId);
            this.UpdateUI(e.WorkflowInstance.InstanceId, se.CurrentStateName, "Loaded");
        }

        void workflowRuntime_WorkflowPersisted(object sender, WorkflowEventArgs e)
        {
            try
            {
                StateMachineWorkflowInstance se = new StateMachineWorkflowInstance(workflowRuntime,
                e.WorkflowInstance.InstanceId);
                this.UpdateUI(e.WorkflowInstance.InstanceId, se.CurrentStateName, "Persisted");
            }
            catch (InvalidOperationException)
            {
                this.UpdateUI(e.WorkflowInstance.InstanceId, "Completed", "Persisted");
            }
        }

        void workflowRuntime_WorkflowCreated(object sender, WorkflowEventArgs e)
        {
            this.UpdateUI(e.WorkflowInstance.InstanceId, "Order Placed", "Created");
            Guid workflowId = (Guid)dgvOrders.Rows[dgvOrders.Rows.Count-1].Cells["WorkflowId"].Value;
            int orderNumber = Convert.ToInt32(dgvOrders.Rows[dgvOrders.Rows.Count-1].Cells
                              ["OrderNumber"].Value);
            OrderEventArgs oe = new OrderEventArgs(workflowId, orderNumber);
            os.OnOrderReceived(oe);
        }

        void workflowRuntime_WorkflowIdled(object sender, WorkflowEventArgs e)
        {
            StateMachineWorkflowInstance se = new StateMachineWorkflowInstance(workflowRuntime,
            e.WorkflowInstance.InstanceId);
            this.UpdateUI(e.WorkflowInstance.InstanceId, se.CurrentStateName, "Idled");
        }

        void workflowRuntime_WorkflowTerminated(object sender, WorkflowTerminatedEventArgs e)
        {
            StateMachineWorkflowInstance se = new StateMachineWorkflowInstance(workflowRuntime,
            e.WorkflowInstance.InstanceId);
            this.UpdateUI(e.WorkflowInstance.InstanceId, se.CurrentStateName, "Terminated");
        }

        void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
        {
            this.UpdateUI(e.WorkflowInstance.InstanceId, "Completed", "Completed");
        }

        delegate void UIUpdater(Guid instanceId, string status, string workflowStatus);
        void UpdateUI(Guid instanceId, string status, string workflowStatus)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new UIUpdater(UpdateUI), new object[] { instanceId, status,
                workflowStatus});
            }
            else
            {
                bool found = false;
                for (int i = 0; i &lt; dgvOrders.Rows.Count; i++)
                {
                    if (dgvOrders.Rows[i].Cells["WorkflowId"].Value.ToString() ==
                        instanceId.ToString())
                    {
                        found = true;
                        dgvOrders.Rows[i].Cells["CurrentState"].Value = status;
                        dgvOrders.Rows[i].Cells["WorkflowStatus"].Value = workflowStatus;
                        System.Threading.Thread.Sleep(2000);
                    }
                }
                if (!found)
                {
                    dgvOrders.Rows.Add(new object[] { txtOrderNumber.Text, instanceId, status,
                    workflowStatus });
                }
            }
        }

        private void btnPlace_Click(object sender, EventArgs e)
        {
            int orderNumber;
            try
            {
                orderNumber = Convert.ToInt32(txtOrderNumber.Text);
            }
            catch (FormatException)
            {
                MessageBox.Show("Not a valid Number. Try Again");
                return;
            }

            Dictionary wfArgs = new Dictionary();
            wfArgs.Add("OrderNumber", orderNumber);
            WorkflowInstance workflowInstance = workflowRuntime.CreateWorkflow(typeof
                      (StateMachineLab.OrderWorkflow), wfArgs);

            workflowInstance.Start();
        }

        private void btnOrderProcessed_Click(object sender, EventArgs e)
        {
            Guid workflowId = (Guid)dgvOrders.CurrentRow.Cells["WorkflowId"].Value;
            int orderNumber = Convert.ToInt32(dgvOrders.CurrentRow.Cells["OrderNumber"].Value);
            OrderEventArgs oe = new OrderEventArgs(workflowId, orderNumber);

            os.OnOrderProcessed(oe);
        }

        private void btnGoodsDelivered_Click(object sender, EventArgs e)
        {
            Guid workflowId = (Guid)dgvOrders.CurrentRow.Cells["WorkflowId"].Value;
            int orderNumber = Convert.ToInt32(dgvOrders.CurrentRow.Cells["OrderNumber"].Value);
            OrderEventArgs oe = new OrderEventArgs(workflowId, orderNumber);

            os.OnGoodsDelivered(oe);
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            if (workflowRuntime != null)
            {
                workflowRuntime.Dispose();
            }
            base.OnFormClosing(e);
        }
    }</pre>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/33/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/33/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/33/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=33&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2008/09/21/creating-state-machine-workflows-step-by-step-windows-application-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>

		<media:content url="http://mydotnet.files.wordpress.com/2008/09/ordermanager.jpg" medium="image">
			<media:title type="html">OrderManager</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating State Machine Workflows &#8211; Step by Step Windows Application &#8211; Part I</title>
		<link>http://mydotnet.wordpress.com/2008/08/27/creating-state-machine-workflows-step-by-step-windows-application-part-i/</link>
		<comments>http://mydotnet.wordpress.com/2008/08/27/creating-state-machine-workflows-step-by-step-windows-application-part-i/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 21:28:57 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[workflow]]></category>
		<category><![CDATA[State Machine]]></category>
		<category><![CDATA[Windows Workflow Foundation]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=23</guid>
		<description><![CDATA[A state machine workflow is all about different states a program execution is in. Take for example Ordering a coffee at a restaurant. How it will go:
1. You order for coffee.
2. Coffee is getting prepared
3. Coffee is delivered
Now think of the above steps as a states in .NET Workflow world and guess what you have [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=23&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>A state machine workflow is all about different states a program execution is in. Take for example Ordering a coffee at a restaurant. How it will go:</p>
<p>1. You order for coffee.</p>
<p>2. Coffee is getting prepared</p>
<p>3. Coffee is delivered</p>
<p>Now think of the above steps as a states in .NET Workflow world and guess what you have just completed is the first step in your state machine workflows. The first step of State Machine says identify your real world problem in terms of states and human interventions.</p>
<p>Let&#8217;s examine each step in a bit detail: The coffee maker is Waiting for Order (State), your Order is received (Event), he prepares coffee (State), once he is done, he says to the waiter that coffee is prepared (Event), the waiter lifts the coffee and delivers at your table(State), you drink it(Completed). So the story board is pretty clear, identify your states and the events which will takes those states to the next state.</p>
<p>Now let&#8217;s design a workflow based on the above story board.</p>
<dl class="wp-caption alignnone">
<dt class="wp-caption-dt"><a href="http://mydotnet.files.wordpress.com/2008/08/orderwf.jpg"><img class="size-medium wp-image-28 alignnone" src="http://mydotnet.files.wordpress.com/2008/08/orderwf.jpg?w=300&#038;h=187" alt="Order Workflow" width="300" height="187" /></a></dt>
</dl>
<p class="MsoNormal">The above State Machine depicts what we just discussed.</p>
<p class="MsoNormal">How to do:</p>
<ol>
<li>Open Visual Studio.</li>
<li><!--[if !supportLists]--><span><span><span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Start a new project <span style="font-family:Wingdings;"><span>à</span></span> Workflow <span style="font-family:Wingdings;"><span>à</span></span>State Machine Console Application</li>
<li><!--[if !supportLists]--><span><span><span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Once your State Machine Canvas is set, drag and drop 4 State Activity on it.</li>
<li><!--[if !supportLists]--><span><span><span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->In each activity drag and drop one EventDriven Activity.</li>
<li><!--[if !supportLists]--><span><span><span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Name the States as given in the picture by setting (Name) property for each activity.</li>
<li><!--[if !supportLists]--><span><span><span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Same way name the EventDriven Activity by setting (Name) property for each activity.</li>
</ol>
<p class="MsoNormal">Now we have plotted our story line in terms of a State Machine Workflow diagram.</p>
<p class="MsoNormal">Now how do we make it work?</p>
<p class="MsoNormal">Concepts:</p>
<p class="MsoNormal">States represents a State your program is in at any given point of time.</p>
<p class="MsoNormal">EventDriven Activity enables execution of the contained activities based on some event.</p>
<p class="MsoNormal">So our first task is to define what all events we can handle. For this purpose we will go with an interface to define all the events which our workflow can handle.</p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;">[<span style="color:#2b91af;">ExternalDataExchange</span>]</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;">public</span><span style="font-size:10pt;font-family:&quot;"> <span style="color:blue;">interface</span> <span style="color:#2b91af;">IOrderSystem</span></span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;">{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span>&lt;<span style="color:#2b91af;">OrderEventArgs</span>&gt; OrderReceived;</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span>&lt;<span style="color:#2b91af;">OrderEventArgs</span>&gt; OrderProcessed;</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span>&lt;<span style="color:#2b91af;">OrderEventArgs</span>&gt; GoodsDelivered;</span></p>
<p class="MsoNormal"><span style="font-size:10pt;line-height:115%;font-family:&quot;">}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;line-height:115%;font-family:&quot;"> </span></p>
<p class="MsoNormal">So here is our interface.</p>
<p class="MsoNormal">Notice the details&#8230;in our workflow we have only three events so our interface also defines that we can handle only 3 events.</p>
<p class="MsoNormal">Attribute [ExternalDataExchange] marks the interface to be used for the purpose of handling external data. In this way we say that this interface defines the contract between the Workflow and any external entity. If the external entity has to send any events it has to be one of these only. The good question is how the external entity sends an event using this interface? For that we need to implement this interface, so that the external entity can actually instantiate that class in order to send events to the workflow.</p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">class</span> <span style="color:#2b91af;">OrderSystem</span>: <span style="color:#2b91af;">IOrderSystem</span></span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span>&lt;<span style="color:#2b91af;">OrderEventArgs</span>&gt; OrderReceived;</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span>&lt;<span style="color:#2b91af;">OrderEventArgs</span>&gt; OrderProcessed;</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">event</span> <span style="color:#2b91af;">EventHandler</span>&lt;<span style="color:#2b91af;">OrderEventArgs</span>&gt; GoodsDelivered;</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"> </span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">void</span> OnOrderReceived(<span style="color:#2b91af;">OrderEventArgs</span> e)</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (OrderReceived != <span style="color:blue;">null</span>)</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">this</span>.OrderReceived(<span style="color:blue;">null</span>, e);</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"> </span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">void</span> OnOrderProcessed(<span style="color:#2b91af;">OrderEventArgs</span> e)</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (OrderProcessed != <span style="color:blue;">null</span>)</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">this</span>.OrderProcessed(<span style="color:blue;">null</span>, e);</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"> </span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">void</span> OnGoodsDelivered(<span style="color:#2b91af;">OrderEventArgs</span> e)</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">if</span> (GoodsDelivered != <span style="color:blue;">null</span>)</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">this</span>.GoodsDelivered(<span style="color:blue;">null</span>, e);</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;line-height:115%;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal">Now we have implemented this as well. One more thing remaining is have you noticed OrderEventArgs? Yes it’s a custom EventArg to send some event info to the workflow. What we send is the OrderNumber just for the demo purposes.</p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;">[<span style="color:#2b91af;">Serializable</span>]</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> <span style="color:blue;">class</span> <span style="color:#2b91af;">OrderEventArgs</span>: <span style="color:#2b91af;">ExternalDataEventArgs</span></span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">private</span> <span style="color:blue;">int</span> orderNumber;</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span style="color:blue;">public</span> OrderEventArgs(<span style="color:#2b91af;">Guid</span> instanceId, <span style="color:blue;">int</span> orderNumber): <span style="color:blue;">base</span> (instanceId)</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>{</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span><span> </span><span style="color:blue;">this</span>.orderNumber = orderNumber;</span></p>
<p class="MsoNormal" style="margin-bottom:.0001pt;line-height:normal;"><span style="font-size:10pt;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal"><span style="font-size:10pt;line-height:115%;font-family:&quot;"><span> </span>}</span></p>
<p class="MsoNormal">Remember it must extend ExternalDataEventArgs and must be Serializable.</p>
<p class="MsoNormal">Now we have everything in place, let’s go back to our workflow diagram to complete it.</p>
<p class="MsoNormal">What do need to complete? We have to make each state transit in to the next state.</p>
<p class="MsoNormal">How to do:</p>
<p class="MsoListParagraphCxSpFirst" style="text-indent:-18pt;padding-left:30px;"><!--[if !supportLists]--><span><span>1.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Double click on your first eventDriven activity: OrderReceived</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:-18pt;padding-left:30px;"><!--[if !supportLists]--><span><span>2.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Drag and drop a handleExternalEvent Activity.</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:-18pt;padding-left:30px;">
<div class="wp-caption alignnone" style="width: 246px"><a href="http://mydotnet.files.wordpress.com/2008/08/waitingfororder.jpg"><img src="http://mydotnet.files.wordpress.com/2008/08/waitingfororder.jpg?w=236&#038;h=327" alt="WaitingForOrder EvenDriven Activity" width="236" height="327" /></a><p class="wp-caption-text">WaitingForOrder EvenDriven Activity</p></div>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:-18pt;padding-left:30px;"><span><span>3.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->In the InterfaceType property select our IOrderSystem interface.</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:-18pt;padding-left:30px;"><!--[if !supportLists]--><span><span>4.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->The EventType property now will list all the Events available in this interface. Select<span> </span>the OrderReceived Event</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:-18pt;padding-left:30px;"><!--[if !supportLists]--><span><span>5.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Drag and drop a SetState activity.</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:-18pt;padding-left:30px;"><!--[if !supportLists]--><span><span>6.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Set TargetStateName property to next state that is ProcessingOrder (this should be available in the dropdown)</p>
<p class="MsoListParagraphCxSpMiddle" style="text-indent:-18pt;padding-left:30px;"><!--[if !supportLists]--><span><span>7.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Similarly do for all other EventDriven activity as well.</p>
<p class="MsoListParagraphCxSpLast" style="text-indent:-18pt;padding-left:30px;"><!--[if !supportLists]--><span><span>8.<span style="font-style:normal;font-variant:normal;font-weight:normal;font-size:7pt;line-height:normal;font-family:&quot;"> </span></span></span><!--[endif]-->Notice when you come back to you main workflow you will see a connecting line between your states. This comes because of SetState Activity’s TargetStateName Property.</p>
<p class="MsoNormal" style="padding-left:30px;">
<p class="MsoNormal">Once you reach GoodsDelivered eventdriven activity, you are done with your StateMachine workflow.</p>
<p class="MsoNormal">Go ahead and compile it.</p>
<p class="MsoNormal">Your first part of this mission is accomplished. For the second part of how to host this in a Windows application, keep watching this space for Part II of this article.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/mydotnet.wordpress.com/23/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/mydotnet.wordpress.com/23/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/23/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/23/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/23/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=23&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2008/08/27/creating-state-machine-workflows-step-by-step-windows-application-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>

		<media:content url="http://mydotnet.files.wordpress.com/2008/08/orderwf.jpg?w=300" medium="image">
			<media:title type="html">Order Workflow</media:title>
		</media:content>

		<media:content url="http://mydotnet.files.wordpress.com/2008/08/waitingfororder.jpg" medium="image">
			<media:title type="html">WaitingForOrder EvenDriven Activity</media:title>
		</media:content>
	</item>
		<item>
		<title>Types of Workflows and selecting the best one</title>
		<link>http://mydotnet.wordpress.com/2008/07/31/types-of-workflows-and-selecting-the-best-one/</link>
		<comments>http://mydotnet.wordpress.com/2008/07/31/types-of-workflows-and-selecting-the-best-one/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 13:28:45 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[workflow]]></category>
		<category><![CDATA[usage]]></category>
		<category><![CDATA[Windows Workflow Foundation]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=16</guid>
		<description><![CDATA[WorkFlow Foundation (WF) is a .NET 3.0 technology for managing workflows. Workflow can be thought of as a series of task that needs to be completed either sequentially or parrallely, completing one activity at a time in a pipeline
.NET Workflow are of two types:
1. State Machine Workflow
2. Sequential Worflow
The good question is: how to decide [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=16&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>WorkFlow Foundation (WF) is a .NET 3.0 technology for managing workflows. Workflow can be thought of as a series of task that needs to be completed either sequentially or parrallely, completing one activity at a time in a pipeline</p>
<p>.NET Workflow are of two types:</p>
<p>1. State Machine Workflow</p>
<p>2. Sequential Worflow</p>
<p>The good question is: how to decide which one suits your need?</p>
<p>Let&#8217;s decide:<br />
1. State Machine has states, states can be thought of as a land mark in a long running activity. You reach one</p>
<p>land mark, rest there, move to next and so on. Take for example Performance Appraisal at the end of the year.</p>
<p>The states can be represented as:</p>
<p>1. Employee Completed Self Appraisal<br />
2. Manager Completed Employee Appraisal<br />
3. Reivew Completed between Employee and Manager<br />
4. Ratings Finalized</p>
<p>Now you move in order, you complete the state 1 then 2 and so on and each of these states mark your status in the whole process.</p>
<p>Workflow also can persist your states in database, so it doesn&#8217;t matter how long it takes for them to complete.</p>
<p>So if you are working on an activity which needs human interventions (for approvals) you should go for State Machine Workflows. It can also take care of load on the server due to multiple workflows starting at the same time.</p>
<p>2. Sequential Workflow can process activities in sequence but at the same time they can also spawn multiple thread on a part of the activity by using the Parallel Activity component. Use Sequential Workflows if you are not very much well verse with multiple thread management, but still want to use its features to enhance the performance of your application.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/mydotnet.wordpress.com/16/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/mydotnet.wordpress.com/16/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/16/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/16/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/16/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=16&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2008/07/31/types-of-workflows-and-selecting-the-best-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>
	</item>
		<item>
		<title>Intellisense in a Windows Forms Textbox</title>
		<link>http://mydotnet.wordpress.com/2008/06/27/intellisense-in-a-windows-forms-textbox/</link>
		<comments>http://mydotnet.wordpress.com/2008/06/27/intellisense-in-a-windows-forms-textbox/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 09:13:22 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[intellisense]]></category>
		<category><![CDATA[textbox]]></category>
		<category><![CDATA[Windows Forms]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=15</guid>
		<description><![CDATA[Recently I came across a problem of implementing a intellisense kind of feature in a normal text box in which the user will type some text in a textbox and keep getting intellisense help to complete the current word.
Basically it was typing of TableName and corresponding columns.
What ultimately was decided was that on typing of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=15&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Recently I came across a problem of implementing a intellisense kind of feature in a normal text box in which the user will type some text in a textbox and keep getting intellisense help to complete the current word.</p>
<p>Basically it was typing of TableName and corresponding columns.</p>
<p>What ultimately was decided was that on typing of space (&#8216; &#8216;) we will show intellisense with Table names and on typing of dot (&#8216;.&#8217;) we will show corresponding column names.</p>
<p>Basics for Intellisense feature</p>
<ol>
<li>You require a TextBox Control to behave as your base editor.</li>
<li>You require a ListBox Control to put all your items used for word completion.</li>
<li>You require a method to get the point (Co-ordinates)of the current text being typed in the TextBox.</li>
</ol>
<p>I guess you are good to get the first two items of the above list. The code for the last item is as follows:</p>
<pre>private Point GetPoint(TextBox textBoxControl)
{
   Graphics graphics = Graphics.FromHwnd(textBoxControl.Handle);
   SizeF size = graphics.MeasureString(textBoxControl.Text.Substring(0,
                textBoxControl.SelectionStart), textBoxControl.Font);
   Point coord = new Point((int)size.Width + textBoxControl.Location.X,
                 (int)size.Height + textBoxControl.Location.Y);
   return coord;
}</pre>
<p>Then you can use this as follows</p>
<pre>private void textBox_KeyPress(object sender, KeyPressEventArgs e)
{
   switch(e.KeyChar)
   {
      case '.':
      listBox.Location = GetPoint(textBox);
      listBox.Visible = true;
      break;
   }
}</pre>
<p>And you are ready with the basic intellisense</p>
<p>Add these two methods as well</p>
<p>//to add an item to Textbox once your press tab in your listBox</p>
<pre>private void listBox_Leave(object sender, EventArgs e)
{
   textBox.Text += listBox1.SelectedItem.ToString();
   textBox.SelectionStart = textBox.Text.Length;
}</pre>
<p>//To start selecting the items once your press up / down arrows</p>
<pre>private void textBox_KeyUp(object sender, KeyEventArgs e)
{
   if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
   {
      listBox.Focus();
   }
}</pre>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/mydotnet.wordpress.com/15/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/mydotnet.wordpress.com/15/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/15/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/15/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/15/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=15&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2008/06/27/intellisense-in-a-windows-forms-textbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>
	</item>
		<item>
		<title>Oracle Workflow Persistence Service for Workflows</title>
		<link>http://mydotnet.wordpress.com/2008/06/10/oracle-workflow-persistence-service-for-workflows/</link>
		<comments>http://mydotnet.wordpress.com/2008/06/10/oracle-workflow-persistence-service-for-workflows/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 08:14:40 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[workflow]]></category>
		<category><![CDATA[Custom]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[OracleWorkflowPersistenceService]]></category>
		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=12</guid>
		<description><![CDATA[Workflow comes with inbuilt MSSQL persistence Service. For other databases you have to create a custom persistence service. I have tried to do the same. Presented below is the basic most Oracle Workflow persistence Service. It has all the elements you need for a basic purpose. I have put appropriate comments with in the code.
To [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=12&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Workflow comes with inbuilt MSSQL persistence Service. For other databases you have to create a custom persistence service. I have tried to do the same. Presented below is the basic most Oracle Workflow persistence Service. It has all the elements you need for a basic purpose. I have put appropriate comments with in the code.</p>
<p>To write a Custom Workflow Persistence Service you need to implement abstract class <em>WorkflowPersistenceService </em>and provide implmentations to the methods it contains.</p>
<p>A brief about all the methods is as follows:</p>
<ul>
<li> SaveWorkflowInstanceState: Saves the current state of the workflow to the database</li>
<li> LoadWorkflowInstanceState: Load an entire workflow from the database, on receiving any events.</li>
<li> SaveCompletedContextActivity: Once an activity is completed persist it to the database.</li>
<li> LoadCompletedContextActivity: Load an activity from the database, on receiving any events.</li>
<li> UnloadOnIdle: Always set it to true to unload and persist your workflow when its idled.</li>
<li> Serialize: To insert/update in to the database</li>
<li> Deserialize: To retrieve from the database</li>
<li> DeleteWorkflow: Delete a completed workflow and all the related activities</li>
<li> GetAllWorkflows: Getting all workflows persisted in the database.</li>
</ul>
<pre>using System;
using System.IO;
using System.Collections.Generic;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Workflow.ComponentModel;
using System.Data.OleDb;
using System.Data;
using System.Data.OracleClient;

namespace SharedWorkflows
{
    ///
    /// Oracle based workflow persistence service: Created by Sunil
    ///
    public class OracleWorkflowPersistenceService: WorkflowPersistenceService
    {
        private string dbconnectionString;
        public OracleWorkflowPersistenceService(string connectionString)
        {
            this.dbconnectionString = connectionString;
        }

        #region Abstract method implementations

        ///
        /// Persist the current state of the entire workflow
        ///
        protected override void SaveWorkflowInstanceState(Activity rootActivity, bool unlock)
        {
            //get the workflow instance Id
            Guid instanceId = WorkflowEnvironment.WorkflowInstanceId;

            //determine the status of the workflow
            WorkflowStatus status = WorkflowPersistenceService.GetWorkflowStatus(rootActivity);
            switch (status)
            {
                case WorkflowStatus.Completed:
                case WorkflowStatus.Terminated:
                    //delete the persisted workflow
                    DeleteWorkflow(instanceId);
                    break;
                default:
                    //save the workflow
                    Serialize(instanceId, Guid.Empty, rootActivity);
                    break;
            }
        }

        ///
        /// Load an entire workflow
        ///
        protected override Activity LoadWorkflowInstanceState(
            Guid instanceId)
        {
            Activity activity = Deserialize(instanceId, Guid.Empty, null);
            if (activity == null)
            {
                ThrowException(instanceId, "Unable to deserialize workflow", null);
            }
            return activity;
        }

        ///
        /// Persist a completed activity context
        ///
        ///
        /// This persists completed activities that were part
        /// of an execution scope. Example:  Activities
        /// within a CompensatableSequenceActivity.
        ///
        protected override void SaveCompletedContextActivity(
            Activity activity)
        {
            //get the workflow instance Id
            Guid instanceId = WorkflowEnvironment.WorkflowInstanceId;

            //get the context Id which identifies the activity scope
            //within the workflow instance
            Guid contextId = (Guid)activity.GetValue(Activity.ActivityContextGuidProperty);

            //persist the activity for this workflow
            Serialize(instanceId, contextId, activity);
        }

        ///
        /// Load an activity context
        ///
        protected override Activity LoadCompletedContextActivity(Guid scopeId, Activity outerActivity)
        {
            //get the workflow instance Id
            Guid instanceId = WorkflowEnvironment.WorkflowInstanceId;

            Activity activity = Deserialize(instanceId, scopeId, outerActivity);
            if (activity == null)
            {
                ThrowException(instanceId, "Unable to deserialize activity", null);
            }
            return activity;
        }

        protected override void UnlockWorkflowInstanceState(Activity rootActivity)
        {
            //I have not implemented locking
        }

        protected override bool UnloadOnIdle(Activity activity)
        {
            //always unload on idle
            return true;
        }

        #endregion

        #region Persistence and Oracle Management

        ///
        /// Serialize the workflow or an activity context
        ///
        private void Serialize(Guid instanceId, Guid contextId, Activity activity)
        {
            try
            {
                MemoryStream memoryStream = new MemoryStream();
                activity.Save(memoryStream);
                byte[] wfState = memoryStream.GetBuffer();

                OracleConnection connection = new OracleConnection(this.dbconnectionString);
                OracleCommand command  = new OracleCommand();
                command.CommandText = "INSERT INTO WFPERSISTENCE (WFID, WFSTATE, CONTEXTID) VALUES ('"
                                      + instanceId.ToString()
                                      + "',:WFSTATE,'" + contextId.ToString() +"')";
                OracleParameter param = new OracleParameter();
                param.OracleType = OracleType.Blob;
                param.ParameterName = "WFSTATE";
                param.Value = wfState;
                command.Parameters.Add(param);

                command.Connection = connection;
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
            }
            catch (ArgumentException e)
            {
                ThrowException(instanceId, "Serialize: Method has invalid argument", e);
            }
            catch (Exception e)
            {
                ThrowException(instanceId, "Serialize: Unknown exception", e);
            }
        }

        ///
        /// Deserialize a workflow or an activity context
        ///
        private Activity Deserialize(Guid instanceId, Guid contextId, Activity rootActivity)
        {
            Activity activity = null;
            try
            {
                OracleConnection connection = new OracleConnection(this.dbconnectionString);
                OracleCommand command = new OracleCommand();
                command.CommandText = "SELECT WFSTATE FROM WFPERSISTENCE WHERE WFID='"
                                      + instanceId.ToString() + "' AND CONTEXTID='"
                                      + contextId.ToString() + "'";
                command.Connection = connection;
                connection.Open();
                byte[] wfState = (byte[]) command.ExecuteScalar();

                connection.Close();
                MemoryStream memoryStream = new MemoryStream(wfState);
                activity = Activity.Load(memoryStream, rootActivity);
            }
            catch (ArgumentException e)
            {
                ThrowException(instanceId, "Deserialize: Path has invalid argument", e);
            }

            catch (Exception e)
            {
                ThrowException(instanceId, "Deserialize: Unknown exception", e);
            }
            return activity;
        }

        ///
        /// Delete a workflow and any related activity context files
        ///
        private void DeleteWorkflow(Guid instanceId)
        {
            try
            {
                OracleConnection connection = new OracleConnection(this.dbconnectionString);
                OracleCommand command = new OracleCommand();
                command.CommandText = "DELETE FROM WFPERSISTENCE WHERE WFID='"
                                      + instanceId.ToString() + "'";
                command.Connection = connection;
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
            }
            catch (ArgumentException e)
            {
                ThrowException(instanceId, "Delete: Method has invalid argument", e);
            }

            catch (Exception e)
            {
                ThrowException(instanceId, "Delete: Unknown exception", e);
            }
        }

        #endregion

        #region Existing Workflow Management

        ///
        /// Return a list of all workflow Ids that are persisted
        ///
        public List GetAllWorkflows()
        {
            List workflows = new List();

            OracleConnection connection = new OracleConnection(this.dbconnectionString);
            OracleCommand command = new OracleCommand();
            command.CommandText = "SELECT DISTINCT WFID FROM WFPERSISTENCE";
            command.Connection = connection;
            DataSet dataSet = new DataSet();
            OracleDataAdapter dataAdapter = new OracleDataAdapter();
            connection.Open();
            dataAdapter.SelectCommand = command;
            dataAdapter.Fill(dataSet);
            connection.Close();

            for (int i = 0; i &lt; dataSet.Tables[0].Rows.Count; i++)
            {
                Guid instanceId = new Guid(dataSet.Tables[0].Rows[i]["WFID"].ToString());
                workflows.Add(instanceId);
            }
            return workflows;
        }

        #endregion

        #region Common Error handling

        ///
        /// Throw an exception due to an error
        ///
        private void ThrowException(Guid instanceId, String message, Exception inner)
        {
            if (inner == null)
            {
                throw new PersistenceException(String.Format("Workflow: {0} Error: {1}",
                                               instanceId, message));
            }
            else
            {
                throw new PersistenceException(String.Format("Workflow: {0} Error: {1}: Inner: {2}",
                                               instanceId, message, inner.Message), inner);
            }
        }

        #endregion
    }
}</pre>
<p>The corresponding database Table Create Script is as follows:</p>
<pre>CREATE TABLE WFPERSISTENCE
(
 WFID       VARCHAR2(36 BYTE)  NOT NULL,
 WFSTATE    BLOB,
 CONTEXTID  VARCHAR2(36 BYTE)
)</pre>
<p>Hope this gets you started on Custom Persistence Services for Oracle.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/mydotnet.wordpress.com/12/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/mydotnet.wordpress.com/12/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/12/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=12&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2008/06/10/oracle-workflow-persistence-service-for-workflows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating Workflows &#8211; Step by Step Console Application</title>
		<link>http://mydotnet.wordpress.com/2008/06/08/creating-workflows-step-by-step-console-application/</link>
		<comments>http://mydotnet.wordpress.com/2008/06/08/creating-workflows-step-by-step-console-application/#comments</comments>
		<pubDate>Sat, 07 Jun 2008 22:13:19 +0000</pubDate>
		<dc:creator>sunworld</dc:creator>
				<category><![CDATA[workflow]]></category>
		<category><![CDATA[creation]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[Sequential]]></category>
		<category><![CDATA[State Machine]]></category>
		<category><![CDATA[tracking]]></category>
		<category><![CDATA[Windows Workflow Foundation]]></category>
		<category><![CDATA[Workflows]]></category>

		<guid isPermaLink="false">http://mydotnet.wordpress.com/?p=6</guid>
		<description><![CDATA[Many of us need a quick guide on how to create Workflows in a step by step approach which would help us not only today but also in future.
So I thought I would create that guide for all of us. Presented below is a step by step approach of using Workflow foundation and creating Sequential [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=6&subd=mydotnet&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Many of us need a quick guide on how to create Workflows in a step by step approach which would help us not only today but also in future.</p>
<p>So I thought I would create that guide for all of us. Presented below is a step by step approach of using Workflow foundation and creating Sequential workflows.</p>
<p>Let&#8217;s get started.</p>
<p>Lets create a simple workflow which takes a command line argument and if the command line argument is &#8220;Sunil&#8221;, we will output &#8220;Valid&#8221; else we will output &#8220;Invalid&#8221; (argument).<a href="http://mydotnet.files.wordpress.com/2008/06/wf.jpg"><img class="alignnone size-medium wp-image-11" src="http://mydotnet.files.wordpress.com/2008/06/wf.jpg?w=250&#038;h=300" alt="" width="250" height="300" /></a></p>
<p>For a workflow to work you need a workflow engine, same as for a .NET code to work you need .NET Framework. Workflow engine provide the basic services and interface to interact with your workflows. It also provides service for persistence and tracking. Make sure you put this in your Main Method to gain access to the command line parameters.</p>
<pre>using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
{
   AutoResetEvent waitHandle = new AutoResetEvent(false);
   workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)
   {
      Console.WriteLine(e.OutputParameters["MyName"]);
      waitHandle.Set();
   };
   workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
   {
      Console.WriteLine(e.Exception.Message);
      waitHandle.Set();
   };

   Dictionary&lt;string, object&gt; wfArgs = new Dictionary&lt;string, object&gt;();
   wfArgs.Add("MyName", args.Length &gt; 0 ? args[0] : "Sunil");

   WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WFFirst.Workflow1),wfArgs);
   instance.Start();
   waitHandle.WaitOne();
}</pre>
<p>Explanation:<br />
We create an instance of WorkflowRuntime and use this to create workflow of type WFFirst.Workflow1<br />
In between we add some event handlers to handles various events generated by the Workflow (there&#8217;s<br />
lot more events to explore!)</p>
<p>Once this Workflow runtime is available lets code the main part of our workflow.</p>
<p>We have to define a property which can serve for our Workflow argument. I have defined &#8220;MyName&#8221; in this case.</p>
<pre>namespace WFFirst
{
   public sealed partial class Workflow1: SequentialWorkflowActivity
   {
		public Workflow1()
		{
			InitializeComponent();
		}

        private string _myName = string.Empty;
        public string MyName
        {
            get { return _myName; }
            set { _myName = value; }
        }

        private void CheckTest(object sender, ConditionalEventArgs e)
        {
            if(_myName=="Sunil")
               e.Result = true;
            else
               e.Result = false;
        }

        private void Valid(object sender, EventArgs e)
        {
            Console.WriteLine("Valid");
        }

        private void Invalid(object sender, EventArgs e)
        {
            Console.WriteLine("Invalid");
        }
   }
}</pre>
<p>Explanation:</p>
<p>This is pretty straight forward.</p>
<p>MyName is the input property name. This is the way you assign inputs to Workflows.</p>
<p>In the above workflow there is a ifelse activity which checks that if the input argument is &#8220;Sunil&#8221;, the result of the workflow is &#8220;Valid&#8221; else its &#8220;Invalid&#8221;. We check this in &#8220;CheckTest&#8221; method and accordingly set the result to true or false.</p>
<p>The &#8220;Valid&#8221; and &#8220;Invalid&#8221; methods just prints the results.</p>
<p>Now to reach this stage you have to do some settings in your Design of Workflow. So lets take a closer look at the design.</p>
<table border="0">
<tbody>
<tr>
<td><a href="http://mydotnet.files.wordpress.com/2008/06/wf.jpg"><img class="alignnone size-medium wp-image-11" src="http://mydotnet.files.wordpress.com/2008/06/wf.jpg?w=286&#038;h=343" alt="" width="286" height="343" /></a></td>
<td></td>
<td>1. Drag and drop an IfElseActivity.</p>
<p>2. As soon as you drop this, it will create 2 branches, one for &#8220;If&#8221; part and one for &#8220;Else&#8221; part.</p>
<p>3. In these branches drop a CodeActivity each.</p>
<p>4. For the ifElseBranchActivity1, set these properties. Condition = Code Condition. It will show a &#8220;+&#8221; mark next to this property, expand this and in Condition property put &#8220;CheckTest&#8221;, we created above</p>
<p>5. For codeActivity1, set &#8220;ExecuteCode&#8221; = Valid (which we created above).</p>
<p>6. For codeActivity2, set &#8220;ExecuteCode&#8221; = Invalid (which we created above). Make sure you enable both of these.</p>
<p>7. Wew, you are ready to execute.</td>
</tr>
</tbody>
</table>
<p>Just execute, try with different command line arguments. All inputs except &#8220;Sunil&#8221; will yield result as &#8220;Invalid&#8221;. This is a pretty simple example to start with. Workflow has lot more to offer. Hope this will get you started. I will cover some more topics on Workflow in coming posts.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/mydotnet.wordpress.com/6/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/mydotnet.wordpress.com/6/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mydotnet.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mydotnet.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mydotnet.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mydotnet.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mydotnet.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mydotnet.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mydotnet.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mydotnet.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mydotnet.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mydotnet.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mydotnet.wordpress.com&blog=2975043&post=6&subd=mydotnet&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://mydotnet.wordpress.com/2008/06/08/creating-workflows-step-by-step-console-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0792974967a4a69b283bc03eca583be7?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">sunworld</media:title>
		</media:content>

		<media:content url="http://mydotnet.files.wordpress.com/2008/06/wf.jpg?w=250" medium="image" />

		<media:content url="http://mydotnet.files.wordpress.com/2008/06/wf.jpg?w=250" medium="image" />
	</item>
	</channel>
</rss>