tag:blogger.com,1999:blog-86016611432161719092024-03-13T22:17:46.220-04:00Programming BitsProgramming notes about C/C++, C#, Ruby, Python, IronPython, and related technologies.janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.comBlogger25125tag:blogger.com,1999:blog-8601661143216171909.post-69017373857014035922013-02-09T22:23:00.001-05:002013-02-09T22:32:19.645-05:00Beginning NServiceBus<p>I my day to day work we are using NServiceBus as our Enterprise Service Bus (ESB) implementation in an effort to advance our organization to a form of  service oriented architecture (SOA).  I am a newbie to SOA and NServiceBus, thus the journey has not always been smooth.  I plan on posting short articles about very specific issues that I have encountered with using NServiceBus.  This is the first such article.</p> <p>I like many developers have to interface to legacy systems.  These systems are usually connected via a .NET assembly and DllImport.  NServiceBus comes with a program called NServiceBus.Host.exe that allows you to host your own service endpoints (basically a message handler).  NServiceBus.Host.exe is provided to make your life easier (and it does). </p> <p>When using NServiceBus.Host.exe to host your own services, upon loading it will scan the directory for all DLLs, load them and look for implementations of IConfigureThisEndpoint. In certain cases, this may cause NServiceBus.Host.exe to exit with an exception.</p> <ul> <li>Multiple implementations of IConfigureThisEndpoint – i.e. multiple endpoints <ul> <li>Put each endpoint in its own directory. Besides, you don’t want to couple all of your code together at the deployment level either in SOA. </li> </ul> </li> <li>Native DLLs in the directory <ul> <li>C++ code anyone? Me too. </li> </ul> </li> <li>Probably other reasons that I will soon discover </li> </ul> <p>You can prevent this scanning by including an NServiceBus.Host.exe.config file that points directly to the assembly that implements IConfigureThisEndpoint.  Here is a sample:</p> <style type="text/css"><br /><br /><br />.csharpcode, .csharpcode pre<br />{<br /> font-size: small;<br /> color: black;<br /> font-family: consolas, "Courier New", courier, monospace;<br /> background-color: #ffffff;<br /> /*white-space: pre;*/<br />}<br />.csharpcode pre { margin: 0em; }<br />.csharpcode .rem { color: #008000; }<br />.csharpcode .kwrd { color: #0000ff; }<br />.csharpcode .str { color: #006080; }<br />.csharpcode .op { color: #0000c0; }<br />.csharpcode .preproc { color: #cc6633; }<br />.csharpcode .asp { background-color: #ffff00; }<br />.csharpcode .html { color: #800000; }<br />.csharpcode .attr { color: #ff0000; }<br />.csharpcode .alt <br />{<br /> background-color: #f4f4f4;<br /> width: 100%;<br /> margin: 0em;<br />}<br />.csharpcode .lnum { color: #606060; }</style> <pre class="csharpcode"><span class="kwrd"><?</span><span class="html">xml</span> <span class="attr">version</span><span class="kwrd">="1.0"</span> <span class="attr">encoding</span><span class="kwrd">="utf-8"</span> ?<span class="kwrd">></span><br /><span class="kwrd"><</span><span class="html">configuration</span><span class="kwrd">></span><br /> <span class="kwrd"><</span><span class="html">appSettings</span><span class="kwrd">></span><br /> <span class="kwrd"><</span><span class="html">add</span> <span class="attr">key</span><span class="kwrd">="EndpointConfigurationType"</span> <span class="attr">value</span><span class="kwrd">="YourNamespace.YourTypeName, YourAssembly"</span><span class="kwrd">/></span><br /> <span class="kwrd"></</span><span class="html">appSettings</span><span class="kwrd">></span><br /><span class="kwrd"></</span><span class="html">configuration</span><span class="kwrd">></span></pre><br /><br /><p>NServiceBus.Host.exe will still scan DLLs for other interface implementations during configuration (like IWantCustomInitialization), even with the NServiceBus.Host.execonfig file in place.  So you will still have to exclude specific DLLs from the configuration scanning process.  Here is an example, the Init() method of an IWantCustomInitialization handler:</p><br /><br /><pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">void</span> Init()<br />{<br /> Configure.With(AllAssemblies.Except(<span class="str">"legacy.dll"</span>).And(<span class="str">"native.dll"</span>))<br /> .Log4Net()<br /> .XmlSerializer();<br />}</pre><br /><br /><p>You can keep chaining “.And” calls to cover all of the DLLs necessary. I hope this saves you some time and frustration.  </p><br /><br /><p>There is a lot of great documentation at <a href="http://support.nservicebus.com/" target="_blank">http://support.nservicebus.com/</a></p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com2tag:blogger.com,1999:blog-8601661143216171909.post-43506789599870991232011-12-11T23:08:00.001-05:002011-12-11T23:09:30.352-05:00Getting Started with Ruby Development on Windows<p>This post is about getting a usable Ruby environment setup and configured on your Windows computer.  I assume that you are familiar with some form of software development but that you are completely new to Ruby.  Download the Ruby installer and the Ruby Development Kit from <a href="http://rubyinstaller.org/downloads/" target="_blank">the RubyInstaller site.</a>  I am using Ruby 1.9.2 (rubyinstaller-1.9.2-p290.exe) and the current DevKit (DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe) I chose to use Ruby 1.9.2 even though Ruby 1.9.3 is out because there is an issue using the Ruby-debug-base19x gem with Ruby 1.9.3.  Currently, you would have to build your own Ruby from source to be able to use the ruby-debug-base19x gem with Ruby 1.9.3 and that is beyond the scope of this blog post. If you are going to use an IDE like RubyMine or eclipse for your Ruby development, then you will want to be able to interactively debug your Ruby code using the ruby-debug gem. </p> <p>Run the Ruby installer that you just downloaded. If you are planning on using multiple Ruby installs, don’t check any of the boxes on the Installation Destination and Optional Tasks installer page.  These options include: </p> <ul> <li>Install Tcl/Tk support </li> <li>Add Ruby executables to your Path </li> <li>Associate .rb and .rbw files with this Ruby installation.  </li> </ul> <p>I always choose to install my development tools into the C:\Dev folder.  So for this install I chose C:\Dev\Ruby192. Later we will be creating batch files that set up the proper environment for each Ruby installation.  Next we need to setup the development kit.  This kit will provide you with all of the C language tools that you may need to compile and build ruby gems.  Many gems come with native extensions written in the C programming language.  The executable, DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe, is a self-extracting executable.  Just run the executable and it will ask you for the location to which you should extract the files.  I chose to use the folder C:\Dev\RubyDevKit.  </p> <p>Launch a command window with the Ruby interpreter on the PATH. In the Start Menu, choose All Programs –> Ruby1.9.2-p290 –> Start a Command Prompt with Ruby. Navigate to the Ruby DevKit installation and execute theses commands:</p> <blockquote> <p>ruby dk.rb init <br />ruby dk.rb install </p> </blockquote> <p>Further documentation for the Ruby DevKit can be found <a href="https://github.com/oneclick/rubyinstaller/wiki/Development-Kit" target="_blank">here</a>.  I use my own batch files to set up the Ruby environment.  I do this because I may have different command windows open with different Ruby environments. I find it easy to start up a command window (cmd.exe) and just run the batch file for the Ruby environment that I wish to use.  In the C:\Dev folder, create a text document name ruby192env.bat.  The contents of this file will look like this:</p> <blockquote> <p>@echo off</p> <p>@echo.   <br />@echo.   <br />@echo         Setting environment for Ruby 1.9.2 tools <br />@echo. </p> <p>set Path=C:\Dev\Ruby192\bin;%Path% <br />call C:\Dev\RubyDevKit\devkitvars.bat</p> <p>title Ruby 1.9.2 <br /></p> </blockquote> <p>This file will insert the Ruby interpreter and DevKit tools at the beginning of your PATH environment variable when run.  I have similar files for all of the Ruby versions installed on my computer.  Let’s test the ruby installation, fire up a command window and execute the command:</p> <blockquote> <p>c:\dev\ruby192env.bat</p> </blockquote> <p>This gets our Ruby environment ready to go. Next run the interactive ruby shell, irb. At the irb prompt type: </p> <blockquote> <p>puts ‘Hello, World!’ </p> </blockquote> <p>Below is the output on my computer:</p> <blockquote> <p>irb(main):001:0> puts 'Hello, World' <br />Hello, World <br />=> nil</p> </blockquote> <p>If you get similar output to the above, then everything is installed correctly. Press Ctrl + d to exit irb. Now that we have a fresh Ruby installation and the DevKit for building native extensions, let’s get some gems!  Gem is Ruby’s package management tool.  If you come from the Python world, it’s like pip only much better. Gem will allow you to find and install Ruby gems (libraries).  Gems are just libraries of code that you can download into your Ruby installation so that they are available for your use.  For example, Rails can be installed with the command:</p> <blockquote> <p>gem install rails</p> </blockquote> <p>I don’t recommend that you actually install rails at this point.  First we need the debugging packages that will allow us to step through our Ruby code in IDEs like RubyMine and eclipse.  Go back to your command window (or fire up a new one, don’t forget to run the ruby192env.bat file) and execute these commands:</p> <blockquote> <p>gem install ruby-debug-base19x <br />gem install ruby-debug-ide</p> </blockquote> <p>Here is the output of these commands on my computer:</p> <blockquote> <p>C: >>gem install ruby-debug-base19x <br />Fetching: columnize-0.3.5.gem (100%) <br />Fetching: archive-tar-minitar-0.5.2.gem (100%) <br />Fetching: ruby_core_source-0.1.5.gem (100%) <br />Fetching: linecache19-0.5.12.gem (100%) <br />Building native extensions.  This could take a while... <br />Fetching: ruby-debug-base19x-0.11.29.gem (100%) <br />Building native extensions.  This could take a while... <br />Successfully installed columnize-0.3.5 <br />Successfully installed archive-tar-minitar-0.5.2 <br />Successfully installed ruby_core_source-0.1.5 <br />Successfully installed linecache19-0.5.12 <br />Successfully installed ruby-debug-base19x-0.11.29 <br />5 gems installed <br />Installing ri documentation for columnize-0.3.5... <br />Installing ri documentation for archive-tar-minitar-0.5.2... <br />Installing ri documentation for ruby_core_source-0.1.5... <br />Installing ri documentation for linecache19-0.5.12... <br />Installing ri documentation for ruby-debug-base19x-0.11.29... <br />Installing RDoc documentation for columnize-0.3.5... <br />Installing RDoc documentation for archive-tar-minitar-0.5.2... <br />Installing RDoc documentation for ruby_core_source-0.1.5... <br />Installing RDoc documentation for linecache19-0.5.12... <br />Installing RDoc documentation for ruby-debug-base19x-0.11.29...</p> <p>C: >>gem install ruby-debug-ide <br />Fetching: ruby-debug-ide-0.4.16.gem (100%) <br />Building native extensions.  This could take a while... <br />Successfully installed ruby-debug-ide-0.4.16 <br />1 gem installed <br />Installing ri documentation for ruby-debug-ide-0.4.16... <br />Installing RDoc documentation for ruby-debug-ide-0.4.16...</p> </blockquote> <p>Now you will be able to breakpoint on, and step through code in your favorite IDE that supports Ruby development.  I am currently using RubyMine by <a href="http://www.jetbrains.com/ruby/" target="_blank">JetBrains</a>. A professional license can be obtained at a very reasonable cost and they offer a free license for open source development. A lot of Ruby programmers use vim as their Ruby development IDE.  If you have never used Linux or any Unix like system and don’t know what vim is, then just stick with RubyMine. </p> <p>There are many more useful gems you will want to install.  It really depends on your goals.  First and foremost I would recommend installing <a href="https://www.relishapp.com/rspec" target="_blank">rspec</a> and <a href="http://cukes.info/" target="_blank">cucumber</a>.  These are BDD style testing tools and each deserves its own blog post.  </p> <p>For your next step into Ruby, do yourself a favor and download and complete the <a href="http://rubykoans.com/" target="_blank">Edgecase Ruby Koans</a>.  These koans are an excellent introduction to the capabilities of the Ruby programming language.  You will not need any additional gems to run the koans.</p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com3tag:blogger.com,1999:blog-8601661143216171909.post-28101325614562679782011-05-15T23:32:00.003-04:002011-05-15T23:39:26.776-04:00Reporting only Failed Test in GoogleTestGoogleTest with GoogleMock (gtest and gmock) is an outstanding platform for testing C++ code. At work, we use gtest and gmock for unit test as well as integration style test. On one of out projects, we are up to over 600 unit tests. This is great for code coverage, but can generate very verbose output. When adding new tests, and a failure occurs, the explanation of the failed will scroll by to quickly to read and may be lost if your console buffer is not large enough. It would be really nice to only output a summary of the executed tests and any failed tests. <br />
The default output printer in gtest is an object named PrettyUnitTestResultPrinter that extends the TestEventListener class. TestEventListener objects can hook into the test framework and handle various events as tests are executed. You can learn about implementing TestEventListener classes <a href="https://code.google.com/p/googletest/wiki/V1_6_AdvancedGuide#Defining_Event_Listeners">here</a>. The documentation even shows you how to implement a minimalist printer, but without the functionality of the default printer. The built in PrettyUnitTestResultPrinter does a nice job of reporting test results. The results are even colored green for success and red for failure. Being an open source project, you could just copy the implementation of PrettyUnitTestResultPrinter and modify it to your needs. I did not want to take this approach as it would be messy to extract this class and all of its dependencies and cause more maintenance. <br />
Instead I created a TestEventListenerProxy class that implements all of the methods in TestEventListener and forwards the calls to a TestEventListener object. This class will take ownership of the pointer passed in to the constructor (deleting it in the destructor). Thus if I can get a pointer to a TestEventListener object, I can wrap it and override methods. See the code below.<br />
<table class="highlighttable"><tbody>
<tr> <td><div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;"><pre style="line-height: 125%;">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre><br />
</div><br />
</td> <td class="code"><br />
<div class="highlight" style="background: #f8f8f8;"><br />
<pre style="line-height: 125%;"><span style="color: green; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">TestEventListenerProxy</span> <span style="color: #666666;">:</span> <span style="color: green; font-weight: bold;">public</span> TestEventListener
{
<span style="color: green; font-weight: bold;">public</span><span style="color: #666666;">:</span>
<span style="color: green; font-weight: bold;">explicit</span> TestEventListenerProxy(TestEventListener<span style="color: #666666;">*</span> event_listener);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #666666;">~</span>TestEventListenerProxy();
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestProgramStart(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestIterationStart(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test, <span style="color: #b00040;">int</span> iteration);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnEnvironmentsSetUpStart(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnEnvironmentsSetUpEnd(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestCaseStart(<span style="color: green; font-weight: bold;">const</span> TestCase<span style="color: #666666;">&</span> test_case);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestStart(<span style="color: green; font-weight: bold;">const</span> TestInfo<span style="color: #666666;">&</span> test_info);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestPartResult(<span style="color: green; font-weight: bold;">const</span> TestPartResult<span style="color: #666666;">&</span> result);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestEnd(<span style="color: green; font-weight: bold;">const</span> TestInfo<span style="color: #666666;">&</span> test_info);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestCaseEnd(<span style="color: green; font-weight: bold;">const</span> TestCase<span style="color: #666666;">&</span> test_case);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnEnvironmentsTearDownStart(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnEnvironmentsTearDownEnd(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestIterationEnd(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test, <span style="color: #b00040;">int</span> iteration);
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestProgramEnd(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> unit_test);
<span style="color: green; font-weight: bold;">protected</span><span style="color: #666666;">:</span>
TestEventListener<span style="color: #666666;">*</span> listener;
};</pre><br />
</div></td></tr>
</tbody></table>Then from this class I created the CaseSummaryAndFailurePrinter class. This class will override some of the TestEventListener methods with empty implementations to effectively remove the printing functionality of those methods. Then, in the OnTestEnd method, the default printer is only called in the event that the test failed. This class will then only print the overall summaries, case summaries and failed tests.<br />
<table class="highlighttable"><tbody>
<tr> <td><br />
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;"><br />
<pre style="line-height: 125%;">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17</pre><br />
</div><br />
</td> <td class="code"><br />
<div class="highlight" style="background: #f8f8f8;"><br />
<pre style="line-height: 125%;"><span style="color: green; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">CaseSummaryAndFailurePrinter</span> <span style="color: #666666;">:</span> <span style="color: green; font-weight: bold;">public</span> TestEventListenerProxy
{
<span style="color: green; font-weight: bold;">public</span><span style="color: #666666;">:</span>
<span style="color: green; font-weight: bold;">explicit</span> CaseSummaryAndFailurePrinter(TestEventListener<span style="color: #666666;">*</span> default_printer)
<span style="color: #666666;"> :</span> TestEventListenerProxy(default_printer)
{
}
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnEnvironmentsTearDownStart(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> <span style="color: #408080; font-style: italic;">/*unit_test*/</span>) { }
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnEnvironmentsSetUpStart(<span style="color: green; font-weight: bold;">const</span> UnitTest<span style="color: #666666;">&</span> <span style="color: #408080; font-style: italic;">/*unit_test*/</span>) { }
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestStart(<span style="color: green; font-weight: bold;">const</span> TestInfo<span style="color: #666666;">&</span> <span style="color: #408080; font-style: italic;">/*test_info*/</span>) { }
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestEnd(<span style="color: green; font-weight: bold;">const</span> TestInfo<span style="color: #666666;">&</span> test_info) {
<span style="color: green; font-weight: bold;"> if</span> (test_info.result()<span style="color: #666666;">-></span>Failed())
listener<span style="color: #666666;">-></span>OnTestEnd(test_info);
}
};</pre><br />
</div><br />
</td> </tr>
</tbody></table>I use the CaseSummaryAndFailurePrinter for integration style tests. These tests may take a while to run and having the case summaries printed allows you to see progress. Test cases are basically the tests defined in one C++ class.<br />
<br />
Finally, for unit tests I use the SummaryAndFailurePrinter class. This class extends CaseSummaryAndFailurePrinter and overrides the OnTestCaseStart and OnTestCaseEnd methods to remove the printing of the test case information. Thus for my 600+ unit test I see only the summary of the number of tests that were executed, and any that may have failed. This removes the verbosity of the default printer in gtest while still getting its functionality when needed.<br />
<br />
<table class="highlighttable"><tbody>
<tr><td><br />
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;"><br />
<pre style="line-height: 125%;">1
2
3
4
5
6
7
8
9
10
11</pre><br />
</div><br />
</td> <td class="code"><br />
<div class="highlight" style="background: #f8f8f8;"><br />
<pre style="line-height: 125%;"><span style="color: green; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">SummaryAndFailurePrinter</span> <span style="color: #666666;">:</span> <span style="color: green; font-weight: bold;">public</span> CaseSummaryAndFailurePrinter
{
<span style="color: green; font-weight: bold;">public</span><span style="color: #666666;">:</span>
<span style="color: green; font-weight: bold;">explicit</span> SummaryAndFailurePrinter(TestEventListener<span style="color: #666666;">*</span> default_printer)
<span style="color: #666666;"> :</span> CaseSummaryAndFailurePrinter(default_printer)
{
}
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestCaseStart(<span style="color: green; font-weight: bold;">const</span> TestCase<span style="color: #666666;">&</span> <span style="color: #408080; font-style: italic;">/*test_case*/</span>) { }
<span style="color: green; font-weight: bold;">virtual</span> <span style="color: #b00040;">void</span> OnTestCaseEnd(<span style="color: green; font-weight: bold;">const</span> TestCase<span style="color: #666666;">&</span> <span style="color: #408080; font-style: italic;">/*test_case*/</span>) { }
};</pre><br />
</div><br />
</td> </tr>
</tbody></table>The only thing left is to replaces the default printer in gtest with out wrapper. This can be accomplished in your main method with the following code:<br />
<br />
<table class="highlighttable"><tbody>
<tr> <td><br />
<div class="linenodiv" style="background-color: #f0f0f0; padding-right: 10px;"><br />
<pre style="line-height: 125%;">1
2
3
4
5
6
7
8
9
10</pre><br />
</div><br />
</td> <td class="code"><br />
<div class="highlight" style="background: #f8f8f8;"><br />
<pre style="line-height: 125%;">testing<span style="color: #666666;">::</span>InitGoogleTest(<span style="color: #666666;">&</span>argc, argv);
testing<span style="color: #666666;">::</span>InitGoogleMock(<span style="color: #666666;">&</span>argc, argv);
testing<span style="color: #666666;">::</span>TestEventListeners<span style="color: #666666;">&</span> listeners <span style="color: #666666;">=</span>
testing<span style="color: #666666;">::</span>UnitTest<span style="color: #666666;">::</span>GetInstance()<span style="color: #666666;">-></span>listeners();
<span style="color: green; font-weight: bold;">auto</span> default_printer <span style="color: #666666;">=</span> listeners.Release(listeners.default_result_printer());
listeners.Append(<span style="color: green; font-weight: bold;">new</span> SummaryAndFailurePrinter(default_printer));
<span style="color: green; font-weight: bold;">return</span> RUN_ALL_TESTS();</pre><br />
</div><br />
</td> </tr>
</tbody></table>As shown above, we can tell the TestEventListeners container to release ownership of the default printer. We can then wrap this default printer with a SummaryAndFailerPrinter and add that object to the TestEventListeners container.<br />
<br />
The more I use gtest and gmock the more impressed I am. This is by far the best C++ testing framework that I have ever seen. Great job google people!janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com4tag:blogger.com,1999:blog-8601661143216171909.post-15002510503672948162011-05-14T18:48:00.001-04:002011-05-14T18:48:03.490-04:00Going Agile…<p>I haven’t posted in a while because I started a new job.  The new job is an agile shop with a firm belief in software craftsmanship.  I had never worked on an agile team before so it was all new to me.  We use Test Driven Development (when possible), pair programming, and have a 2 week iteration cycle.  I say when possible about TDD because working in a C++ project with an approximately 3 minute compile time does not allow you to do TDD the way it was meant to be done.  The new gig is mostly a .NET shop but, as mentioned, they still have some C++ applications out there.  The interesting thing is that not many of the team members had any real experience with C++.  It is a youngish team that mostly started with C# and .NET, with a few that have some Java experience.  C++ frustrates these people so much, it is kind of funny to sit back and watch.  I get the feeling that the C++ code is a major reason that I was pulled in to this team. </p> <p>I have been busy learning the new code base.  Now about 3 iterations in, I believe that I am adding a lot of value to the team.  The one major omission with this job is that they do not use, and don’t plan on using, Python.  I will miss using Python at work.  Any new software is to be done in C# on the .NET platform.  Not that there is any real dependency on Microsoft, this is just team policy. A well respected contractor tried to turn the team on to Ruby, but so far nothing has come of it.</p> <p>The team has been reading “Clean Code” by Robert C. Martin.  There is a weekly book club meeting where we discuss a chapter of the book.  This is part of the software craftsmanship initiative.  I think this is a great idea and it helps to improve the quality of all of the software developers.  We will be reading a TDD book after we finish the clean code book.</p> <p>I hope to get back to writing one post a month.  This was my initial goal for this blog.  Time flies when your coding!</p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com1tag:blogger.com,1999:blog-8601661143216171909.post-51308994646276772292011-02-21T09:19:00.001-05:002011-02-21T09:19:32.033-05:00Python 3.2 Released<p>On Sunday February 20th Python 3.2 was released. Normally I wouldn’t mention when a new point release of Python, but this one is special to me.  It is the first release of Python in which I have played a (very small) part.  </p> <p>A while ago, I was playing around with Python’s multiprocessing module which, at the time, was new to me.  All of the simple examples that I found would use the os.getpid() and os.getppid() functions to show that the spawned process was indeed a child of the initial Python process.  The problem is that on the Windows platform, os.getppid() was not implemented.  I downloaded a zip of the source code and within a hour I had a working implementation of os.getppid() and could run the samples, great.  Time goes by, and I start to think about contributing my implementation to the actual Python source code.  I had no idea how to go about and do such a thing.  Fortunately, the <a href="http://docs.python.org/devguide/" target="_blank">Python developer guide</a> has wonderful documentation on how you can contribute.  So, I created an issue for os.getppid() on Windows, stumbled through the process of creating a patch, submitted the patch, and then waited.  A core Python developer picked up the issue and told me that I would have to provide a unit test before any check-in would happen.  This meant I would have to spelunk through the source tree to find the unit tests and implement a meaningful test for this.  Well, you all know how life happens, time goes by, and I actually forgot that I had even created this issue.  Eventually I received an email from a core Python developer that moved the issues from the 2.x branch of Python to the 3.x branch.  I got back involved, implemented the unit test and the documentation changes, submitted all the patches and before I knew it, the code was checked in and the issue was closed.</p> <p>About this time Tim Golden <a href="http://ramblings.timgolden.me.uk/2010/08/16/im-a-windows-person-how-can-i-contribute-to-python-part-i/" target="_blank">posted a call out to Windows developers</a> to help contribute to Python.  I looked around for other issues to work on.  I ended up being involved on two other issues for Python 3.2 (on Windows).  First, I implemented os.getlogin().  It was just another os module function not available on Windows.  Then, I fixed a bug in the generation of .pyc files.  There was a call to _mkdir to create a directory.  The signature of this function on Windows has one less parameter than on *Nix systems.  Thus, every time _mkdir was called it would push an extra parameter on the stack that was not used.  Being that it is using the C calling convention, the caller cleans the stack, so the extra parameter was actually cleaned up off the stack.  Thus, this was a very minor issue that most likely wouldn’t have caused any problems, but I fixed it anyway.</p> <p>I would like to write a more in-depth entry about my experience contributing to Python.  I would also like to get involved again in more issues.  Most likely one at a time because:  It can be time consuming, no one is going to pay you, and you must work on the issues on your own time.  It is also great fun and a learning experience.  I think every professional developer should be involved in some open source project.  There are many open source projects, even in the Windows and .NET worlds too (<a href="http://www.nunit.org/" target="_blank">NUnit</a>, <a href="http://nhforge.org/Default.aspx" target="_blank">NHibernate</a>, <a href="http://ironpython.net/" target="_blank">IronPython</a>, <a href="http://ironruby.codeplex.com/" target="_blank">IronRuby</a>, checkout <a href="http://www.codeplex.com/" target="_blank">codeplex</a>).  Go find an open source project and grab an issue from the issue tracker and go for it!       </p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-34919007142707867192011-02-18T14:44:00.004-05:002011-02-21T10:40:09.627-05:00Essential OperatingSystem ExtensionsThere are times that you may need to determine which version of Windows your program is running upon. In the .NET Framework there is the System.OperatingSystem class that provides many of these details. You can acquire an instance of this class via the System.Environment.OSVersion property. The OperatingSystem class will tell you essential details like the major and minor version numbers, the revision and build numbers, and even the service pack version (if any) installed on the computer. There is also a PlatformID property that will tell you the platform type. This is an enumeration of the various supported platforms. If you look this up in the <a href="http://msdn.microsoft.com/en-us/library/3a8hyw88.aspx" target="_blank">MSDN Documentation</a>, you may be surprised to find values such as: Win32S, Win32Windows (were talking Windows 95, 98, ME), WinCE, Xbox, MacOSX and even Unix! Most commonly this value will be Win32NT as this is used for Windows 2000, XP, server 2003, server 2008, and 7. These are the NT line of the Windows operating system. Generally this is the information that your program needs for most purposes like a diagnostic report. <br />
Missing from the OperatingSystem class is any method or property that would tell me if I am running on a server operating system. I recently had a need to know this information, thus I had to resort to using platform invoke to call into some native Windows functions. I used the extension method mechanism to integrate my methods with the OperatingSystem class. Here is my IsServer extension method. <br />
<div class="highlight" style="background: #f8f8f8;"><pre style="line-height: 125%;"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: green; font-weight: bold;">class</span> <span style="color: blue; font-weight: bold;">OSExtensions</span>
<span class="lineno"> 2</span> {
<span class="lineno"> 3</span> <span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: #b00040;">bool</span> <span style="color: blue;">IsServer</span>(<span style="color: green; font-weight: bold;">this</span> OperatingSystem Os)
<span class="lineno"> 4</span> {
<span class="lineno"> 5</span> var osinfo = <span style="color: green; font-weight: bold;">new</span> OSVERSIONINFOEX();
<span class="lineno"> 6</span> osinfo.dwOSVersionInfoSize = (UInt32)Marshal.SizeOf(osinfo);
<span class="lineno"> 7</span>
<span class="lineno"> 8</span> <span style="color: green; font-weight: bold;">if</span> (GetVersionEx(<span style="color: green; font-weight: bold;">ref</span> osinfo))
<span class="lineno"> 9</span> {
<span class="lineno">10</span> <span style="color: green; font-weight: bold;">return</span> (VER_NT_WORKSTATION != osinfo.wProductType);
<span class="lineno">11</span> }
<span class="lineno">12</span>
<span class="lineno">13</span> <span style="color: green; font-weight: bold;">throw</span> <span style="color: green; font-weight: bold;">new</span> <span style="color: blue;">Win32Exception</span>();
<span class="lineno">14</span> }
<span class="lineno">15</span> }</pre></div><br />
You can see that this is a simple method that calls the Win32 API GetVersionEx to get even more useful version information. This function provides a wealth of information about the underlying Windows installation. In this function, I look at the wProductType field of the OSVERSIONINFORMATIONEX structure to see if its value is not VER_NT_WORKSTATION. The wProductType field can be one of the following values: VER_NT_WORKSTATION, VER_NT_SERVER, or VER_NT_DOMAIN_CONTROLLER. Thus if the value is not VER_NT_WORKSTATION then I must be on a server (a domain controller is a server). Below is some of the interop code that makes this work. <br />
<br />
<div class="highlight" style="background: #f8f8f8;"><pre style="line-height: 125%;"><span class="lineno"> 1</span> <span style="color: #7d9029;">[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]</span>
<span class="lineno"> 2</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">struct</span> <span style="color: blue; font-weight: bold;">OSVERSIONINFOEX</span>
<span class="lineno"> 3</span> {
<span class="lineno"> 4</span> <span style="color: green; font-weight: bold;">public</span> UInt32 dwOSVersionInfoSize;
<span class="lineno"> 5</span> <span style="color: green; font-weight: bold;">public</span> UInt32 dwMajorVersion;
<span class="lineno"> 6</span> <span style="color: green; font-weight: bold;">public</span> UInt32 dwMinorVersion;
<span class="lineno"> 7</span> <span style="color: green; font-weight: bold;">public</span> UInt32 dwBuildNumber;
<span class="lineno"> 8</span> <span style="color: green; font-weight: bold;">public</span> UInt32 dwPlatformId;
<span class="lineno"> 9</span> <span style="color: #7d9029;"> [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]</span>
<span class="lineno">10</span> <span style="color: green; font-weight: bold;">public</span> <span style="color: #b00040;">string</span> szCSDVersion;
<span class="lineno">11</span> <span style="color: green; font-weight: bold;">public</span> Int16 wServicePackMajor;
<span class="lineno">12</span> <span style="color: green; font-weight: bold;">public</span> Int16 wServicePackMinor;
<span class="lineno">13</span> <span style="color: green; font-weight: bold;">public</span> Int16 wSuiteMask;
<span class="lineno">14</span> <span style="color: green; font-weight: bold;">public</span> SByte wProductType;
<span class="lineno">15</span> <span style="color: green; font-weight: bold;">public</span> SByte wReserved;
<span class="lineno">16</span> }
<span class="lineno">17</span>
<span class="lineno">18</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">const</span> SByte VER_NT_WORKSTATION = <span style="color: #666666;">0</span>x01;
<span class="lineno">19</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">const</span> SByte VER_NT_DOMAIN_CONTROLLER = <span style="color: #666666;">0</span>x02;
<span class="lineno">20</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">const</span> SByte VER_NT_SERVER = <span style="color: #666666;">0</span>x03;
<span class="lineno">21</span>
<span class="lineno">22</span> <span style="color: #7d9029;">[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]</span>
<span class="lineno">23</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: green; font-weight: bold;">extern</span> <span style="color: #b00040;">bool</span> <span style="color: blue;">GetVersionEx</span>(
<span class="lineno">24</span> <span style="color: green; font-weight: bold;">ref</span> OSVERSIONINFOEX lpVersionInfo
<span class="lineno">25</span> );</pre></div><br />
I placed these items in the OSExtensions class as well. The MSDN documentation for <a href="http://msdn.microsoft.com/en-us/library/ms724833(v=VS.85).aspx" target="_blank">OSVERSIONINFOEX</a> will show you all of the interesting information you can retrieve if needed. <br />
<br />
Another piece of information you may want is the friendly name of the operating system. The OperatingSystem class includes a VersionString property that will give you the information, but not in the format that you may desire. Yes, telling your users that the OS is “Microsoft Windows NT 6.1.7600.0” is precise, but the end user of your software will tell you, “No, I’m running Windows 7.” Below is the Name extension method. It is not exhaustive, but it covers all of the cases in which my software was interested. If the friendly name is not determined, it returns the same value as the VersionString property.<br />
<br />
<div class="highlight" style="background: #f8f8f8;"><pre style="line-height: 125%;"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold;">public</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: #b00040;">string</span> <span style="color: blue;">Name</span>(<span style="color: green; font-weight: bold;">this</span> OperatingSystem Os)
<span class="lineno"> 2</span> {
<span class="lineno"> 3</span> <span style="color: #b00040;">string</span> name = String.Empty;
<span class="lineno"> 4</span> <span style="color: green; font-weight: bold;">if</span> (PlatformID.Win32Windows == Os.Platform)
<span class="lineno"> 5</span> {
<span class="lineno"> 6</span> name = GetLegacyName(Os);
<span class="lineno"> 7</span> }
<span class="lineno"> 8</span> <span style="color: green; font-weight: bold;">else</span> <span style="color: blue;">if</span> (PlatformID.Win32NT == Os.Platform)
<span class="lineno"> 9</span> {
<span class="lineno">10</span> <span style="color: green; font-weight: bold;">if</span> (Os.IsServer())
<span class="lineno">11</span> name = GetServerName(Os);
<span class="lineno">12</span> <span style="color: green; font-weight: bold;">else</span>
<span class="lineno">13</span> name = GetWorkstationName(Os);
<span class="lineno">14</span> }
<span class="lineno">15</span>
<span class="lineno">16</span> <span style="color: green; font-weight: bold;">if</span> (String.IsNullOrEmpty(name))
<span class="lineno">17</span> <span style="color: green; font-weight: bold;">return</span> Os.VersionString;
<span class="lineno">18</span> <span style="color: green; font-weight: bold;">else</span>
<span class="lineno">19</span> <span style="color: green; font-weight: bold;">return</span> String.Format(<span style="color: #ba2121;">"{0}, {1}"</span>, name, Os.Version.ToString());
<span class="lineno">20</span> }
<span class="lineno">21</span>
<span class="lineno">22</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: #b00040;">string</span> <span style="color: blue;">GetLegacyName</span>(OperatingSystem Os)
<span class="lineno">23</span> {
<span class="lineno">24</span> <span style="color: #b00040;">string</span> name = String.Empty;
<span class="lineno">25</span> <span style="color: green; font-weight: bold;">switch</span> (Os.Version.Minor)
<span class="lineno">26</span> {
<span class="lineno">27</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">0</span>:
<span class="lineno">28</span> name = <span style="color: #ba2121;">"Windows 95"</span>;
<span class="lineno">29</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">30</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">10</span>:
<span class="lineno">31</span> name = <span style="color: #ba2121;">"Windows 98"</span>;
<span class="lineno">32</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">33</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">90</span>:
<span class="lineno">34</span> name = <span style="color: #ba2121;">"Windows ME"</span>;
<span class="lineno">35</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">36</span> }
<span class="lineno">37</span>
<span class="lineno">38</span> <span style="color: green; font-weight: bold;">return</span> name;
<span class="lineno">39</span> }
<span class="lineno">40</span>
<span class="lineno">41</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: #b00040;">string</span> <span style="color: blue;">GetServerName</span>(OperatingSystem Os)
<span class="lineno">42</span> {
<span class="lineno">43</span> <span style="color: #b00040;">string</span> name = String.Empty;
<span class="lineno">44</span> <span style="color: green; font-weight: bold;">switch</span> (Os.Version.Major)
<span class="lineno">45</span> {
<span class="lineno">46</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">3</span>:
<span class="lineno">47</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">4</span>:
<span class="lineno">48</span> name = <span style="color: #ba2121;">"Windows NT Server"</span>;
<span class="lineno">49</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">50</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">5</span>:
<span class="lineno">51</span> <span style="color: green; font-weight: bold;">if</span> (Os.Version.Minor == <span style="color: #666666;">0</span>)
<span class="lineno">52</span> name = <span style="color: #ba2121;">"Windows 2000 Server"</span>;
<span class="lineno">53</span> <span style="color: green; font-weight: bold;">else</span> <span style="color: blue;">if</span> (Os.Version.Minor == <span style="color: #666666;">2</span>)
<span class="lineno">54</span> {
<span class="lineno">55</span> <span style="color: green; font-weight: bold;">if</span> (<span style="color: #666666;">0</span> == GetSystemMetrics(SM_SERVERR2))
<span class="lineno">56</span> name = <span style="color: #ba2121;">"Windows Server 2003"</span>;
<span class="lineno">57</span> <span style="color: green; font-weight: bold;">else</span>
<span class="lineno">58</span> name = <span style="color: #ba2121;">"Windows Server 2003 R2"</span>;
<span class="lineno">59</span> }
<span class="lineno">60</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">61</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">6</span>:
<span class="lineno">62</span> <span style="color: green; font-weight: bold;">if</span> (Os.Version.Minor == <span style="color: #666666;">0</span>)
<span class="lineno">63</span> name = <span style="color: #ba2121;">"Windows Server 2008"</span>;
<span class="lineno">64</span> <span style="color: green; font-weight: bold;">else</span> <span style="color: blue;">if</span> (Os.Version.Minor == <span style="color: #666666;">1</span>)
<span class="lineno">65</span> name = <span style="color: #ba2121;">"Windows Server 2008 R2"</span>;
<span class="lineno">66</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">67</span> }
<span class="lineno">68</span>
<span class="lineno">69</span> <span style="color: green; font-weight: bold;">return</span> name;
<span class="lineno">70</span> }
<span class="lineno">71</span>
<span class="lineno">72</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: #b00040;">string</span> <span style="color: blue;">GetWorkstationName</span>(OperatingSystem Os)
<span class="lineno">73</span> {
<span class="lineno">74</span> <span style="color: #b00040;">string</span> name = String.Empty;
<span class="lineno">75</span> <span style="color: green; font-weight: bold;">switch</span> (Os.Version.Major)
<span class="lineno">76</span> {
<span class="lineno">77</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">3</span>:
<span class="lineno">78</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">4</span>:
<span class="lineno">79</span> name = <span style="color: #ba2121;">"Windows NT"</span>;
<span class="lineno">80</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">81</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">5</span>:
<span class="lineno">82</span> <span style="color: green; font-weight: bold;">if</span> (Os.Version.Minor == <span style="color: #666666;">0</span>)
<span class="lineno">83</span> name = <span style="color: #ba2121;">"Windows 2000"</span>;
<span class="lineno">84</span> <span style="color: green; font-weight: bold;">else</span> <span style="color: blue;">if</span> (Os.Version.Minor == <span style="color: #666666;">1</span>)
<span class="lineno">85</span> name = <span style="color: #ba2121;">"Windows XP"</span>;
<span class="lineno">86</span> <span style="color: green; font-weight: bold;">else</span> <span style="color: blue;">if</span> (Os.Version.Minor == <span style="color: #666666;">2</span>)
<span class="lineno">87</span> name = <span style="color: #ba2121;">"Windows XP x64"</span>;
<span class="lineno">88</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">89</span> <span style="color: green; font-weight: bold;">case</span> <span style="color: #666666;">6</span>:
<span class="lineno">90</span> <span style="color: green; font-weight: bold;">if</span> (Os.Version.Minor == <span style="color: #666666;">0</span>)
<span class="lineno">91</span> name = <span style="color: #ba2121;">"Windows Vista"</span>;
<span class="lineno">92</span> <span style="color: green; font-weight: bold;">else</span> <span style="color: blue;">if</span> (Os.Version.Minor == <span style="color: #666666;">1</span>)
<span class="lineno">93</span> name = <span style="color: #ba2121;">"Windows 7"</span>;
<span class="lineno">94</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">95</span> }
<span class="lineno">96</span>
<span class="lineno">97</span> <span style="color: green; font-weight: bold;">return</span> name;
<span class="lineno">98</span> }</pre></div><br />
There was a little more interop code required to make this work. This code allows you to retrieve the value of the SM_SERVERR2 flag, which if non-zero means you are running the R2 variant of Windows Server 2003. Here is the code. <br />
<br />
<div class="highlight" style="background: #f8f8f8;"><pre style="line-height: 125%;"><span class="lineno">1</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">const</span> <span style="color: #b00040;">int</span> SM_SERVERR2 = <span style="color: #666666;">89</span>;
<span class="lineno">2</span>
<span class="lineno">3</span> <span style="color: #7d9029;">[DllImport("User32.dll", SetLastError = false)]</span>
<span class="lineno">4</span> <span style="color: green; font-weight: bold;">private</span> <span style="color: green; font-weight: bold;">static</span> <span style="color: green; font-weight: bold;">extern</span> <span style="color: #b00040;">int</span> <span style="color: blue;">GetSystemMetrics</span>(<span style="color: #b00040;">int</span> nIndex);</pre></div><br />
Through the use of extension methods and a little p/invoke we are able to determine if a .NET program is running on a server OS and provide a more friendly name that could be displayed to the user. Until next time.janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com2tag:blogger.com,1999:blog-8601661143216171909.post-72438861592224890662011-02-05T16:22:00.003-05:002013-02-09T21:44:39.375-05:00Using Encrypted Data Between Python and SilverlightI had a chance to work on a project in which data was encrypted and shared between a Python program on the server side and a Silverlight .NET Framework application on the client side.  Both programming environments offer a rich set of libraries for doing data encryption.  On the Python side I chose to use the excellent <a href="http://www.dlitz.net/software/pycrypto/" target="_blank">PyCrypto</a> library.  At the time that I wrote the code I was using version 2.1 of PyCrypto and version 2.7 of Python.  PyCrypto is in the public domain from the way I understand the license files.  On the .NET side, the System.Security.Cryptography namespace provides the classes needed.  In a Silverlight application the System.Security.Cryptography namespace is much, much smaller than in the full .NET Framework.  Thus AES would have to be the encryption algorithm used.  <br />AES is the Rijndael symmetric algorithm with a fixed block size (128 bits) and iteration count. For the <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.aesmanaged(v=VS.95).aspx" target="_blank">Silverlight version</a> of this algorithm the cipher mode and padding mode are CBC and PKCS7 respectively and can not be changed.  Padding is used to ensure that the data to be encrypted is a multiple of the block size.  <br />Here is an example of encrypting the data in Python. You can find the code in this article on <a href="https://github.com/janglin/crypto-pkcs7-example" target="_blank">GitHub.</a>  Obviously, you will need to have <a href="http://python.org/download" target="_blank">Python</a> and PyCrypto installed to use it. <br /> <div style="background: #f8f8f8" class="highlight"> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold">from</span> <span style="color: blue; font-weight: bold">Crypto.Cipher</span> <span style="color: green; font-weight: bold">import</span> AES<br /><span class="lineno"> 2</span> <span style="color: green; font-weight: bold">from</span> <span style="color: blue; font-weight: bold">pkcs7</span> <span style="color: green; font-weight: bold">import</span> PKCS7Encoder<br /><span class="lineno"> 3</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">base64</span><br /><span class="lineno"> 4</span> <br /><span class="lineno"> 5</span> key <span style="color: #666666">=</span> <span style="color: #ba2121">'your key 16bytes'</span><br /><span class="lineno"> 6</span> <span style="font-style: italic; color: #408080"># 16 byte initialization vector</span><br /><span class="lineno"> 7</span> iv <span style="color: #666666">=</span> <span style="color: #ba2121">'1234567812345678'</span><br /><span class="lineno"> 8</span> <br /><span class="lineno"> 9</span> aes <span style="color: #666666">=</span> AES<span style="color: #666666">.</span>new(key, AES<span style="color: #666666">.</span>MODE_CBC, iv)<br /><span class="lineno">10</span> encoder <span style="color: #666666">=</span> PKCS7Encoder()<br /><span class="lineno">11</span> <br /><span class="lineno">12</span> text <span style="color: #666666">=</span> <span style="color: #ba2121">'This is my plain text'</span><br /><span class="lineno">13</span> <br /><span class="lineno">14</span> <span style="font-style: italic; color: #408080"># pad the plain text according to PKCS7</span><br /><span class="lineno">15</span> pad_text <span style="color: #666666">=</span> encoder<span style="color: #666666">.</span>encode(text)<br /><span class="lineno">16</span> <span style="font-style: italic; color: #408080"># encrypt the padding text</span><br /><span class="lineno">17</span> cipher <span style="color: #666666">=</span> aes<span style="color: #666666">.</span>encrypt(pad_text)<br /><span class="lineno">18</span> <span style="font-style: italic; color: #408080"># base64 encode the cipher text for transport</span><br /><span class="lineno">19</span> enc_cipher <span style="color: #666666">=</span> base64<span style="color: #666666">.</span>b64encode(cipher)<br /><span class="lineno">20</span> <br /><span class="lineno">21</span> <span style="color: green; font-weight: bold">print</span> enc_cipher</pre><br /><br /> <br /></div><br />The data to be encrypted is first run through the padding encoder.  This will ensure that the data is a multiple of the block size (16 bytes in this case).  Note that even if the data is already the correct size it is still padded.  The data is always padded thus the padding must always need to be removed.  This alleviates the programmer from having to know if the data is padded or not. This program will print the following encoded string: ZeYXkFf8wPbvzdC91V4adwx4U56o2zMMOathdDYuBOE= <br /><br /><br /><br /><br /><br />The PKCS7 padding code is built in to the Silverlight AesManaged class.  On the Python side, I had to write this my self.  PKCS7 is described in <a href="http://www.ietf.org/rfc/rfc2315.txt" target="_blank">RFC 2315</a> and is actually very simple, here is the code.<br /><br /><br /><br /><br /><br /><br /><br /><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">binascii</span><br /><span class="lineno"> 2</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">StringIO</span><br /><span class="lineno"> 3</span> <br /><span class="lineno"> 4</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">PKCS7Encoder</span>(<span style="color: green">object</span>):<br /><span class="lineno"> 5</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno"> 6</span> <span style="font-style: italic; color: #ba2121"> RFC 2315: PKCS#7 page 21</span><br /><span class="lineno"> 7</span> <span style="font-style: italic; color: #ba2121"> Some content-encryption algorithms assume the</span><br /><span class="lineno"> 8</span> <span style="font-style: italic; color: #ba2121"> input length is a multiple of k octets, where k > 1, and</span><br /><span class="lineno"> 9</span> <span style="font-style: italic; color: #ba2121"> let the application define a method for handling inputs</span><br /><span class="lineno">10</span> <span style="font-style: italic; color: #ba2121"> whose lengths are not a multiple of k octets. For such</span><br /><span class="lineno">11</span> <span style="font-style: italic; color: #ba2121"> algorithms, the method shall be to pad the input at the</span><br /><span class="lineno">12</span> <span style="font-style: italic; color: #ba2121"> trailing end with k - (l mod k) octets all having value k -</span><br /><span class="lineno">13</span> <span style="font-style: italic; color: #ba2121"> (l mod k), where l is the length of the input. In other</span><br /><span class="lineno">14</span> <span style="font-style: italic; color: #ba2121"> words, the input is padded at the trailing end with one of</span><br /><span class="lineno">15</span> <span style="font-style: italic; color: #ba2121"> the following strings:</span><br /><span class="lineno">16</span> <br /><span class="lineno">17</span> <span style="font-style: italic; color: #ba2121"> 01 -- if l mod k = k-1</span><br /><span class="lineno">18</span> <span style="font-style: italic; color: #ba2121"> 02 02 -- if l mod k = k-2</span><br /><span class="lineno">19</span> <span style="font-style: italic; color: #ba2121"> .</span><br /><span class="lineno">20</span> <span style="font-style: italic; color: #ba2121"> .</span><br /><span class="lineno">21</span> <span style="font-style: italic; color: #ba2121"> .</span><br /><span class="lineno">22</span> <span style="font-style: italic; color: #ba2121"> k k ... k k -- if l mod k = 0</span><br /><span class="lineno">23</span> <br /><span class="lineno">24</span> <span style="font-style: italic; color: #ba2121"> The padding can be removed unambiguously since all input is</span><br /><span class="lineno">25</span> <span style="font-style: italic; color: #ba2121"> padded and no padding string is a suffix of another. This</span><br /><span class="lineno">26</span> <span style="font-style: italic; color: #ba2121"> padding method is well-defined if and only if k < 256;</span><br /><span class="lineno">27</span> <span style="font-style: italic; color: #ba2121"> methods for larger k are an open issue for further study.</span><br /><span class="lineno">28</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno">29</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">__init__</span>(<span style="color: green">self</span>, k<span style="color: #666666">=16</span>):<br /><span class="lineno">30</span> <span style="color: green">self</span><span style="color: #666666">.</span>k <span style="color: #666666">=</span> k<br /><span class="lineno">31</span> <br /><span class="lineno">32</span> <span style="font-style: italic; color: #408080">## @param text The padded text for which the padding is to be removed.</span><br /><span class="lineno">33</span> <span style="font-style: italic; color: #408080"># @exception ValueError Raised when the input padding is missing or corrupt.</span><br /><span class="lineno">34</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">decode</span>(<span style="color: green">self</span>, text):<br /><span class="lineno">35</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno">36</span> <span style="font-style: italic; color: #ba2121"> Remove the PKCS#7 padding from a text string</span><br /><span class="lineno">37</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno">38</span> nl <span style="color: #666666">=</span> <span style="color: green">len</span>(text)<br /><span class="lineno">39</span> val <span style="color: #666666">=</span> <span style="color: green">int</span>(binascii<span style="color: #666666">.</span>hexlify(text[<span style="color: #666666">-1</span>]), <span style="color: #666666">16</span>)<br /><span class="lineno">40</span> <span style="color: green; font-weight: bold">if</span> val <span style="color: #666666">></span> <span style="color: green">self</span><span style="color: #666666">.</span>k:<br /><span class="lineno">41</span> <span style="color: green; font-weight: bold">raise</span> <span style="color: #d2413a; font-weight: bold">ValueError</span>(<span style="color: #ba2121">'Input is not padded or padding is corrupt'</span>)<br /><span class="lineno">42</span> <br /><span class="lineno">43</span> l <span style="color: #666666">=</span> nl <span style="color: #666666">-</span> val<br /><span class="lineno">44</span> <span style="color: green; font-weight: bold">return</span> text[:l]<br /><span class="lineno">45</span> <br /><span class="lineno">46</span> <span style="font-style: italic; color: #408080">## @param text The text to encode.</span><br /><span class="lineno">47</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">encode</span>(<span style="color: green">self</span>, text):<br /><span class="lineno">48</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno">49</span> <span style="font-style: italic; color: #ba2121"> Pad an input string according to PKCS#7</span><br /><span class="lineno">50</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno">51</span> l <span style="color: #666666">=</span> <span style="color: green">len</span>(text)<br /><span class="lineno">52</span> output <span style="color: #666666">=</span> StringIO<span style="color: #666666">.</span>StringIO()<br /><span class="lineno">53</span> val <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>k <span style="color: #666666">-</span> (l <span style="color: #666666">%</span> <span style="color: green">self</span><span style="color: #666666">.</span>k)<br /><span class="lineno">54</span> <span style="color: green; font-weight: bold">for</span> _ <span style="color: #aa22ff; font-weight: bold">in</span> <span style="color: green">xrange</span>(val):<br /><span class="lineno">55</span> output<span style="color: #666666">.</span>write(<span style="color: #ba2121">'</span><span style="color: #bb6688; font-weight: bold">%02x</span><span style="color: #ba2121">'</span> <span style="color: #666666">%</span> val)<br /><span class="lineno">56</span> <span style="color: green; font-weight: bold">return</span> text <span style="color: #666666">+</span> binascii<span style="color: #666666">.</span>unhexlify(output<span style="color: #666666">.</span>getvalue())</pre><br /><br /> <br /></div><br />Remember that each time the AES key is used to encrypt/decrypt a block of data, the internal state of the key changes.  Thus each time you are preparing encrypted data to transmit to the server you must create a new AES key object from the original key and iv or that data will not be properly transformed.  The server will also have to create a new AES key with the original data as well. If you do not, you will have a hard time keeping the server and client AES keys in sync and data will not be transformed properly on either side. <br /><br /><br /><br /><br /><br />Decryption on the Silverlight side is very straight forward.  I am presenting this here as a console based program but there should not be any relevant difference when used in a Silverlight program.<br /><br /><br /><br /><br /><br /><br /><br /><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold">using</span> <span style="color: blue; font-weight: bold">System</span>;<br /><span class="lineno"> 2</span> <span style="color: green; font-weight: bold">using</span> <span style="color: blue; font-weight: bold">System.Text</span>;<br /><span class="lineno"> 3</span> <span style="color: green; font-weight: bold">using</span> <span style="color: blue; font-weight: bold">System.Security.Cryptography</span>;<br /><span class="lineno"> 4</span> <br /><span class="lineno"> 5</span> <span style="color: green; font-weight: bold">namespace</span> <span style="color: blue; font-weight: bold">AesTest</span><br /><span class="lineno"> 6</span> {<br /><span class="lineno"> 7</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">Program</span><br /><span class="lineno"> 8</span> {<br /><span class="lineno"> 9</span> <span style="color: green; font-weight: bold">static</span> <span style="color: green; font-weight: bold">void</span> <span style="color: blue">Main</span>(<span style="color: #b00040">string</span>[] args)<br /><span class="lineno">10</span> {<br /><span class="lineno">11</span> <span style="font-style: italic; color: #408080">// This was the output of our Python program.</span><br /><span class="lineno">12</span> <span style="color: #b00040">string</span> enc_cipher = <span style="color: #ba2121">"ZeYXkFf8wPbvzdC91V4adwx4U56o2zMMOathdDYuBOE="</span>;<br /><span class="lineno">13</span> <br /><span class="lineno">14</span> var textEncoder = <span style="color: green; font-weight: bold">new</span> UTF8Encoding();<br /><span class="lineno">15</span> <br /><span class="lineno">16</span> <span style="font-style: italic; color: #408080">// defaults to CBC and PKCS7</span><br /><span class="lineno">17</span> var aes = <span style="color: green; font-weight: bold">new</span> AesManaged();<br /><span class="lineno">18</span> aes.Key = textEncoder.GetBytes(<span style="color: #ba2121">"your key 16bytes"</span>);<br /><span class="lineno">19</span> aes.IV = textEncoder.GetBytes(<span style="color: #ba2121">"1234567812345678"</span>);<br /><span class="lineno">20</span> <br /><span class="lineno">21</span> var decryptor = aes.CreateDecryptor();<br /><span class="lineno">22</span> var cipher = Convert.FromBase64String(enc_cipher);<br /><span class="lineno">23</span> var text_bytes = decryptor.TransformFinalBlock(cipher, <span style="color: #666666">0</span>, cipher.Length);<br /><span class="lineno">24</span> <br /><span class="lineno">25</span> var text = textEncoder.GetString(text_bytes);<br /><span class="lineno">26</span> <span style="font-style: italic; color: #408080">// Should print 'This is my plain text'</span><br /><span class="lineno">27</span> Console.WriteLine(text);<br /><span class="lineno">28</span> }<br /><span class="lineno">29</span> }<br /><span class="lineno">30</span> }</pre><br /><br /> <br /></div><br />It should be easy for any programmer to reverse the process so the the Silverlight client encrypts data that is then decrypted on the python side.  The hard part here is the age old problem of how you share the key to the symmetric encryption algorithm.  For this we used RSA public key cryptography.<br /><br /><br /><br /><br /><br />PyCrypto once again comes to the rescue as it includes RSA encryption classes, for the most part.  Once again I had to write a padding encoder/decoder to be used along with the RSA classes. RSA can use a variety of padding schemes like PKCS#1 v1.5, and OAEP (optimal asymmetric encryption padding), with OAEP being recommended for new applications.  I wrapped the Crypto.PublicKey.RSA class in my own RSAkey class shown below.  As you can see in the code the data is padded, encrypted, and then base64 encoded.  The data can easily be transmitted via web protocols when it is base64 encoded.<br /><br /><br /><br /><br /><br /><br /><br /><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold">from</span> <span style="color: blue; font-weight: bold">Crypto.PublicKey</span> <span style="color: green; font-weight: bold">import</span> RSA<br /><span class="lineno"> 2</span> <span style="color: green; font-weight: bold">from</span> <span style="color: blue; font-weight: bold">pkcs1</span> <span style="color: green; font-weight: bold">import</span> OAEPEncoder<br /><span class="lineno"> 3</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">base64</span><br /><span class="lineno"> 4</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">binascii</span><br /><span class="lineno"> 5</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">os</span><br /><span class="lineno"> 6</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">pickle</span><br /><span class="lineno"> 7</span> <br /><span class="lineno"> 8</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">RSAKey</span>(<span style="color: green">object</span>):<br /><span class="lineno"> 9</span> <br /><span class="lineno">10</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">__init__</span>(<span style="color: green">self</span>, keybitsize, encoder<span style="color: #666666">=</span>OAEPEncoder()):<br /><span class="lineno">11</span> <span style="color: green">self</span><span style="color: #666666">.</span>_encoder <span style="color: #666666">=</span> encoder<br /><span class="lineno">12</span> <span style="color: green">self</span><span style="color: #666666">.</span>_keysize <span style="color: #666666">=</span> keybitsize<br /><span class="lineno">13</span> <span style="color: green">self</span><span style="color: #666666">.</span>_key <span style="color: #666666">=</span> RSA<span style="color: #666666">.</span>generate(keybitsize, os<span style="color: #666666">.</span>urandom)<br /><span class="lineno">14</span> <br /><span class="lineno">15</span> <span style="color: #aa22ff">@property</span><br /><span class="lineno">16</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">key</span>(<span style="color: green">self</span>):<br /><span class="lineno">17</span> <span style="color: green; font-weight: bold">return</span> <span style="color: green">self</span><span style="color: #666666">.</span>_key<br /><span class="lineno">18</span> <br /><span class="lineno">19</span> <span style="color: #aa22ff">@property</span><br /><span class="lineno">20</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">key_size</span>(<span style="color: green">self</span>):<br /><span class="lineno">21</span> <span style="color: green; font-weight: bold">return</span> <span style="color: green">self</span><span style="color: #666666">.</span>_keysize<br /><span class="lineno">22</span> <br /><span class="lineno">23</span> <span style="font-style: italic; color: #408080">## Get the public RSA key used to encrypt data as</span><br /><span class="lineno">24</span> <span style="font-style: italic; color: #408080"># an XML string.</span><br /><span class="lineno">25</span> <span style="font-style: italic; color: #408080"># @param xml_format True if the key should be returned as XML.</span><br /><span class="lineno">26</span> <span style="font-style: italic; color: #408080"># If False, the key is returned as a base64 encoded pickled </span><br /><span class="lineno">27</span> <span style="font-style: italic; color: #408080"># Python object.</span><br /><span class="lineno">28</span> <span style="font-style: italic; color: #408080"># @return: An XML string representation of the </span><br /><span class="lineno">29</span> <span style="font-style: italic; color: #408080"># public RSA key. Each node is a base64</span><br /><span class="lineno">30</span> <span style="font-style: italic; color: #408080"># encoded string. It has the following </span><br /><span class="lineno">31</span> <span style="font-style: italic; color: #408080"># structure.</span><br /><span class="lineno">32</span> <span style="font-style: italic; color: #408080"># \<RSAKeyValue\></span><br /><span class="lineno">33</span> <span style="font-style: italic; color: #408080"># \<Exponent\>AQAB\</Exponent\></span><br /><span class="lineno">34</span> <span style="font-style: italic; color: #408080"># \<Modulus\>some data\</Modulus\></span><br /><span class="lineno">35</span> <span style="font-style: italic; color: #408080"># \</RSAKeyValue\> </span><br /><span class="lineno">36</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">public_key</span>(<span style="color: green">self</span>, xml_format):<br /><span class="lineno">37</span> pkey <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>_key<span style="color: #666666">.</span>publickey()<br /><span class="lineno">38</span> <br /><span class="lineno">39</span> <span style="color: green; font-weight: bold">if</span> xml_format:<br /><span class="lineno">40</span> <span style="font-style: italic; color: #408080"># Pads with leading zeros if needed.</span><br /><span class="lineno">41</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">ensure_length</span>(hexstr):<br /><span class="lineno">42</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(hexstr) <span style="color: #666666">%</span> <span style="color: #666666">2</span> <span style="color: #666666">!=</span> <span style="color: #666666">0</span>:<br /><span class="lineno">43</span> <span style="color: green; font-weight: bold">return</span> <span style="color: #ba2121">'0'</span> <span style="color: #666666">+</span> hexstr<br /><span class="lineno">44</span> <span style="color: green; font-weight: bold">else</span>:<br /><span class="lineno">45</span> <span style="color: green; font-weight: bold">return</span> hexstr<br /><span class="lineno">46</span> <span style="font-style: italic; color: #408080"># make an encoded child node</span><br /><span class="lineno">47</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">add_child</span>(tag, n):<br /><span class="lineno">48</span> str_n <span style="color: #666666">=</span> ensure_length(<span style="color: #ba2121">'</span><span style="color: #bb6688; font-weight: bold">%x</span><span style="color: #ba2121">'</span> <span style="color: #666666">%</span> n)<br /><span class="lineno">49</span> n_bytes <span style="color: #666666">=</span> binascii<span style="color: #666666">.</span>unhexlify(str_n)<br /><span class="lineno">50</span> <br /><span class="lineno">51</span> sub <span style="color: #666666">=</span> et<span style="color: #666666">.</span>SubElement(root, tag)<br /><span class="lineno">52</span> sub<span style="color: #666666">.</span>text <span style="color: #666666">=</span> base64<span style="color: #666666">.</span>b64encode(n_bytes)<br /><span class="lineno">53</span> <br /><span class="lineno">54</span> root <span style="color: #666666">=</span> et<span style="color: #666666">.</span>Element(<span style="color: #ba2121">'RSAKeyValue'</span>)<br /><span class="lineno">55</span> add_child(<span style="color: #ba2121">'Exponent'</span>, pkey<span style="color: #666666">.</span>e)<br /><span class="lineno">56</span> add_child(<span style="color: #ba2121">'Modulus'</span>, pkey<span style="color: #666666">.</span>n)<br /><span class="lineno">57</span> <span style="color: green; font-weight: bold">return</span> tostring(root)<br /><span class="lineno">58</span> <span style="color: green; font-weight: bold">else</span>:<br /><span class="lineno">59</span> <span style="color: green; font-weight: bold">return</span> base64<span style="color: #666666">.</span>b64encode(pickle<span style="color: #666666">.</span>dumps(pkey))<br /><span class="lineno">60</span> <br /><span class="lineno">61</span> <span style="font-style: italic; color: #408080">## Encrypt data with the public RSA key.</span><br /><span class="lineno">62</span> <span style="font-style: italic; color: #408080"># @param data The data to be encrypted</span><br /><span class="lineno">63</span> <span style="font-style: italic; color: #408080"># @return A base64 encoded string that is the encrypted data.</span><br /><span class="lineno">64</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">encrypt</span>(<span style="color: green">self</span>, data):<br /><span class="lineno">65</span> enc_data <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>_encoder<span style="color: #666666">.</span>encode(data, keybits<span style="color: #666666">=</span><span style="color: green">self</span><span style="color: #666666">.</span>_keysize)<br /><span class="lineno">66</span> cipher <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>_key<span style="color: #666666">.</span>encrypt(enc_data, <span style="color: #ba2121">''</span>)<br /><span class="lineno">67</span> <span style="color: green; font-weight: bold">return</span> base64<span style="color: #666666">.</span>b64encode(cipher[<span style="color: #666666">0</span>])<br /><span class="lineno">68</span> <br /><span class="lineno">69</span> <span style="font-style: italic; color: #408080">## Decrypt data with the private RSA key.</span><br /><span class="lineno">70</span> <span style="font-style: italic; color: #408080"># @param encoded_cipher A base64 encoded string of encrypted data.</span><br /><span class="lineno">71</span> <span style="font-style: italic; color: #408080"># @return The decrypted data as a string.</span><br /><span class="lineno">72</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">decrypt</span>(<span style="color: green">self</span>, encoded_cipher):<br /><span class="lineno">73</span> cipher <span style="color: #666666">=</span> base64<span style="color: #666666">.</span>b64decode(encoded_cipher)<br /><span class="lineno">74</span> enc_data <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>_key<span style="color: #666666">.</span>decrypt(cipher)<br /><span class="lineno">75</span> data <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>_encoder<span style="color: #666666">.</span>decode(enc_data)<br /><span class="lineno">76</span> <span style="color: green; font-weight: bold">return</span> data</pre><br /><br /> <br /></div><br />Following are the classes I wrote that implement two of the padding schemes (OAEP, PKCS#1 v1.5)described in <a href="http://www.ietf.org/rfc/rfc2437.txt" target="_blank">rfc 2437</a>.  Coming from a C background, I find it hard to work with binary data in python. i know that there must be more efficient ways to handle binary data. The python standard library modules cStringIo, binascii and struct come in very handy. <br /><br /><br /><br /><br /><br />You may notice that some of the variable names in the following code are not ideal (sorry Uncle Bob!).  They actually reflect the names used within the RFC to make it easier for someone to follow along with the RFC document.  Also, for those of you that do not know Python well, an '_' prefix to a field name in a class is the convention for specifying a private class field. When a Python programmer sees a field like this: self._hash_length, it is clear (to Python programmers) that the author intended this to be private.  This is just a convention that you must enforce upon yourself as the Python language will allow you to access the field via an instance of the class. <br /><br /><br /><br /><br /><br /><br /><br /><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">binascii</span><br /><span class="lineno"> 2</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">cStringIO</span><br /><span class="lineno"> 3</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">hashlib</span><br /><span class="lineno"> 4</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">os</span><br /><span class="lineno"> 5</span> <span style="color: green; font-weight: bold">import</span> <span style="color: blue; font-weight: bold">struct</span><br /><span class="lineno"> 6</span> <br /><span class="lineno"> 7</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">PKCS1Error</span>(<span style="color: #d2413a; font-weight: bold">RuntimeError</span>):<br /><span class="lineno"> 8</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno"> 9</span> <span style="font-style: italic; color: #ba2121"> Base class for PKCS1 encoding/decoding errors.</span><br /><span class="lineno"> 10</span> <span style="font-style: italic; color: #ba2121"> Error of this or derived classes should be caught</span><br /><span class="lineno"> 11</span> <span style="font-style: italic; color: #ba2121"> by the calling code and then a generic error message</span><br /><span class="lineno"> 12</span> <span style="font-style: italic; color: #ba2121"> should be returned to the caller.</span><br /><span class="lineno"> 13</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno"> 14</span> <span style="color: green; font-weight: bold">pass</span><br /><span class="lineno"> 15</span> <br /><span class="lineno"> 16</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">DecoderError</span>(PKCS1Error):<br /><span class="lineno"> 17</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno"> 18</span> <span style="font-style: italic; color: #ba2121"> Raised when a decoding error has been detected.</span><br /><span class="lineno"> 19</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno"> 20</span> <span style="color: green; font-weight: bold">pass</span><br /><span class="lineno"> 21</span> <br /><span class="lineno"> 22</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">EncoderError</span>(PKCS1Error):<br /><span class="lineno"> 23</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno"> 24</span> <span style="font-style: italic; color: #ba2121"> Raise when an encoding error has been detected.</span><br /><span class="lineno"> 25</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno"> 26</span> <span style="color: green; font-weight: bold">pass</span><br /><span class="lineno"> 27</span> <br /><span class="lineno"> 28</span> <br /><span class="lineno"> 29</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">PKCSAuxiliary</span>(<span style="color: green">object</span>):<br /><span class="lineno"> 30</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno"> 31</span> <span style="font-style: italic; color: #ba2121"> Auxiliary functions used in RFC 2437</span><br /><span class="lineno"> 32</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno"> 33</span> <br /><span class="lineno"> 34</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">__init__</span>(<span style="color: green">self</span>):<br /><span class="lineno"> 35</span> <span style="color: green">self</span><span style="color: #666666">.</span>_hash_length <span style="color: #666666">=</span> <span style="color: green">None</span><br /><span class="lineno"> 36</span> <br /><span class="lineno"> 37</span> <span style="color: #aa22ff">@property</span><br /><span class="lineno"> 38</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">hash_length</span>(<span style="color: green">self</span>):<br /><span class="lineno"> 39</span> <span style="color: green; font-weight: bold">if</span> <span style="color: #aa22ff; font-weight: bold">not</span> <span style="color: green">self</span><span style="color: #666666">.</span>_hash_length:<br /><span class="lineno"> 40</span> hasher <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>create_hasher()<br /><span class="lineno"> 41</span> <span style="color: green">self</span><span style="color: #666666">.</span>_hash_length <span style="color: #666666">=</span> hasher<span style="color: #666666">.</span>digest_size<br /><span class="lineno"> 42</span> <br /><span class="lineno"> 43</span> <span style="color: green; font-weight: bold">return</span> <span style="color: green">self</span><span style="color: #666666">.</span>_hash_length<br /><span class="lineno"> 44</span> <br /><span class="lineno"> 45</span> <span style="color: #aa22ff">@staticmethod</span><br /><span class="lineno"> 46</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">create_hasher</span>():<br /><span class="lineno"> 47</span> <span style="color: green; font-weight: bold">return</span> hashlib<span style="color: #666666">.</span>sha1()<br /><span class="lineno"> 48</span> <br /><span class="lineno"> 49</span> <span style="color: #aa22ff">@staticmethod</span><br /><span class="lineno"> 50</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">compute_hash</span>(data, hex_digest<span style="color: #666666">=</span><span style="color: green">False</span>):<br /><span class="lineno"> 51</span> hasher <span style="color: #666666">=</span> PKCSAuxiliary<span style="color: #666666">.</span>create_hasher()<br /><span class="lineno"> 52</span> hasher<span style="color: #666666">.</span>update(data)<br /><span class="lineno"> 53</span> <span style="color: green; font-weight: bold">if</span> hex_digest:<br /><span class="lineno"> 54</span> <span style="color: green; font-weight: bold">return</span> hasher<span style="color: #666666">.</span>hex_digest()<br /><span class="lineno"> 55</span> <span style="color: green; font-weight: bold">else</span>:<br /><span class="lineno"> 56</span> <span style="color: green; font-weight: bold">return</span> hasher<span style="color: #666666">.</span>digest()<br /><span class="lineno"> 57</span> <br /><span class="lineno"> 58</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">mgf</span>(<span style="color: green">self</span>, seed, length):<br /><span class="lineno"> 59</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno"> 60</span> <span style="font-style: italic; color: #ba2121"> RFC 2437 page 28 MFG1</span><br /><span class="lineno"> 61</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno"> 62</span> counter <span style="color: #666666">=</span> <span style="color: #666666">0</span><br /><span class="lineno"> 63</span> output <span style="color: #666666">=</span> cStringIO<span style="color: #666666">.</span>StringIO()<br /><span class="lineno"> 64</span> <span style="color: green; font-weight: bold">try</span>:<br /><span class="lineno"> 65</span> limit <span style="color: #666666">=</span> length <span style="color: #666666">/</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length<br /><span class="lineno"> 66</span> <span style="color: green; font-weight: bold">while</span> counter <span style="color: #666666"><=</span> limit:<br /><span class="lineno"> 67</span> C <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>i2osp(counter)<br /><span class="lineno"> 68</span> output<span style="color: #666666">.</span>write(<span style="color: green">self</span><span style="color: #666666">.</span>compute_hash(seed <span style="color: #666666">+</span> C))<br /><span class="lineno"> 69</span> counter <span style="color: #666666">+=</span> <span style="color: #666666">1</span><br /><span class="lineno"> 70</span> <br /><span class="lineno"> 71</span> raw_mask <span style="color: #666666">=</span> output<span style="color: #666666">.</span>getvalue()<br /><span class="lineno"> 72</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(raw_mask) <span style="color: #666666"><</span> length:<br /><span class="lineno"> 73</span> <span style="color: green; font-weight: bold">raise</span> PKCS1Error(<span style="color: #ba2121">"MGF: mask too long"</span>)<br /><span class="lineno"> 74</span> <span style="color: green; font-weight: bold">finally</span>:<br /><span class="lineno"> 75</span> output<span style="color: #666666">.</span>close()<br /><span class="lineno"> 76</span> <br /><span class="lineno"> 77</span> mask <span style="color: #666666">=</span> raw_mask[:length]<br /><span class="lineno"> 78</span> <span style="color: green; font-weight: bold">return</span> mask<br /><span class="lineno"> 79</span> <br /><span class="lineno"> 80</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">i2osp</span>(<span style="color: green">self</span>, x):<br /><span class="lineno"> 81</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno"> 82</span> <span style="font-style: italic; color: #ba2121"> RFC 2437 page 6 I2OSP</span><br /><span class="lineno"> 83</span> <span style="font-style: italic; color: #ba2121"> Special case where length = 4</span><br /><span class="lineno"> 84</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno"> 85</span> <span style="color: green; font-weight: bold">if</span> x <span style="color: #666666">></span> <span style="color: #666666">256</span> <span style="color: #666666">**</span> <span style="color: #666666">4</span>:<br /><span class="lineno"> 86</span> <span style="color: green; font-weight: bold">raise</span> PKCS1Error(<span style="color: #ba2121">"I2OSP: integer too large"</span>)<br /><span class="lineno"> 87</span> <br /><span class="lineno"> 88</span> sp <span style="color: #666666">=</span> (<br /><span class="lineno"> 89</span> <span style="color: green">int</span>((x <span style="color: #666666">>></span> <span style="color: #666666">24</span>) <span style="color: #666666">&</span> <span style="color: #666666">0xff</span>),<br /><span class="lineno"> 90</span> <span style="color: green">int</span>((x <span style="color: #666666">>></span> <span style="color: #666666">16</span>) <span style="color: #666666">&</span> <span style="color: #666666">0xff</span>),<br /><span class="lineno"> 91</span> <span style="color: green">int</span>((x <span style="color: #666666">>></span> <span style="color: #666666">8</span>) <span style="color: #666666">&</span> <span style="color: #666666">0xff</span>),<br /><span class="lineno"> 92</span> <span style="color: green">int</span>((x <span style="color: #666666">>></span> <span style="color: #666666">0</span>) <span style="color: #666666">&</span> <span style="color: #666666">0xff</span>)<br /><span class="lineno"> 93</span> )<br /><span class="lineno"> 94</span> <br /><span class="lineno"> 95</span> <span style="color: green; font-weight: bold">return</span> struct<span style="color: #666666">.</span>pack(<span style="color: #ba2121">'BBBB'</span>, <span style="color: #666666">*</span>sp)<br /><span class="lineno"> 96</span> <br /><span class="lineno"> 97</span> <span style="color: #aa22ff">@staticmethod</span><br /><span class="lineno"> 98</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">xor</span>(a, b):<br /><span class="lineno"> 99</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno">100</span> <span style="font-style: italic; color: #ba2121"> RFC 2437 bitwise exclusive-or of two octet strings.</span><br /><span class="lineno">101</span> <span style="font-style: italic; color: #ba2121"> page 23</span><br /><span class="lineno">102</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno">103</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(a) <span style="color: #666666">!=</span> <span style="color: green">len</span>(b):<br /><span class="lineno">104</span> <span style="color: green; font-weight: bold">raise</span> PKCS1Error(<span style="color: #ba2121">"XOR: invalid input lengths"</span>)<br /><span class="lineno">105</span> <br /><span class="lineno">106</span> output <span style="color: #666666">=</span> cStringIO<span style="color: #666666">.</span>StringIO()<br /><span class="lineno">107</span> <br /><span class="lineno">108</span> <span style="color: green; font-weight: bold">try</span>:<br /><span class="lineno">109</span> <span style="color: green; font-weight: bold">for</span> i <span style="color: #aa22ff; font-weight: bold">in</span> <span style="color: green">xrange</span>(<span style="color: green">len</span>(a)):<br /><span class="lineno">110</span> x <span style="color: #666666">=</span> <span style="color: green">int</span>(binascii<span style="color: #666666">.</span>hexlify(a[i]), <span style="color: #666666">16</span>)<br /><span class="lineno">111</span> y <span style="color: #666666">=</span> <span style="color: green">int</span>(binascii<span style="color: #666666">.</span>hexlify(b[i]), <span style="color: #666666">16</span>)<br /><span class="lineno">112</span> output<span style="color: #666666">.</span>write(<span style="color: #ba2121">'</span><span style="color: #bb6688; font-weight: bold">%02x</span><span style="color: #ba2121">'</span> <span style="color: #666666">%</span> (x <span style="color: #666666">^</span> y))<br /><span class="lineno">113</span> <br /><span class="lineno">114</span> data <span style="color: #666666">=</span> output<span style="color: #666666">.</span>getvalue()<br /><span class="lineno">115</span> <br /><span class="lineno">116</span> <span style="color: green; font-weight: bold">finally</span>:<br /><span class="lineno">117</span> output<span style="color: #666666">.</span>close()<br /><span class="lineno">118</span> <br /><span class="lineno">119</span> <span style="color: green; font-weight: bold">return</span> binascii<span style="color: #666666">.</span>unhexlify(data)<br /><span class="lineno">120</span> <br /><span class="lineno">121</span> <br /><span class="lineno">122</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">OAEPEncoder</span>(PKCSAuxiliary):<br /><span class="lineno">123</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno">124</span> <span style="font-style: italic; color: #ba2121"> RFC 2437 9.1.1 EME-OAEP PKCS1-v2.0</span><br /><span class="lineno">125</span> <span style="font-style: italic; color: #ba2121"> 9.1.1.1 EME-OAEP-ENCODE</span><br /><span class="lineno">126</span> <span style="font-style: italic; color: #ba2121"> 9.1.1.2 EME-OAEP-DECODE</span><br /><span class="lineno">127</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno">128</span> <br /><span class="lineno">129</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">__init__</span>(<span style="color: green">self</span>):<br /><span class="lineno">130</span> <span style="color: green">super</span>(OAEPEncoder, <span style="color: green">self</span>)<span style="color: #666666">.</span>__init__()<br /><span class="lineno">131</span> <br /><span class="lineno">132</span> <br /><span class="lineno">133</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">encode</span>(<span style="color: green">self</span>, msg, salt<span style="color: #666666">=</span><span style="color: #ba2121">''</span>, keybits<span style="color: #666666">=1024</span>):<br /><span class="lineno">134</span> k <span style="color: #666666">=</span> keybits <span style="color: #666666">/</span> <span style="color: #666666">8</span><br /><span class="lineno">135</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(msg) <span style="color: #666666">></span> (k <span style="color: #666666">-</span> <span style="color: #666666">2</span> <span style="color: #666666">-</span> <span style="color: #666666">2</span> <span style="color: #666666">*</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length):<br /><span class="lineno">136</span> <span style="color: green; font-weight: bold">raise</span> EncoderError(<span style="color: #ba2121">"EME-OAEP: message too long"</span>)<br /><span class="lineno">137</span> <br /><span class="lineno">138</span> emLen <span style="color: #666666">=</span> k <span style="color: #666666">-</span> <span style="color: #666666">1</span><br /><span class="lineno">139</span> <span style="color: green; font-weight: bold">if</span> (emLen <span style="color: #666666"><</span> (<span style="color: #666666">2</span> <span style="color: #666666">*</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length <span style="color: #666666">+</span> <span style="color: #666666">1</span>) <span style="color: #aa22ff; font-weight: bold">or</span><br /><span class="lineno">140</span> <span style="color: green">len</span>(msg) <span style="color: #666666">></span> (emLen <span style="color: #666666">-</span> <span style="color: #666666">1</span> <span style="color: #666666">-</span> <span style="color: #666666">2</span> <span style="color: #666666">*</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length)):<br /><span class="lineno">141</span> <span style="color: green; font-weight: bold">raise</span> EncoderError(<span style="color: #ba2121">"EME-OAEP: message too long"</span>)<br /><span class="lineno">142</span> <br /><span class="lineno">143</span> pslen <span style="color: #666666">=</span> emLen <span style="color: #666666">-</span> <span style="color: green">len</span>(msg) <span style="color: #666666">-</span> <span style="color: #666666">2</span> <span style="color: #666666">*</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length <span style="color: #666666">-</span> <span style="color: #666666">1</span><br /><span class="lineno">144</span> output <span style="color: #666666">=</span> cStringIO<span style="color: #666666">.</span>StringIO()<br /><span class="lineno">145</span> <span style="color: green; font-weight: bold">try</span>:<br /><span class="lineno">146</span> <span style="color: green; font-weight: bold">for</span> _ <span style="color: #aa22ff; font-weight: bold">in</span> <span style="color: green">xrange</span>(pslen):<br /><span class="lineno">147</span> output<span style="color: #666666">.</span>write(<span style="color: #ba2121">'</span><span style="color: #bb6688; font-weight: bold">%02x</span><span style="color: #ba2121">'</span> <span style="color: #666666">%</span> <span style="color: #666666">0</span>)<br /><span class="lineno">148</span> ps <span style="color: #666666">=</span> binascii<span style="color: #666666">.</span>unhexlify(output<span style="color: #666666">.</span>getvalue())<br /><span class="lineno">149</span> <span style="color: green; font-weight: bold">assert</span> <span style="color: green">len</span>(ps) <span style="color: #666666">==</span> pslen, <span style="color: #ba2121">"PS: invalid length"</span><br /><span class="lineno">150</span> <span style="color: green; font-weight: bold">finally</span>:<br /><span class="lineno">151</span> output<span style="color: #666666">.</span>close()<br /><span class="lineno">152</span> <br /><span class="lineno">153</span> shash <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>compute_hash(salt)<br /><span class="lineno">154</span> dbout <span style="color: #666666">=</span> cStringIO<span style="color: #666666">.</span>StringIO()<br /><span class="lineno">155</span> <span style="color: green; font-weight: bold">try</span>:<br /><span class="lineno">156</span> dbout<span style="color: #666666">.</span>write(shash)<br /><span class="lineno">157</span> dbout<span style="color: #666666">.</span>write(ps)<br /><span class="lineno">158</span> dbout<span style="color: #666666">.</span>write(<span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x01</span><span style="color: #ba2121">'</span>)<br /><span class="lineno">159</span> dbout<span style="color: #666666">.</span>write(msg)<br /><span class="lineno">160</span> db <span style="color: #666666">=</span> dbout<span style="color: #666666">.</span>getvalue()<br /><span class="lineno">161</span> <span style="color: green; font-weight: bold">finally</span>:<br /><span class="lineno">162</span> dbout<span style="color: #666666">.</span>close()<br /><span class="lineno">163</span> <br /><span class="lineno">164</span> seed <span style="color: #666666">=</span> os<span style="color: #666666">.</span>urandom(<span style="color: green">self</span><span style="color: #666666">.</span>hash_length)<br /><span class="lineno">165</span> <span style="color: green; font-weight: bold">assert</span> <span style="color: green">len</span>(seed) <span style="color: #666666">==</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length<br /><span class="lineno">166</span> <br /><span class="lineno">167</span> dbMask <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>mgf(seed, emLen <span style="color: #666666">-</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length)<br /><span class="lineno">168</span> maskedDB <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>xor(db, dbMask)<br /><span class="lineno">169</span> seedMask <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>mgf(maskedDB, <span style="color: green">self</span><span style="color: #666666">.</span>hash_length)<br /><span class="lineno">170</span> maskedSeed <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>xor(seed, seedMask)<br /><span class="lineno">171</span> emout <span style="color: #666666">=</span> cStringIO<span style="color: #666666">.</span>StringIO()<br /><span class="lineno">172</span> <span style="color: green; font-weight: bold">try</span>:<br /><span class="lineno">173</span> emout<span style="color: #666666">.</span>write(maskedSeed)<br /><span class="lineno">174</span> emout<span style="color: #666666">.</span>write(maskedDB)<br /><span class="lineno">175</span> emsg <span style="color: #666666">=</span> emout<span style="color: #666666">.</span>getvalue()<br /><span class="lineno">176</span> <span style="color: green; font-weight: bold">finally</span>:<br /><span class="lineno">177</span> emout<span style="color: #666666">.</span>close()<br /><span class="lineno">178</span> <span style="color: green; font-weight: bold">return</span> emsg<br /><span class="lineno">179</span> <br /><span class="lineno">180</span> <br /><span class="lineno">181</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">decode</span>(<span style="color: green">self</span>, emsg, salt<span style="color: #666666">=</span><span style="color: #ba2121">''</span>):<br /><span class="lineno">182</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(emsg) <span style="color: #666666"><</span> (<span style="color: #666666">2</span> <span style="color: #666666">*</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length <span style="color: #666666">+</span> <span style="color: #666666">1</span>):<br /><span class="lineno">183</span> <span style="color: green; font-weight: bold">raise</span> DecoderError(<span style="color: #ba2121">"EME-OAEP: decoding error"</span>)<br /><span class="lineno">184</span> <br /><span class="lineno">185</span> maskedSeed <span style="color: #666666">=</span> emsg[:<span style="color: green">self</span><span style="color: #666666">.</span>hash_length]<br /><span class="lineno">186</span> maskedDB <span style="color: #666666">=</span> emsg[<span style="color: green">self</span><span style="color: #666666">.</span>hash_length:]<br /><span class="lineno">187</span> seedMask <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>mgf(maskedDB, <span style="color: green">self</span><span style="color: #666666">.</span>hash_length)<br /><span class="lineno">188</span> seed <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>xor(maskedSeed, seedMask)<br /><span class="lineno">189</span> dbMask <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>mgf(seed, <span style="color: green">len</span>(emsg) <span style="color: #666666">-</span> <span style="color: green">self</span><span style="color: #666666">.</span>hash_length)<br /><span class="lineno">190</span> db <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>xor(maskedDB, dbMask)<br /><span class="lineno">191</span> shash <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>compute_hash(salt)<br /><span class="lineno">192</span> <br /><span class="lineno">193</span> db_shash <span style="color: #666666">=</span> db[:<span style="color: green">self</span><span style="color: #666666">.</span>hash_length]<br /><span class="lineno">194</span> <span style="color: green; font-weight: bold">if</span> db_shash <span style="color: #666666">!=</span> shash:<br /><span class="lineno">195</span> <span style="color: green; font-weight: bold">raise</span> DecoderError(<span style="color: #ba2121">"EME-OAEP: decoding error"</span>)<br /><span class="lineno">196</span> <br /><span class="lineno">197</span> index <span style="color: #666666">=</span> db<span style="color: #666666">.</span>find(<span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x01</span><span style="color: #ba2121">'</span>, <span style="color: green">self</span><span style="color: #666666">.</span>hash_length)<br /><span class="lineno">198</span> <span style="color: green; font-weight: bold">if</span> <span style="color: #666666">-</span> <span style="color: #666666">1</span> <span style="color: #666666">==</span> index:<br /><span class="lineno">199</span> <span style="color: green; font-weight: bold">raise</span> DecoderError(<span style="color: #ba2121">"EME-OAEP: decoding error"</span>)<br /><span class="lineno">200</span> <br /><span class="lineno">201</span> <span style="color: green; font-weight: bold">return</span> db[index <span style="color: #666666">+</span> <span style="color: #666666">1</span>:]<br /><span class="lineno">202</span> <br /><span class="lineno">203</span> <br /><span class="lineno">204</span> <br /><span class="lineno">205</span> <span style="color: green; font-weight: bold">class</span> <span style="color: blue; font-weight: bold">PKCS1v1_5Encoder</span>(<span style="color: green">object</span>):<br /><span class="lineno">206</span> <span style="font-style: italic; color: #ba2121">'''</span><br /><span class="lineno">207</span> <span style="font-style: italic; color: #ba2121"> RFC 2437 9.1.2 EME-PKCS1-v1_5</span><br /><span class="lineno">208</span> <span style="font-style: italic; color: #ba2121"> </span><br /><span class="lineno">209</span> <span style="font-style: italic; color: #ba2121"> 9.1.2.1 EME-PKCS1-v1_5-ENCODE</span><br /><span class="lineno">210</span> <span style="font-style: italic; color: #ba2121"> 9.1.2.2 EME-PKCS1-v1_5-DECODE</span><br /><span class="lineno">211</span> <span style="font-style: italic; color: #ba2121"> '''</span><br /><span class="lineno">212</span> <br /><span class="lineno">213</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">encode</span>(<span style="color: green">self</span>, msg, keybits<span style="color: #666666">=1024</span>):<br /><span class="lineno">214</span> emLen <span style="color: #666666">=</span> keybits <span style="color: #666666">/</span> <span style="color: #666666">8</span> <span style="color: #666666">-</span> <span style="color: #666666">1</span><br /><span class="lineno">215</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(msg) <span style="color: #666666">></span> (emLen <span style="color: #666666">-</span> <span style="color: #666666">10</span>):<br /><span class="lineno">216</span> <span style="color: green; font-weight: bold">raise</span> EncoderError(<span style="color: #ba2121">"PKCS1-V1.5: message too long"</span>)<br /><span class="lineno">217</span> <br /><span class="lineno">218</span> ps <span style="color: #666666">=</span> <span style="color: green">self</span><span style="color: #666666">.</span>rnd_non_zero(emLen <span style="color: #666666">-</span> <span style="color: green">len</span>(msg) <span style="color: #666666">-</span> <span style="color: #666666">2</span>)<br /><span class="lineno">219</span> <span style="color: green; font-weight: bold">assert</span> <span style="color: green">len</span>(ps) <span style="color: #666666">>=</span> <span style="color: #666666">8</span>, <span style="color: #ba2121">"PKCS1-V1.5: invalid PS"</span><br /><span class="lineno">220</span> <br /><span class="lineno">221</span> emout <span style="color: #666666">=</span> cStringIO<span style="color: #666666">.</span>StringIO()<br /><span class="lineno">222</span> <span style="color: green; font-weight: bold">try</span>:<br /><span class="lineno">223</span> emout<span style="color: #666666">.</span>write(<span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x02</span><span style="color: #ba2121">'</span>)<br /><span class="lineno">224</span> emout<span style="color: #666666">.</span>write(ps)<br /><span class="lineno">225</span> emout<span style="color: #666666">.</span>write(<span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x00</span><span style="color: #ba2121">'</span>)<br /><span class="lineno">226</span> emout<span style="color: #666666">.</span>write(msg)<br /><span class="lineno">227</span> emsg <span style="color: #666666">=</span> emout<span style="color: #666666">.</span>getvalue()<br /><span class="lineno">228</span> <span style="color: green; font-weight: bold">finally</span>:<br /><span class="lineno">229</span> emout<span style="color: #666666">.</span>close()<br /><span class="lineno">230</span> <br /><span class="lineno">231</span> <span style="color: green; font-weight: bold">return</span> emsg<br /><span class="lineno">232</span> <br /><span class="lineno">233</span> <br /><span class="lineno">234</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">decode</span>(<span style="color: green">self</span>, emsg):<br /><span class="lineno">235</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(emsg) <span style="color: #666666"><</span> <span style="color: #666666">10</span>:<br /><span class="lineno">236</span> <span style="color: green; font-weight: bold">raise</span> DecoderError(<span style="color: #ba2121">"PKCS1-V1.5: decoding error"</span>)<br /><span class="lineno">237</span> <br /><span class="lineno">238</span> <span style="color: green; font-weight: bold">if</span> <span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x02</span><span style="color: #ba2121">'</span> <span style="color: #666666">!=</span> emsg[<span style="color: #666666">0</span>]:<br /><span class="lineno">239</span> <span style="color: green; font-weight: bold">raise</span> DecoderError(<span style="color: #ba2121">"PKCS1-V1.5: decoding error"</span>)<br /><span class="lineno">240</span> <br /><span class="lineno">241</span> index <span style="color: #666666">=</span> emsg<span style="color: #666666">.</span>find(<span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x00</span><span style="color: #ba2121">'</span>)<br /><span class="lineno">242</span> <span style="color: green; font-weight: bold">if</span> <span style="color: #666666">-</span> <span style="color: #666666">1</span> <span style="color: #666666">==</span> index:<br /><span class="lineno">243</span> <span style="color: green; font-weight: bold">raise</span> DecoderError(<span style="color: #ba2121">"PKCS1-V1.5: decoding error"</span>)<br /><span class="lineno">244</span> <br /><span class="lineno">245</span> ps <span style="color: #666666">=</span> emsg[<span style="color: #666666">1</span>:index]<br /><span class="lineno">246</span> <span style="color: green; font-weight: bold">if</span> <span style="color: green">len</span>(ps) <span style="color: #666666"><</span> <span style="color: #666666">8</span>:<br /><span class="lineno">247</span> <span style="color: green; font-weight: bold">raise</span> DecoderError(<span style="color: #ba2121">"PKCS1-V1.5: decoding error"</span>)<br /><span class="lineno">248</span> <br /><span class="lineno">249</span> <span style="color: green; font-weight: bold">return</span> emsg[index <span style="color: #666666">+</span> <span style="color: #666666">1</span>:]<br /><span class="lineno">250</span> <br /><span class="lineno">251</span> <br /><span class="lineno">252</span> <span style="color: #aa22ff">@staticmethod</span><br /><span class="lineno">253</span> <span style="color: green; font-weight: bold">def</span> <span style="color: blue">rnd_non_zero</span>(length):<br /><span class="lineno">254</span> rnd <span style="color: #666666">=</span> os<span style="color: #666666">.</span>urandom(length)<br /><span class="lineno">255</span> <span style="color: green; font-weight: bold">while</span> <span style="color: #666666">-</span> <span style="color: #666666">1</span> <span style="color: #666666">!=</span> rnd<span style="color: #666666">.</span>find(<span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x00</span><span style="color: #ba2121">'</span>):<br /><span class="lineno">256</span> rnd <span style="color: #666666">=</span> rnd<span style="color: #666666">.</span>replace(<span style="color: #ba2121">'</span><span style="color: #bb6622; font-weight: bold">\x00</span><span style="color: #ba2121">'</span>, os<span style="color: #666666">.</span>urandom(<span style="color: #666666">1</span>))<br /><span class="lineno">257</span> <span style="color: green; font-weight: bold">return</span> rnd</pre><br /><br /> <br /></div><br />Silverlight does not provide any RSA cryptography classes in the its version of the .NET framework.  Fortunately, the <a href="http://scrypt.codeplex.com/" target="_blank">Scrypt project</a> exists and provides a nice RSA library for Silverlight (version 3+) and windows phone 7!  the Scrypt project is licensed under the Microsoft public license (ms-pl).  the RSA.RSACrypto class has an interface that is very similar to that of System.Security.Cryptography.RSACryptoServiceProvider in the full .NET framework.<br /><br /><br /><br /><br /><br />In my project the Silverlight client would obtain the RSA public key in XML format via a web service call.  This would be used to encrypt login credentials.  During that process an AES key would be generated for the login session.  Any sensitive data would then be encrypted by the AES key shared between the Python server and the Silverlight client. Here is an example of the encryption on the Silverlight side.<br /><br /><br /><br /><br /><br /><br /><br /><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="color: green; font-weight: bold">using</span> <span style="color: blue; font-weight: bold">System</span>;<br /><span class="lineno"> 2</span> <span style="color: green; font-weight: bold">using</span> <span style="color: blue; font-weight: bold">System.Text</span>;<br /><span class="lineno"> 3</span> <span style="color: green; font-weight: bold">using</span> <span style="color: blue; font-weight: bold">RSA</span>;<br /><span class="lineno"> 4</span> <br /><span class="lineno"> 5</span> <span style="font-style: italic; color: #408080">// ... other code ...</span><br /><span class="lineno"> 6</span> <br /><span class="lineno"> 7</span> <span style="font-style: italic; color: #408080">// in this example, e is the GetPublicKeyCompletedEventArgs</span><br /><span class="lineno"> 8</span> <span style="font-style: italic; color: #408080">// parameter from an asynchronous web service call</span><br /><span class="lineno"> 9</span> var pkey = <span style="color: green; font-weight: bold">new</span> RSACrypto();<br /><span class="lineno">10</span> pkey.FromXmlString(e.Result.GetPublicKeyResult);<br /><span class="lineno">11</span> <br /><span class="lineno">12</span> StringBuilder output = <span style="color: green; font-weight: bold">new</span> StringBuilder();<br /><span class="lineno">13</span> <span style="font-style: italic; color: #408080">// fill output with some data... </span><br /><span class="lineno">14</span> Byte[] raw_data = Encoding.UTF8.GetBytes(output.ToString());<br /><span class="lineno">15</span> var cipher = pkey.Encrypt(raw_data);<br /><span class="lineno">16</span> var encodedCipher = Convert.ToBase64String(cipher);<br /><span class="lineno">17</span> <br /><span class="lineno">18</span> <span style="font-style: italic; color: #408080">// now encodedCipher is ready to be transported </span><br /><span class="lineno">19</span> <span style="font-style: italic; color: #408080">// to the Python server.</span></pre><br /><br /> <br /></div><br />Remember, with RSA public key cryptography you can only encrypt up to keysize / 8 – 1 bytes of data.  Thus if you have a key that is 128 bytes (1024 bits), you can only encrypt up to 127 bytes (1016 bits) of data (depending on the implementation details, maybe less).  The padding schemes used with RSA ensure that the data you are to encrypt is exactly keysize / 8 – 1 bytes in length.  Thus if your data is short, like a 32 byte AES key (16 byte key, 16 byte iv for 256 bits), the padding scheme will pad out the data to keysize / 8 – 1 bytes before the data is encrypted.<br /><br /><br /><br /><br /><br />This was a fun project to work on.  I learned a great deal and had a blast. I appreciate all of the hard work that others have put in to make the excellent encryption libraries that exist and are freely available.  Maybe some of you will find my padding encoders useful, Cheers!<br /><br /><br /> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com4tag:blogger.com,1999:blog-8601661143216171909.post-31529960830427987842010-11-18T14:11:00.001-05:002010-11-18T14:11:54.594-05:00Enable ADC on Your Windows Phone 7<p>I received a Windows Phone 7 device by attending the Microsoft PDC in Redmond this year.  I was given an LG E900 device.  The phone came from Vodafone in Germany.  It even has the European style electrical plug, luckily they provided an adaptor.  </p> <p>The story goes that Microsoft approached AT&T to buy phones for the PDC attendees.  AT&T refused so Microsoft bought phones from Vodafone.  Microsoft then employed someone to switch the language of each phone from German to English.  I don’t know if this is entirely true, but that was the story going around the PDC.</p> <p>Like many others, I popped the SIM card out of my IPhone and placed it in the E900.  ADC was not enabled so I had to set many properties of the phone carrier that a normal customer would not have to.  My carrier is AT&T.  I first had to set the APN to enable data access.  This can be done by going to the Settings app, choosing cellular from the system page and clicking the ‘edit apn’ button on the bottom of the page.  In the APN text box enter: wap.cingular then click the done button (check mark).  </p> <p>You may also have to set your SMS number although this was done automatically for me. Settings app, flip to the applications page and choose ‘messaging.’  Here you will find the SMS center number.   You can call AT&T to get your number, mine is +13123149810.</p> <p>Next you may need to set the voicemail number.  I had to do this.  Settings app, flip to the applications page and choose ‘phone.’  Here you will see the voicemail number.  Once again I obtained this number by calling AT&T, yours may be different, mine is +13174379963.</p> <h3></h3> <h3> </h3> <h3>Enabling MMS</h3> <p>Everything was now working on the phone except for MMS.  I was able to get the required MMS settings from AT&T, but there did not appear to be a way to put these settings into the phone.  I had heard that you could reset the phone and at the first boot (with your SIM card in place) you could set the MMS settings.  This turned out to not be true.  Thanks to Google translator I was able to get the phone back to English (it booted up in German after the reset).  The original instructions came from <a href="http://forums.whirlpool.net.au/archive/1575615" target="_blank">this site</a>, many thanks to the author of that post. Here is how to enable MMS without resetting your phone.  Sorry for the low quality pictures, you can’t take a screen shot of a running app on Windows Phone 7 like you can with an Iphone.</p> <ol> <li>Open the phone app used to make calls </li> <li>Dial ##634# and click call <ol> <li>This will install the MFG application on your phone (shows up in your installed applications). </li> </ol> </li> <li>In the MFG application enter the password 277634#*# <ol> <li><a href="http://lh5.ggpht.com/_xiL_ba2B_Sc/TOV6aFnLXoI/AAAAAAAAADY/8e-DT4R_Z5A/s1600-h/2e%5B2%5D.jpg"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2e" border="0" alt="2e" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/TOV6arQ-5jI/AAAAAAAAADc/IuvO48o0dBI/2e_thumb.jpg?imgmax=800" width="142" height="244" /></a> </li> </ol> </li> <li>In the Factory Menu choose  “Engineer Menu” <ol> <li><a href="http://lh4.ggpht.com/_xiL_ba2B_Sc/TOV6a8Y7zLI/AAAAAAAAADg/kUgG5oQZcFg/s1600-h/2d%5B2%5D.jpg"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2d" border="0" alt="2d" src="http://lh5.ggpht.com/_xiL_ba2B_Sc/TOV6bdfqRSI/AAAAAAAAADk/K5oaRu6NJCs/2d_thumb.jpg?imgmax=800" width="184" height="244" /></a> </li> </ol> </li> <li>In the Engineer Menu choose “Other Setting” <ol> <li><a href="http://lh4.ggpht.com/_xiL_ba2B_Sc/TOV6bj8oyZI/AAAAAAAAADo/EXVWdY01pIk/s1600-h/2c%5B2%5D.jpg"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2c" border="0" alt="2c" src="http://lh5.ggpht.com/_xiL_ba2B_Sc/TOV6cOxPEZI/AAAAAAAAADs/PaSNHS7l4VA/2c_thumb.jpg?imgmax=800" width="184" height="244" /></a> </li> </ol> </li> <li>In the Other Setting Menu choose “Set ADC” and set it to Enable <ol> <li><a href="http://lh5.ggpht.com/_xiL_ba2B_Sc/TOV6cTCS9oI/AAAAAAAAADw/uBvoKy8f3YU/s1600-h/2a%5B3%5D.jpg"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2a" border="0" alt="2a" src="http://lh4.ggpht.com/_xiL_ba2B_Sc/TOV6c3PT0fI/AAAAAAAAAD0/cPvZVSCfjyg/2a_thumb.jpg?imgmax=800" width="157" height="244" /></a>  </li> </ol> </li> <li>In the Other Setting Menu choose “Set network profiles” <ol> <li><a href="http://lh3.ggpht.com/_xiL_ba2B_Sc/TOV6dDx9wgI/AAAAAAAAAD4/-PR6VGynjxs/s1600-h/2b%5B2%5D.jpg"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2b" border="0" alt="2b" src="http://lh3.ggpht.com/_xiL_ba2B_Sc/TOV6d_lmplI/AAAAAAAAAD8/hNGa_iWx9yI/2b_thumb.jpg?imgmax=800" width="184" height="244" /></a> </li> </ol> </li> <li>On the bottom half of the screen you will see a list of XML files that can be used to configure the network profile on your phone.  You will have to guess which file you will need for your carrier and country.  The currently selected profile will be highlighted in your theme color.  You may want to write down the current setting in case you need to go back. Because I am on AT&T in the US, I chose the file _PROV_ATT_US_310_410.xml. </li> <li>To view the new settings choose “View current profile” from the “Other Setting” menu.  This will bring up the “View config xml” page. This will show you an XML file that contains the new network profile settings that you just placed into your phone.  Within this XML file on my phone, I can see (among other things) the settings that the AT&T representative gave to enable MMS. <ol> <li><a href="http://lh3.ggpht.com/_xiL_ba2B_Sc/TOV6eG7RPUI/AAAAAAAAAEA/2YSR_o4wHzA/s1600-h/29%5B3%5D.jpg"><img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="29" border="0" alt="29" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/TOV6ebEPGRI/AAAAAAAAAEE/An5OrSvq0Z8/29_thumb.jpg?imgmax=800" width="175" height="244" /></a> </li> </ol> </li> <li>Test it out, mine worked! </li> <li>The MFG app will now be in your applications page with all of your other apps.  You will still need the password to open it. </li> </ol> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com5tag:blogger.com,1999:blog-8601661143216171909.post-71367304944163784742010-09-14T17:55:00.001-04:002010-09-14T17:55:56.065-04:00How to Migrate a Visual SourceSafe Database to Subversion<p>The software tools involved in this migration are:</p> <li><a href="http://www.open.collab.net/downloads/subversion.html" target="_blank">Collabnet</a> Subversion Edge 1.2 – the subversion server </li> <li><a href="http://tortoisesvn.net/downloads" target="_blank">TortoiseSVN</a> 1.6.10 – a subversion client </li> <li><a href="http://vss2svn.codeplex.com/" target="_blank">VSS2SVN</a> 0.2.0  - the Visual SourceSafe to Subversion conversion tool </li> <li>Visual SourceSafe 2005 – the VSS software <p>I used Collabnet Subversion Edge 1.2 as my subversion server.  It is easy to install and configure and it is free.  This post assumes you can handle the server setup yourself. First we must create a subversion repository to hold the converted VSS database. Open the web interface to Collabnet Subversion (<a href="http://your-server-here:3343">http://your-server-here:3343</a>) and click the Repositories tab.  Click the ‘New Repository’ link.  This will ask you to provide a name for the repository and if you would like to use the standard trunk/branches/tags structure.</p> <p><a href="http://lh6.ggpht.com/_xiL_ba2B_Sc/TI_vYtR8FII/AAAAAAAAAC4/AoMQUTZaedk/s1600-h/image%5B3%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/TI_vZORaUBI/AAAAAAAAAC8/5tfU6Mb6CX0/image_thumb%5B1%5D.png?imgmax=800" width="695" height="355" /></a> </p> <p>We need to set up a pre-revision hook in the new repository for the conversion tool to successfully save your source code history.  To do this, go to your repository folder in the file system and find the hooks directory.  It is a sub-folder of your newly created repository folder.  In the hooks directory and several tmpl files. These are hook templates.  To get a hook to execute you must place an executable file (exe, script, batch file, etc…) in the hooks folder with the exact name of the hook.  For our purposes, create a file named pre-revprop-change.bat and in this file place the line: exit /b 0.</p> <p><a href="http://lh3.ggpht.com/_xiL_ba2B_Sc/TI_vZX6-wVI/AAAAAAAAADA/G4y4qBfKYI0/s1600-h/image%5B8%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/TI_vZ3Z7xSI/AAAAAAAAADE/fdZ_Bwbp7ZY/image_thumb%5B4%5D.png?imgmax=800" width="474" height="627" /></a>   </p> <p>We are done on the server.  </p> <p>You most likely have Visual SourceSafe installed on your client computer.  After all this is what you have been using for source control.  If not, you must install and configure Visual SourceSafe 2005 on your client computer.  Next, Install TortoiseSVN on your client computer.  Using TortoiseSVN pull down your empty subversion repository that we created earlier.  Any temp folder will do.  We just need to have TortoiseSVN to have a connection to the subversion server so that the VSS2SVN tool will work properly.</p> <p>You may want to copy your entire VSS database to your local computer for the migration.  First make sure that no user has any checked out items in the VSS database.  Next copy the entire VSS database to your local computer.  The conversion tool may take several hours if you have a large database.  The nice thing is that the VSS2SVN tool will allow you to convert one project at a time. </p> <p>Download and run the VSS2SVN tool.  If you are on a 64 bit verison of Windows you will need to download the source code for VSS2SVN.  Open the solution in Visual Studio 2008, add an x86 configuration to the project and rebuild.  By default it is built for any CPU, but VSS only provides x86 versions of its automation DLL.  VSS2SVN uses this automation DLL so we must have a 32 bit (x86) build of the VSS2SVN tool.</p> <p>The VSS2SVN tool is under-documented.  First you need to set the VSS Parameters.  This includes: Path to Scrsafe.ini, User name, Password, and VSS project to use.  Browse to your copy of your VSS databases srcsafe.ini folder, enter your VSS user name and password, enter the path to the project to be converted and then click the ‘Find file in source safe’ button.</p> <p><a href="http://lh6.ggpht.com/_xiL_ba2B_Sc/TI_vaEpWxiI/AAAAAAAAADI/AhL1aDJ9hDg/s1600-h/image%5B12%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/TI_vaz4ztjI/AAAAAAAAADM/NfHHRtgST3Q/image_thumb%5B6%5D.png?imgmax=800" width="706" height="408" /></a> </p> <p>   </p> <p></p> <p>Click ‘OK’ to dismiss this dialog and then the General and SVN parameters become available to be edited.  Set the working directory to something like %TEMP% and check the ‘Delete temporary files when done’ button.  Fill out the ‘SVN path to use’ with the path to the trunk of the repository that you created at the beginning of this blog post and click the ‘Migrate to subversion’ button.  This may take <strong>a long time!</strong>  It depends on the size of the project and the number of revisions that is has.  Your SourceSafe history will be converted to subversion revisions.</p> <p>When this is done you can open the web interface to Collabnet Subversion and browse through your source repository.  Collabnet also provides Windows command line subversion tools, as well as Visual Studio and Eclipse plug-ins.</p> <p></p> <p></p> <p></p> </li> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com1tag:blogger.com,1999:blog-8601661143216171909.post-50123729105822115312010-09-10T11:09:00.001-04:002010-09-10T11:09:00.736-04:00VC++ Directories in Visual Studio 2010<p>The default include, lib, etc… directories in Visual Studio 2010 are no longer project dependent.  You can, if you need to, over-ride the settings on a per project basis.  The directory settings are stored in the following location:</p> <blockquote> <p>%USERPROFILE%\AppData\Local\Microsoft\MSBuild\v4.0</p> </blockquote> <p>In this directory you will find the files:  Microsoft.Cpp.Win32.user.props, Microsoft.Cpp.x64.user.props, and Microsoft.Itanium.user.props  (the last two only if you have installed the x64 tools).</p> <p>These files are UTF-8 encoded XML files.  In them you can define your include, lib, executable, reference, and source paths.  You can also define excluded directories.  These settings become the defaults for all C++ projects.  Of course the Win32 file is for 32 bit Windows builds, while the x64 file is for 64 bit AMD64 builds.  I don’t know anyone that has an Itanium computer so I won’t even discuss those.</p> <p>This is great now that you don’t have to search and replace through every .vcproj file (I know .vcxproj file in 2010) every time you want to change an include path.  Just change the paths in these files and all projects are updated.</p> <p><strong>Teams: <br /></strong>You can store your Microsoft.Cpp.xxx.user.props files in source control.  Each team member can pull down the required files so that everyone is on the same path (bad pun, couldn’t resist).</p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-39190012828436096122010-09-03T23:37:00.003-04:002010-09-03T23:43:54.603-04:00My Thanks to the ProfilerI recently had an issue at work with one of our kernel mode file system filters for Windows. The CPU was spending way too much time executing our drivers code. I ran the kernrate sampling profiler tool from the Windows Driver Kit on our driver to see what code was taking so long to execute. The profiler revealed that over 50% of the time that our driver was executing in a function named RtlUnicodeStStri. This is a function that I wrote that is similar to the strstr function in the C standard library with the exception that it is case-insensitive and it works on UNICODE_STRING structures. In the Windows kernel, UNICODE_STRING structures are used in place of character arrays. The structure is defined like this:<br />
<br />
<span style="font-family: Consolas;">typedef struct _UNICODE_STRING <br />
{ <br />
USHORT Length; <br />
USHORT MaximumLength; <br />
PWCH Buffer; <br />
} UNICODE_STRING, *PUNICODE_STRING; </span><br />
<br />
Windows includes type definitions of USHORT as unsigned short and PWCH as wchar_t*. When using UNICODE_STRING structures you have the length of the string (in bytes) and the maximum length (i.e. the buffer size) of the string (in bytes). This provides many benefits: you can safely detect if any operation will overrun your string buffer, you can compare lengths before comparing strings, etc… The strings stored in the Buffer member of the UNICODE_STRING structure are not guaranteed to be NULL terminated and many times they are not. Thus you can not use the standard C library functions on the Buffer member.<br />
Although the Windows kernel internally uses the UNICODE_STRING, there is not a very comprehensive library for handling UNICODE_STRINGS (The string handling functions are in the Rtl library). This causes many developers like myself to write functions like RtlUnicodeStrStri. Below is the original version of RtlUnicodeStrStri that I had written. <br />
<div class="highlight" style="background: #f8f8f8;"><pre style="line-height: 125%;"><span class="lineno"> 1</span> __drv_maxIRQL(APC_LEVEL)
<span class="lineno"> 2</span> NTSTATUS
<span class="lineno"> 3</span> RtlUnicodeStrStri(
<span class="lineno"> 4</span> __in PCUNICODE_STRING Str,
<span class="lineno"> 5</span> __in PCUNICODE_STRING SubStr,
<span class="lineno"> 6</span> __out_opt PUNICODE_STRING Result,
<span class="lineno"> 7</span> __out_opt <span style="color: #b00040;">int</span><span style="color: #666666;">*</span> MatchStartIndex
<span class="lineno"> 8</span> )
<span class="lineno"> 9</span> {
<span class="lineno">10</span> USHORT l1<span style="color: #666666;">=0</span>, l2<span style="color: #666666;">=0</span>;
<span class="lineno">11</span> USHORT start <span style="color: #666666;">=</span> <span style="color: #666666;">0</span>;
<span class="lineno">12</span>
<span class="lineno">13</span> <span style="color: #408080; font-style: italic;">// Translate all counts to character counts.</span>
<span class="lineno">14</span> <span style="color: green; font-weight: bold;">const</span> USHORT StrCharLen <span style="color: #666666;">=</span> Str<span style="color: #666666;">-></span>Length <span style="color: #666666;">/</span> <span style="color: green; font-weight: bold;">sizeof</span>(WCHAR);
<span class="lineno">15</span> <span style="color: green; font-weight: bold;">const</span> USHORT SubStrCharLen <span style="color: #666666;">=</span> SubStr<span style="color: #666666;">-></span>Length <span style="color: #666666;">/</span> <span style="color: green; font-weight: bold;">sizeof</span>(WCHAR);
<span class="lineno">16</span>
<span class="lineno">17</span> ASSERT_VALID_STRING(Str);
<span class="lineno">18</span> ASSERT_VALID_STRING(SubStr);
<span class="lineno">19</span>
<span class="lineno">20</span> <span style="color: green; font-weight: bold;">while</span> (start <span style="color: #666666;"><</span> StrCharLen)
<span class="lineno">21</span> {
<span class="lineno">22</span> <span style="color: green; font-weight: bold;">for</span> (l1<span style="color: #666666;">=</span>start,l2<span style="color: #666666;">=0</span>; l1<span style="color: #666666;"><</span>StrCharLen <span style="color: #666666;">&&</span> l2<span style="color: #666666;"><</span>SubStrCharLen; <span style="color: #666666;">++</span>l1, <span style="color: #666666;">++</span>l2)
<span class="lineno">23</span> {
<span class="lineno">24</span> <span style="color: green; font-weight: bold;">if</span> (RtlUpcaseUnicodeChar(Str<span style="color: #666666;">-></span>Buffer[l1]) <span style="color: #666666;">!=</span>
<span class="lineno">25</span> RtlUpcaseUnicodeChar(SubStr<span style="color: #666666;">-></span>Buffer[l2]))
<span class="lineno">26</span> {
<span class="lineno">27</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">28</span> }
<span class="lineno">29</span> }
<span class="lineno">30</span> }
<span class="lineno">31</span>
<span class="lineno">32</span> <span style="color: #408080; font-style: italic;">// other code removed...</span>
<span class="lineno">33</span>
<span class="lineno">34</span> } <span style="color: #408080; font-style: italic;">// RtlUnicodeStrStri</span></pre><br />
</div>At first glance, I thought that the function was fairly straightforward. Then I noticed one particular optimization that should have been made. In the worst case, when the sub-string is not present, the algorithm continues to look through the entire source string even when the remaining length of the source string is too short to hold the sub-string. This is an optimization that can not be made in the C version of strstr because you have no idea in advance how long the source string. The full code is given below. <br />
<br />
<div class="highlight" style="background: #f8f8f8;"><br />
<pre style="line-height: 125%;"><span class="lineno"> 1</span> __drv_maxIRQL(APC_LEVEL)
<span class="lineno"> 2</span> NTSTATUS
<span class="lineno"> 3</span> RtlUnicodeStrStri(
<span class="lineno"> 4</span> __in PCUNICODE_STRING Str,
<span class="lineno"> 5</span> __in PCUNICODE_STRING SubStr,
<span class="lineno"> 6</span> __out_opt PUNICODE_STRING Result,
<span class="lineno"> 7</span> __out_opt <span style="color: #b00040;">int</span><span style="color: #666666;">*</span> MatchStartIndex
<span class="lineno"> 8</span> )
<span class="lineno"> 9</span> <span style="color: #408080; font-style: italic;">/*++</span>
<span class="lineno">10</span>
<span class="lineno">11</span> <span style="color: #408080; font-style: italic;">Routine Description:</span>
<span class="lineno">12</span>
<span class="lineno">13</span> <span style="color: #408080; font-style: italic;"> This routine search Str for the first occurrence of the string SubStr</span>
<span class="lineno">14</span> <span style="color: #408080; font-style: italic;"> in a case insensitive manner. If Result is provided and the search is</span>
<span class="lineno">15</span> <span style="color: #408080; font-style: italic;"> successful, it will be filled in with the string starting at the matched </span>
<span class="lineno">16</span> <span style="color: #408080; font-style: italic;"> sub-string.</span>
<span class="lineno">17</span>
<span class="lineno">18</span> <span style="color: #408080; font-style: italic;">Arguments:</span>
<span class="lineno">19</span>
<span class="lineno">20</span> <span style="color: #408080; font-style: italic;"> Str - The string to search.</span>
<span class="lineno">21</span> <span style="color: #408080; font-style: italic;"> </span>
<span class="lineno">22</span> <span style="color: #408080; font-style: italic;"> SubStr - The string to search for.</span>
<span class="lineno">23</span>
<span class="lineno">24</span> <span style="color: #408080; font-style: italic;"> Result - Result of the search starting at the sub-string and </span>
<span class="lineno">25</span> <span style="color: #408080; font-style: italic;"> continuing through the rest of Str. This structure </span>
<span class="lineno">26</span> <span style="color: #408080; font-style: italic;"> justs points to the string in Str.</span>
<span class="lineno">27</span>
<span class="lineno">28</span> <span style="color: #408080; font-style: italic;"> MatchStartIndex - The starting index within Str at which SubStr</span>
<span class="lineno">29</span> <span style="color: #408080; font-style: italic;"> appears. </span>
<span class="lineno">30</span>
<span class="lineno">31</span> <span style="color: #408080; font-style: italic;">Return Value:</span>
<span class="lineno">32</span>
<span class="lineno">33</span> <span style="color: #408080; font-style: italic;"> STATUS_SUCCESS if SubStr was found in Str, </span>
<span class="lineno">34</span> <span style="color: #408080; font-style: italic;"> STATUS_OBJECT_NAME_NOT_FOUND otherwise.</span>
<span class="lineno">35</span>
<span class="lineno">36</span> <span style="color: #408080; font-style: italic;">Unit test:</span>
<span class="lineno">37</span> <span style="color: #408080; font-style: italic;"> </span>
<span class="lineno">38</span> <span style="color: #408080; font-style: italic;"> UnitTest4() via RtlWStrStri</span>
<span class="lineno">39</span>
<span class="lineno">40</span> <span style="color: #408080; font-style: italic;">--*/</span>
<span class="lineno">41</span> {
<span class="lineno">42</span> USHORT l1<span style="color: #666666;">=0</span>, l2<span style="color: #666666;">=0</span>;
<span class="lineno">43</span> USHORT start <span style="color: #666666;">=</span> <span style="color: #666666;">0</span>;
<span class="lineno">44</span>
<span class="lineno">45</span> <span style="color: #408080; font-style: italic;">// Translate all counts to character counts.</span>
<span class="lineno">46</span> <span style="color: green; font-weight: bold;">const</span> USHORT StrCharLen <span style="color: #666666;">=</span> Str<span style="color: #666666;">-></span>Length <span style="color: #666666;">/</span> <span style="color: green; font-weight: bold;">sizeof</span>(WCHAR);
<span class="lineno">47</span> <span style="color: green; font-weight: bold;">const</span> USHORT SubStrCharLen <span style="color: #666666;">=</span> SubStr<span style="color: #666666;">-></span>Length <span style="color: #666666;">/</span> <span style="color: green; font-weight: bold;">sizeof</span>(WCHAR);
<span class="lineno">48</span>
<span class="lineno">49</span> ASSERT_VALID_STRING(Str);
<span class="lineno">50</span> ASSERT_VALID_STRING(SubStr);
<span class="lineno">51</span>
<span class="lineno">52</span> <span style="color: #408080; font-style: italic;">// Run the loop while the length of the sub-string (SubStr) is less</span>
<span class="lineno">53</span> <span style="color: #408080; font-style: italic;">// than the remaining length of the input string being searched (Str). </span>
<span class="lineno">54</span> <span style="color: green; font-weight: bold;">while</span> (start <span style="color: #666666;"><</span> StrCharLen <span style="color: #666666;">&&</span> (SubStrCharLen <span style="color: #666666;"><=</span> (StrCharLen <span style="color: #666666;">-</span> start)))
<span class="lineno">55</span> {
<span class="lineno">56</span> <span style="color: green; font-weight: bold;">for</span> (l1<span style="color: #666666;">=</span>start,l2<span style="color: #666666;">=0</span>; l1<span style="color: #666666;"><</span>StrCharLen <span style="color: #666666;">&&</span> l2<span style="color: #666666;"><</span>SubStrCharLen; <span style="color: #666666;">++</span>l1, <span style="color: #666666;">++</span>l2)
<span class="lineno">57</span> {
<span class="lineno">58</span> <span style="color: green; font-weight: bold;">if</span> (RtlUpcaseUnicodeChar(Str<span style="color: #666666;">-></span>Buffer[l1]) <span style="color: #666666;">!=</span>
<span class="lineno">59</span> RtlUpcaseUnicodeChar(SubStr<span style="color: #666666;">-></span>Buffer[l2]))
<span class="lineno">60</span> {
<span class="lineno">61</span> <span style="color: green; font-weight: bold;">break</span>;
<span class="lineno">62</span> }
<span class="lineno">63</span> }
<span class="lineno">64</span>
<span class="lineno">65</span> <span style="color: green; font-weight: bold;">if</span> (l2 <span style="color: #666666;">==</span> SubStrCharLen)
<span class="lineno">66</span> {
<span class="lineno">67</span> <span style="color: green; font-weight: bold;">if</span> (ARGUMENT_PRESENT(Result))
<span class="lineno">68</span> {
<span class="lineno">69</span> <span style="color: #408080; font-style: italic;">// Translate start back to byte count.</span>
<span class="lineno">70</span> l1 <span style="color: #666666;">=</span> start <span style="color: #666666;">*</span> <span style="color: green; font-weight: bold;">sizeof</span>(WCHAR);
<span class="lineno">71</span>
<span class="lineno">72</span> Result<span style="color: #666666;">-></span>Length <span style="color: #666666;">=</span> Str<span style="color: #666666;">-></span>Length <span style="color: #666666;">-</span> l1;
<span class="lineno">73</span> Result<span style="color: #666666;">-></span>MaximumLength <span style="color: #666666;">=</span> Str<span style="color: #666666;">-></span>MaximumLength <span style="color: #666666;">-</span> l1;
<span class="lineno">74</span> Result<span style="color: #666666;">-></span>Buffer <span style="color: #666666;">=</span> <span style="color: #666666;">&</span>Str<span style="color: #666666;">-></span>Buffer[start];
<span class="lineno">75</span> }
<span class="lineno">76</span>
<span class="lineno">77</span> <span style="color: green; font-weight: bold;">if</span> (ARGUMENT_PRESENT(MatchStartIndex))
<span class="lineno">78</span> {
<span class="lineno">79</span> <span style="color: #666666;">*</span>MatchStartIndex <span style="color: #666666;">=</span> start;
<span class="lineno">80</span> }
<span class="lineno">81</span>
<span class="lineno">82</span> <span style="color: green; font-weight: bold;">return</span> STATUS_SUCCESS;
<span class="lineno">83</span> }
<span class="lineno">84</span>
<span class="lineno">85</span> <span style="color: #666666;">++</span>start;
<span class="lineno">86</span> }
<span class="lineno">87</span>
<span class="lineno">88</span> <span style="color: green; font-weight: bold;">return</span> STATUS_OBJECT_NAME_NOT_FOUND;
<span class="lineno">89</span>
<span class="lineno">90</span> } <span style="color: #408080; font-style: italic;">// RtlUnicodeStrStri</span></pre><br />
</div>This optimization dropped our drivers execution time dramatically, to an acceptable level, though RtlUnicodeStrStri was still responsible for about %30 of our drivers execution time. I tried to optimize the calls to RtlUpcaseUnicodeChar (A Windows API) by doing quick translations for English ASCII codes (including ignoring chars that were already up-cased). It turns out that RtlUpcaseUnicodeChar is very very good and any optimization attempt I made just made the driver’s execution time worse.<br />
<br />
It turns out that our programmer’s (including myself) just got lazy and overused RtlUnicodeStrStri. I mean, why parse a string and do a compare on the part of interest when you can just call RtlUnicodeStrStri? So I wrote many more UNICODE_STRING handling functions like RtlStringEndsWithSuffix that can replace many calls to RtlUnicodeStrStri and more clearly capture the programmer’s intention in the code.janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-30503297083239913112010-09-01T13:43:00.001-04:002010-09-01T13:43:37.168-04:00Porting C# Code to IronPython, an Example<p>Lately, I have been reading Jeff Richter’s book “CLR via C#, 3rd Edition.”  I have read several of Jeff Richter’s programming books over the years, mostly his series of books on programming Windows with C/C++.  I have always liked his writing.  He is not afraid to say that Microsoft has made a mistake by providing a Windows API or technology that is substandard.  He won’t just complain about it, no, he will go on to say how he would have done it (and provide code).  Don’t get me wrong here, he also points out many things that Microsoft has done well.  I just respect the fact that he is not afraid to provide a dissenting opinion.</p> <p>In chapter 26 of “CLR via C#, 3rd, Ed.,” “Compute-Bound Asynchronous Operations”  there is a cool example of using Task objects from the System.Threading.Task namespace.  This small example demonstrates several features of Task objects including using a TaskScheduler to sync back to the GUI thread, cancelling a task, and using a continuation task to execute another action after a task completes.  The sample uses a contrived example of a compute bound function named Sum that keeps the CPU busy for a while by adding integers from 0 through some number n.  This program is a simple Windows Forms application.  I have modified it slightly to use a button instead of just detecting a mouse click on the form.  Below is the form and the C# code that appeared in the book (modified by me).</p> <p>  <a href="http://lh6.ggpht.com/_xiL_ba2B_Sc/TH6QvQFaQAI/AAAAAAAAACY/gOhYvVAHh4c/s1600-h/form3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="form" border="0" alt="form" src="http://lh5.ggpht.com/_xiL_ba2B_Sc/TH6Qvg6EuNI/AAAAAAAAACc/A0hU7jbjctY/form_thumb1.png?imgmax=800" width="323" height="158" /></a></p> <div style="background: #f8f8f8" class="highlight"> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="border-bottom: #ff0000 1px solid; border-left: #ff0000 1px solid; border-top: #ff0000 1px solid; border-right: #ff0000 1px solid"></span><span style="color: #008000; font-weight: bold">using</span> <span style="color: #0000ff; font-weight: bold">System</span>;<br /><span class="lineno"> 2</span> <span style="color: #008000; font-weight: bold">using</span> <span style="color: #0000ff; font-weight: bold">System.Windows.Forms</span>;<br /><span class="lineno"> 3</span> <span style="color: #008000; font-weight: bold">using</span> <span style="color: #0000ff; font-weight: bold">System.Threading</span>;<br /><span class="lineno"> 4</span> <span style="color: #008000; font-weight: bold">using</span> <span style="color: #0000ff; font-weight: bold">System.Threading.Tasks</span>;<br /><span class="lineno"> 5</span> <br /><span class="lineno"> 6</span> <span style="color: #008000; font-weight: bold">namespace</span> <span style="color: #0000ff; font-weight: bold">TaskSchedTest</span><br /><span class="lineno"> 7</span> {<br /><span class="lineno"> 8</span> <span style="color: #008000; font-weight: bold">public</span> <span style="color: #008000; font-weight: bold">partial</span> <span style="color: #008000; font-weight: bold">class</span> <span style="color: #0000ff; font-weight: bold">Form1</span> : Form<br /><span class="lineno"> 9</span> {<br /><span class="lineno">10</span> <span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">readonly</span> TaskScheduler m_syncContextTaskScheduler;<br /><span class="lineno">11</span> <span style="color: #008000; font-weight: bold">private</span> CancellationTokenSource m_cts;<br /><span class="lineno">12</span> <br /><span class="lineno">13</span> <span style="color: #008000; font-weight: bold">public</span> <span style="color: #0000ff">Form1</span>()<br /><span class="lineno">14</span> {<br /><span class="lineno">15</span> m_syncContextTaskScheduler = <br /><span class="lineno">16</span> TaskScheduler.FromCurrentSynchronizationContext();<br /><span class="lineno">17</span> <br /><span class="lineno">18</span> InitializeComponent();<br /><span class="lineno">19</span> }<br /><span class="lineno">20</span> <br /><span class="lineno">21</span> <span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">void</span> <span style="color: #0000ff">button1_Click</span>(<span style="color: #b00040">object</span> sender, EventArgs e)<br /><span class="lineno">22</span> {<br /><span class="lineno">23</span> <span style="color: #008000; font-weight: bold">if</span> (<span style="color: #008000; font-weight: bold">null</span> != m_cts)<br /><span class="lineno">24</span> {<br /><span class="lineno">25</span> m_cts.Cancel();<br /><span class="lineno">26</span> }<br /><span class="lineno">27</span> <span style="color: #008000; font-weight: bold">else</span><br /><span class="lineno">28</span> {<br /><span class="lineno">29</span> label1.Text = <span style="color: #ba2121">"Operation Running..."</span>;<br /><span class="lineno">30</span> button1.Text = <span style="color: #ba2121">"Cancel Task"</span>;<br /><span class="lineno">31</span> <br /><span class="lineno">32</span> <span style="font-style: italic; color: #408080">// Define a function to reset the state of the program</span><br /><span class="lineno">33</span> <span style="font-style: italic; color: #408080">// upon task completion.</span><br /><span class="lineno">34</span> Func<String, Int32> reset = (String labelText) =><br /><span class="lineno">35</span> {<br /><span class="lineno">36</span> label1.Text = labelText;<br /><span class="lineno">37</span> m_cts = <span style="color: #008000; font-weight: bold">null</span>;<br /><span class="lineno">38</span> button1.Text = <span style="color: #ba2121">"Run Task"</span>;<br /><span class="lineno">39</span> <span style="color: #008000; font-weight: bold">return</span> <span style="color: #666666">0</span>;<br /><span class="lineno">40</span> };<br /><span class="lineno">41</span> <br /><span class="lineno">42</span> m_cts = <span style="color: #008000; font-weight: bold">new</span> CancellationTokenSource();<br /><span class="lineno">43</span> <br /><span class="lineno">44</span> <span style="font-style: italic; color: #408080">// This task uses the default task scheduler and executes</span><br /><span class="lineno">45</span> <span style="font-style: italic; color: #408080">// on a thread pool thread.</span><br /><span class="lineno">46</span> var t = <span style="color: #008000; font-weight: bold">new</span> Task<Int64>(() => Sum(m_cts.Token, <span style="color: #666666">200000000</span>), m_cts.Token);<br /><span class="lineno">47</span> t.Start();<br /><span class="lineno">48</span> <br /><span class="lineno">49</span> <span style="font-style: italic; color: #408080">// These tasks use the syn context task schedules and execute</span><br /><span class="lineno">50</span> <span style="font-style: italic; color: #408080">// on the GUI thread.</span><br /><span class="lineno">51</span> t.ContinueWith(task => { reset(<span style="color: #ba2121">"Result: "</span> + task.Result); },<br /><span class="lineno">52</span> CancellationToken.None, <br /><span class="lineno">53</span> TaskContinuationOptions.OnlyOnRanToCompletion,<br /><span class="lineno">54</span> m_syncContextTaskScheduler);<br /><span class="lineno">55</span> <br /><span class="lineno">56</span> t.ContinueWith(task => { reset(<span style="color: #ba2121">"Operation canceled"</span>); },<br /><span class="lineno">57</span> CancellationToken.None, <br /><span class="lineno">58</span> TaskContinuationOptions.OnlyOnCanceled,<br /><span class="lineno">59</span> m_syncContextTaskScheduler);<br /><span class="lineno">60</span> <br /><span class="lineno">61</span> t.ContinueWith(task => { reset(<span style="color: #ba2121">"Operation faulted"</span>); },<br /><span class="lineno">62</span> CancellationToken.None, <br /><span class="lineno">63</span> TaskContinuationOptions.OnlyOnFaulted,<br /><span class="lineno">64</span> m_syncContextTaskScheduler);<br /><span class="lineno">65</span> }<br /><span class="lineno">66</span> }<br /><span class="lineno">67</span> <br /><span class="lineno">68</span> <span style="color: #008000; font-weight: bold">private</span> <span style="color: #008000; font-weight: bold">static</span> Int64 <span style="color: #0000ff">Sum</span>(CancellationToken ct, Int32 n)<br /><span class="lineno">69</span> {<br /><span class="lineno">70</span> Int64 sum = <span style="color: #666666">0</span>;<br /><span class="lineno">71</span> <span style="color: #008000; font-weight: bold">for</span> (; n > <span style="color: #666666">0</span>; n--)<br /><span class="lineno">72</span> {<br /><span class="lineno">73</span> <span style="font-style: italic; color: #408080">// The following throws OperationCanceledException when Cancel</span><br /><span class="lineno">74</span> <span style="font-style: italic; color: #408080">// is called on the CancellationTokenSource referred by the token</span><br /><span class="lineno">75</span> ct.ThrowIfCancellationRequested();<br /><span class="lineno">76</span> <span style="color: #008000; font-weight: bold">checked</span> { sum += n; }<br /><span class="lineno">77</span> }<br /><span class="lineno">78</span> <br /><span class="lineno">79</span> <span style="color: #008000; font-weight: bold">return</span> sum;<br /><span class="lineno">80</span> }<br /><span class="lineno">81</span> }<br /><span class="lineno">82</span> }</pre><br /></div><br /><br /><p>I added the reset function that is used within the lambda expressions in the ContinueWith method calls.  I like this code because it is very succinct and it doesn’t pollute your class namespace with a bunch of private functions that are only used within this one method call.  The performance hit of creating the reset function and the lambda expressions are negligible as well.  The C# compiler actually generates an internal class that contains as method members the lambda expression functions.  You can see this in the image below taken from ildasm.exe.  The compiler generated class is called <>c__DisplayClass7 and the lambda expressions from the ContinueWith method calls are named <button1_Click>b__2, <button1_Click>b__3, and <button1_Click>b__4. You can also see the reset function object as a field.        </p><br /><br /><p><a href="http://lh3.ggpht.com/_xiL_ba2B_Sc/TH6QwHFIfHI/AAAAAAAAACg/61rwPE5RWMs/s1600-h/ildasm15.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ildasm1" border="0" alt="ildasm1" src="http://lh4.ggpht.com/_xiL_ba2B_Sc/TH6QwXEgKDI/AAAAAAAAACk/7GdzZNgE5XQ/ildasm1_thumb3.png?imgmax=800" width="525" height="515" /></a></p><br /><br /><p>I liked this sample so much that I wanted to port it to IronPython.  I enjoy Python programming and I have been trying to incorporate IronPython into my work whenever it makes sense to do so.  Being that Python and IronPython are dynamic languages, interfacing the to the .NET Framework can make the syntax cumbersome and not very Pythonic at times.  You must ensure that your IronPython code is using the correct types because the .NET Framework is statically typed. A lot of the time the IronPython interpreter will infer the correct types for you and everything just works.  At other times, the IronPython interpreter does not infer the correct types and you are left with a runtime exception.  For this IronPython example I changed to a Windows Presentation Foundation application, mostly because Visual Studio has a drag and drop WPF editor for IronPython.  Below is the WPF form with XAML and the IronPython code.</p><br /><br /><p><a href="http://lh3.ggpht.com/_xiL_ba2B_Sc/TH6Qw45l1hI/AAAAAAAAACo/GacGIqBti-Q/s1600-h/wpf3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="wpf" border="0" alt="wpf" src="http://lh3.ggpht.com/_xiL_ba2B_Sc/TH6QxMUsw1I/AAAAAAAAACs/gYuXSWjyHF8/wpf_thumb1.png?imgmax=800" width="347" height="180" /></a> </p><br /><br /><p></p><br /><br /><p><a href="http://lh6.ggpht.com/_xiL_ba2B_Sc/TH6QxsIBwqI/AAAAAAAAACw/qjNW08Uv078/s1600-h/xaml5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="xaml" border="0" alt="xaml" src="http://lh3.ggpht.com/_xiL_ba2B_Sc/TH6QyCTI-_I/AAAAAAAAAC0/GVJ-t_7MOcg/xaml_thumb3.png?imgmax=800" width="561" height="246" /></a></p><br /><br /><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span class="lineno"> 1</span> <span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000ff; font-weight: bold">clr</span><br /><span class="lineno"> 2</span> clr<span style="color: #666666">.</span>AddReference(<span style="color: #ba2121">'PresentationFramework'</span>)<br /><span class="lineno"> 3</span> <br /><span class="lineno"> 4</span> <span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000ff; font-weight: bold">System</span> <span style="color: #008000; font-weight: bold">import</span> Func<br /><span class="lineno"> 5</span> <span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000ff; font-weight: bold">System.Windows</span> <span style="color: #008000; font-weight: bold">import</span> Application, Window<br /><span class="lineno"> 6</span> <span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000ff; font-weight: bold">System.Threading</span> <span style="color: #008000; font-weight: bold">import</span> CancellationTokenSource, CancellationToken<br /><span class="lineno"> 7</span> <span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000ff; font-weight: bold">System.Threading.Tasks</span> <span style="color: #008000; font-weight: bold">import</span> (Task, TaskScheduler,<br /><span class="lineno"> 8</span> TaskContinuationOptions<br /><span class="lineno"> 9</span> )<br /><span class="lineno">10</span> <br /><span class="lineno">11</span> <span style="color: #008000; font-weight: bold">class</span> <span style="color: #0000ff; font-weight: bold">MyWindow</span>(Window):<br /><span class="lineno">12</span> <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000ff">__init__</span>(<span style="color: #008000">self</span>):<br /><span class="lineno">13</span> clr<span style="color: #666666">.</span>LoadComponent(<span style="color: #ba2121">'WpfApplication1.xaml'</span>, <span style="color: #008000">self</span>)<br /><span class="lineno">14</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>cts <span style="color: #666666">=</span> <span style="color: #008000">None</span><br /><span class="lineno">15</span> <br /><span class="lineno">16</span> <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000ff">AppLoaded</span>(<span style="color: #008000">self</span>, sender, e):<br /><span class="lineno">17</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>syncContextTaskScheduler <span style="color: #666666">=</span> TaskScheduler<span style="color: #666666">.</span>FromCurrentSynchronizationContext()<br /><span class="lineno">18</span> <br /><span class="lineno">19</span> <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000ff">Button_Click</span>(<span style="color: #008000">self</span>, sender, e):<br /><span class="lineno">20</span> <span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>cts <span style="color: #aa22ff; font-weight: bold">is</span> <span style="color: #aa22ff; font-weight: bold">not</span> <span style="color: #008000">None</span>:<br /><span class="lineno">21</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>cts<span style="color: #666666">.</span>Cancel()<br /><span class="lineno">22</span> <span style="color: #008000; font-weight: bold">else</span>:<br /><span class="lineno">23</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>label1<span style="color: #666666">.</span>Content <span style="color: #666666">=</span> <span style="color: #ba2121">"Operation Running..."</span>;<br /><span class="lineno">24</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>button1<span style="color: #666666">.</span>Content <span style="color: #666666">=</span> <span style="color: #ba2121">"Cancel Task"</span>;<br /><span class="lineno">25</span> <br /><span class="lineno">26</span> <span style="font-style: italic; color: #408080"># Define a function to reset the state of the program</span><br /><span class="lineno">27</span> <span style="font-style: italic; color: #408080"># upon task completion.</span><br /><span class="lineno">28</span> <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000ff">reset</span>(labelText):<br /><span class="lineno">29</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>label1<span style="color: #666666">.</span>Content <span style="color: #666666">=</span> labelText<br /><span class="lineno">30</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>button1<span style="color: #666666">.</span>Content <span style="color: #666666">=</span> <span style="color: #ba2121">"Run Task"</span><br /><span class="lineno">31</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>cts <span style="color: #666666">=</span> <span style="color: #008000">None</span><br /><span class="lineno">32</span> <br /><span class="lineno">33</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>cts <span style="color: #666666">=</span> CancellationTokenSource();<br /><span class="lineno">34</span> <br /><span class="lineno">35</span> <span style="font-style: italic; color: #408080"># This task uses the default task scheduler and executes</span><br /><span class="lineno">36</span> <span style="font-style: italic; color: #408080"># on a thread pool thread.</span><br /><span class="lineno">37</span> t <span style="color: #666666">=</span> Task[<span style="color: #008000">long</span>](<span style="color: #008000; font-weight: bold">lambda</span>: <span style="color: #008000">self</span><span style="color: #666666">.</span>Sum(<span style="color: #008000">self</span><span style="color: #666666">.</span>cts<span style="color: #666666">.</span>Token, <span style="color: #666666">2000000</span>), <span style="color: #008000">self</span><span style="color: #666666">.</span>cts<span style="color: #666666">.</span>Token)<br /><span class="lineno">38</span> t<span style="color: #666666">.</span>Start()<br /><span class="lineno">39</span> <br /><span class="lineno">40</span> NoneType <span style="color: #666666">=</span> <span style="color: #008000">type</span>(<span style="color: #008000">None</span>)<br /><span class="lineno">41</span> <span style="font-style: italic; color: #408080"># These tasks use the syn context task schedules and execute</span><br /><span class="lineno">42</span> <span style="font-style: italic; color: #408080"># on the GUI thread.</span><br /><span class="lineno">43</span> t<span style="color: #666666">.</span>ContinueWith[NoneType](<br /><span class="lineno">44</span> Func[Task[<span style="color: #008000">long</span>], NoneType](<br /><span class="lineno">45</span> <span style="color: #008000; font-weight: bold">lambda</span> task: reset(<span style="color: #ba2121">"Result: {0}"</span><span style="color: #666666">.</span>format(task<span style="color: #666666">.</span>Result))<br /><span class="lineno">46</span> ),<br /><span class="lineno">47</span> CancellationToken<span style="color: #666666">.</span>None, <br /><span class="lineno">48</span> TaskContinuationOptions<span style="color: #666666">.</span>OnlyOnRanToCompletion,<br /><span class="lineno">49</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>syncContextTaskScheduler)<br /><span class="lineno">50</span> <br /><span class="lineno">51</span> t<span style="color: #666666">.</span>ContinueWith[NoneType](<br /><span class="lineno">52</span> Func[Task[<span style="color: #008000">long</span>], NoneType](<br /><span class="lineno">53</span> <span style="color: #008000; font-weight: bold">lambda</span> task: reset(<span style="color: #ba2121">"Operation canceled."</span>)<br /><span class="lineno">54</span> ),<br /><span class="lineno">55</span> CancellationToken<span style="color: #666666">.</span>None, <br /><span class="lineno">56</span> TaskContinuationOptions<span style="color: #666666">.</span>OnlyOnCanceled,<br /><span class="lineno">57</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>syncContextTaskScheduler)<br /><span class="lineno">58</span> <br /><span class="lineno">59</span> t<span style="color: #666666">.</span>ContinueWith[NoneType](<br /><span class="lineno">60</span> Func[Task[<span style="color: #008000">long</span>], NoneType](<br /><span class="lineno">61</span> <span style="color: #008000; font-weight: bold">lambda</span> task: reset(<span style="color: #ba2121">"Operation faulted."</span>)<br /><span class="lineno">62</span> ),<br /><span class="lineno">63</span> CancellationToken<span style="color: #666666">.</span>None, <br /><span class="lineno">64</span> TaskContinuationOptions<span style="color: #666666">.</span>OnlyOnFaulted,<br /><span class="lineno">65</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>syncContextTaskScheduler)<br /><span class="lineno">66</span> <br /><span class="lineno">67</span> <span style="color: #aa22ff">@staticmethod</span><br /><span class="lineno">68</span> <span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000ff">Sum</span>(cancellationToken, n):<br /><span class="lineno">69</span> <span style="color: #008000">sum</span> <span style="color: #666666">=</span> <span style="color: #666666">0L</span><br /><span class="lineno">70</span> <span style="color: #008000; font-weight: bold">for</span> i <span style="color: #aa22ff; font-weight: bold">in</span> <span style="color: #008000">xrange</span>(n <span style="color: #666666">+</span> <span style="color: #666666">1</span>):<br /><span class="lineno">71</span> cancellationToken<span style="color: #666666">.</span>ThrowIfCancellationRequested()<br /><span class="lineno">72</span> <span style="color: #008000">sum</span> <span style="color: #666666">+=</span> i<br /><span class="lineno">73</span> <span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000">sum</span><br /><span class="lineno">74</span> <br /><span class="lineno">75</span> <br /><span class="lineno">76</span> <span style="color: #008000; font-weight: bold">if</span> __name__ <span style="color: #666666">==</span> <span style="color: #ba2121">'__main__'</span>:<br /><span class="lineno">77</span> Application()<span style="color: #666666">.</span>Run(MyWindow())</pre><br /></div><br /><br /><p>The most difficult part of this port was getting the .NET Framework generic types correct.  When constructing the initial Task object, I had to use the Task[long] notation for generics with IronPython.  Without the generic parameter, the IronPython interpreter would produce a non-generic Task object and this version of the Task object does not have a Result property as the generic parameter is the result type (line 37).  The nice thing about this line is that I could pass in a Python lambda expression directly and the interpreter infers the proper .NET type, Func[long], in this case.  As you can see later in the code this is not the case.  For those that do not know, generic syntax in IronPython differs from C#. For example: Task<TResult>, in C# you may have Task<Int64> where in IronPython you would write Task[long].  </p><br /><br /><p>The ContinueWith method calls on lines 43, 51, and 59 gave me the most trouble.  I found that if I tried to pass the lambda expressions directly as the first parameter to ContinueWith, the IronPython interpreter would generate a Func[Task, long] object, when in fact I needed to have Func[Task[long], NoneType] objects.  This is because each of these lambda expressions are called with a single parameter of type Task[long] and they do not have a return value.  In C# this would be void, IronPython it would be NoneType.  To make this work, I had to explicitly create Func[Task[long], NoneType] objects and pass them into ContinueWith.  Luckily I could pass the Python lambda expressions directly to the Func constructor.  I also used the generic notation on the ContinueWith[NoneType] calls to state that they do not have any return value.  </p><br /><br /><p>When I first coded this up I had mistakenly used Func[Task[long], long] objects and ContinueWith[long] method calls.  This is stating that the functions will take a Task[long] parameter (which is correct) and return a long value (which is not correct).  This actually seemed to work, at least until the Finalizer thread ran!  When the Func[Task[long], long] object was called by the framework, an exception was thrown because it was expecting a long value to be returned but received NoneType.  It seemed to work because my function had already executed.  The Finalizer thread would see that a Task had thrown an exception.  It would then pack up this exception into an AggregateException and throw that object.  </p><br /><br /><p>I had fun porting this sample to IronPython and I hope to use it more in my daily work.  Interfacing with the .NET Framework with IronPython can be a very non-Pythonic experience, but this just how it is when you cross the dynamic to static type boundary.</p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-90909418060485411392010-07-02T09:57:00.001-04:002010-07-02T09:57:06.155-04:00Py2Exe and SQLAlchemy<p>I recently had the task of delivering an application written in Python to a large customer.  This would be the first application developed with Python that my company has distributed.  We chose to use Py2Exe for distribution of this program.  Py2Exe is a Python distutils extension that takes your Python code as input and outputs Windows executables that can run without a local Python installation.  Read about it at <a href="http://www.py2exe.org" target="_blank">www.py2exe.org</a>.  I have blogged about it before as well, you can read that <a href="http://japrogbits.blogspot.com/2010/03/multiprocessing-py2exe-and-windows.html" target="_blank">here</a>.</p> <p>At times Py2Exe will not be able to determine that you are using some Python modules and packages.  In this case you will have to manually include them or your resultant binary file will raise an ImportError and stop running.  This is the case when using SQLAlchemy.  </p> <p>SQLAlchemy is an awesome Python based SQL toolkit and ORM package.  Read all about it at <a href="http://www.sqlalchemy.org">www.sqlalchemy.org</a>.  SQLAlchemy was completely new to me.  I wanted to learn about it so I forced myself to use it on this project.  I have had a very good experience with SQLAlchemy and will use it again whenever I can.  Below is my setup.py file that I used for my application with names and descriptions replaced with meaningless names.  </p> <div style="background: #f8f8f8" class="highlight"> <pre style="line-height: 125%"><span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000ff; font-weight: bold">distutils.core</span> <span style="color: #008000; font-weight: bold">import</span> setup<br /><span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000ff; font-weight: bold">py2exe</span> <span style="font-style: italic; color: #408080">#@UnusedImport</span><br /><span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000ff; font-weight: bold">platform</span><br /> <br /><span style="font-style: italic; color: #408080"># 1. List of python modules to exclude from the distribution</span><br />mod_excludes <span style="color: #666666">=</span> [<br /> <span style="color: #ba2121">"Tkinter"</span>,<br /> <span style="color: #ba2121">"doctest"</span>,<br /> <span style="color: #ba2121">"unittest"</span>,<br /> <span style="color: #ba2121">"pydoc"</span>,<br /> <span style="color: #ba2121">"pygments"</span>,<br /> <span style="color: #ba2121">"pdb"</span>,<br /> <span style="color: #ba2121">"email"</span><br />]<br /> <br /><span style="font-style: italic; color: #408080"># 2. List of dll's (and apparently exe's) to exclude from the distribution</span><br /><span style="font-style: italic; color: #408080"># if any Windows system dll appears in the dist folder, add it to this</span><br /><span style="font-style: italic; color: #408080"># list.</span><br />dll_excludes <span style="color: #666666">=</span> [<br /> <span style="color: #ba2121">"API-MS-Win-Core-LocalRegistry-L1-1-0.dll"</span>,<br /> <span style="color: #ba2121">"POWRPROF.dll"</span>,<br /> <span style="color: #ba2121">"w9xpopen.exe"</span><br />]<br /> <br /><span style="font-style: italic; color: #408080"># 3. List of python modules that are to be manually included.</span><br />mod_includes <span style="color: #666666">=</span> [<br /> <span style="color: #ba2121">"Cheetah.DummyTransaction"</span>,<br />]<br /> <br /><span style="font-style: italic; color: #408080"># 4. List of python packages that are to be manually included.</span><br />package_includes <span style="color: #666666">=</span> [<br /> <span style="color: #ba2121">"sqlite3"</span>,<br /> <span style="color: #ba2121">"sqlalchemy.dialects.sqlite"</span><br />]<br /> <br /><span style="font-style: italic; color: #408080"># 5. determine the distribution folder.</span><br />arch <span style="color: #666666">=</span> platform<span style="color: #666666">.</span>architecture()<br /><span style="color: #008000; font-weight: bold">if</span> <span style="color: #ba2121">'32bit'</span> <span style="color: #aa22ff; font-weight: bold">in</span> arch:<br /> dist_dir <span style="color: #666666">=</span> <span style="color: #ba2121">"dist-x86"</span><br /><span style="color: #008000; font-weight: bold">elif</span> <span style="color: #ba2121">'64bit'</span> <span style="color: #aa22ff; font-weight: bold">in</span> arch:<br /> dist_dir <span style="color: #666666">=</span> <span style="color: #ba2121">"dist-x64"</span><br /><span style="color: #008000; font-weight: bold">else</span>:<br /> <span style="color: #008000; font-weight: bold">raise</span> <span style="color: #d2413a; font-weight: bold">RuntimeError</span>(<span style="color: #ba2121">"Unsupported architecture!"</span>)<br /> <br /><span style="font-style: italic; color: #408080"># 6. Dictionary of options to pass to py2exe</span><br />py2exe_options <span style="color: #666666">=</span> {<br /> <span style="color: #ba2121">"optimize"</span>: <span style="color: #666666">2</span>, <span style="font-style: italic; color: #408080"># 0 (None), 1 (-O), 2 (-OO)</span><br /> <span style="color: #ba2121">"includes"</span>: mod_includes,<br /> <span style="color: #ba2121">"excludes"</span>: mod_excludes,<br /> <span style="color: #ba2121">"dll_excludes"</span>: dll_excludes,<br /> <span style="color: #ba2121">"packages"</span>: package_includes,<br /> <span style="color: #ba2121">"xref"</span>: <span style="color: #008000">False</span>,<br /> <span style="font-style: italic; color: #408080"># bundle_files: 1|2|3</span><br /> <span style="font-style: italic; color: #408080"># 1: executable and library.zip</span><br /> <span style="font-style: italic; color: #408080"># 2: executable, Python DLL, library.zip</span><br /> <span style="font-style: italic; color: #408080"># 3: executable, Python DLL, other DLLs and PYDs, library.zip</span><br /> <span style="color: #ba2121">"bundle_files"</span>: <span style="color: #666666">3</span>,<br /> <span style="color: #ba2121">"dist_dir"</span>: dist_dir<br />}<br /> <br /><span style="font-style: italic; color: #408080"># 7. call setup to create the service and the console app</span><br />setup(service<span style="color: #666666">=</span>[{<span style="color: #ba2121">'modules'</span>: <span style="color: #ba2121">'myservice'</span>,<br /> <span style="color: #ba2121">'icon_resources'</span>: [(<span style="color: #666666">1</span>, <span style="color: #ba2121">'..</span><span style="color: #bb6622; font-weight: bold">\\</span><span style="color: #ba2121">my.ico'</span>)]<br /> }],<br /> console<span style="color: #666666">=</span>[{<span style="color: #ba2121">'script'</span>: <span style="color: #ba2121">'..</span><span style="color: #bb6622; font-weight: bold">\\</span><span style="color: #ba2121">myexe.py'</span>,<br /> <span style="color: #ba2121">'icon_resources'</span>: [(<span style="color: #666666">1</span>, <span style="color: #ba2121">'..</span><span style="color: #bb6622; font-weight: bold">\\</span><span style="color: #ba2121">my.ico'</span>)]<br /> }],<br /> version<span style="color: #666666">=</span><span style="color: #ba2121">'1.0'</span>,<br /> description<span style="color: #666666">=</span><span style="color: #ba2121">'My Service'</span>,<br /> long_description<span style="color: #666666">=</span><span style="color: #ba2121">"My service verbose description."</span>,<br /> author<span style="color: #666666">=</span><span style="color: #ba2121">'Jon Anglin'</span>,<br /> author_email<span style="color: #666666">=</span><span style="color: #ba2121">'jonanglin@somewhere.com'</span>,<br /> url<span style="color: #666666">=</span><span style="color: #ba2121">'http://japrogbits.blogspot.com'</span>,<br /> options<span style="color: #666666">=</span>{<span style="color: #ba2121">"py2exe"</span>: py2exe_options}<br /> )</pre><br /></div><br /><br /><p>To make your executable run correctly, you need to tell Py2exe to include your database DB-API package and the SQLAlchemy database dialect package that you have used.  You can see this in the code above at 4.  I have indicated that Py2exe should include the sqlite3 and the sqlalchemy.dialects.sqlite packages in the final output.  You can also indicate that Py2exe should include a certain Python module.  I have done this as well (above at 3) as I was using the Cheetah template library for formatting my web reports (<a href="http://www.cheetahtemplate.org/" target="_blank">read about Cheetah</a>). </p><br /><br /><p>Also at times Py2exe may include in your output DLLs or Python package and modules that should not be included.  When a Windows system DLL ends up in my distribution folder I know for sure that I need to exclude it in my setup file.  You can see this at 2 above.  Python modules are not so easy to determine though.  You may exclude a module and suddenly find that you executable will no longer run.  If you are certain that a Python package or module is not used in your application you may exclude it as shown in 1 above.</p><br /><br /><p>I also build 32 and 64 bit versions of the software.  This is accomplished simply by running setup.py first with the 32 bit python.exe and then again with the 64 bit python.exe.  I use the currently running platform.architecture() string to create separate distribution folders for each build of the software.  You can see that at 5 above.</p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-10573598927066087552010-05-11T17:11:00.001-04:002010-05-11T17:18:25.477-04:00Programming MongoDB on Windows – Basics<p></p> <div>Here are a few samples that build on my previous post “Installing MongoDB on a Windows Server.”  The following code snippets were developed in Visual Studio 2010 with the IronPython Tools for Visual Studio installed.  You can grab these tools <a href="http://ironpython.net/tools/" target="_blank">here</a>.  </div> <div>The first code snippet queries for the one document that we inserted into the database in the previous post.  This just shows a basic connection and query using the C# programming language.  The .NET drivers for MongoDB that I am using here, mongodb-csharp, come from the following link: <a href="http://github.com/samus/mongodb-csharp" target="_blank">http://github.com/samus/mongodb-csharp</a>.</div> <div><a href="http://lh6.ggpht.com/_xiL_ba2B_Sc/S-nJmWv33VI/AAAAAAAAACA/Zaul7mhPq4Q/s1600-h/csharp%5B3%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="csharp" border="0" alt="csharp" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/S-nJm8CJCdI/AAAAAAAAACE/Cw6yYLCc8bo/csharp_thumb%5B1%5D.png?imgmax=800" width="462" height="548" /></a>  </div> <div>Next is the exact same code only in IronPython.  I had one issue while creating this simple sample.  The IronPython code would not load the MongoDB.Driver.dll that I downloaded from github.  I had to download the source for it and rebuild it.  Then, IronPython would load the assembly.</div> <div> <pre><span><a href="http://lh4.ggpht.com/_xiL_ba2B_Sc/S-nJnhNwm0I/AAAAAAAAACI/iQXNnvQKZnE/s1600-h/ipy%5B3%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ipy" border="0" alt="ipy" src="http://lh3.ggpht.com/_xiL_ba2B_Sc/S-nJoLBR2kI/AAAAAAAAACM/IHc2ZOIeX6I/ipy_thumb%5B1%5D.png?imgmax=800" width="462" height="429" /></a> </span><style type="text/css"><br /><br /></div><br /><br /><p>these are extremely simple examples though they do verify that your environment is ready to go for developing with mongodb in c# and ironpython.</p><p></p><p></p></div></div></div></div></div></div></div></div></div></div></body></html></style></pre><br /></div> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-25553168468521262662010-05-11T10:03:00.001-04:002010-05-11T10:04:00.760-04:00Installing MongoDB on a Windows Server<p>To start, I downloaded the latest mongo binaries from  <a href="http://www.mongodb.org/display/DOCS/Downloads" target="_blank">the mongo download site</a>.  This was version 1.4.2 at the time of this writing.  I was installing mongo on a 64 bit Windows 2008 server so I picked the Windows 64-bit binary package.</p> <p>On the server, I created the folder C:\Program Files\MongoDB to hold the binaries and the folder C:\ProgramData\mongodb\data to hold the mongo databases.  I then extracted the binaries from the downloaded file (mongodb-win32-x86_64-1.4.2.zip) to the C:\Program Files\MongoDB folder.  I then opened a command prompt as Administrator and installed mongo as a service by executing the following line:</p> <blockquote> <p>“C:\Program Files\MongoDB\bin\mongod” -–dbpath C:\ProgramData\mongodb\data -–install</p> </blockquote> <p>This runs the mongod.exe executable and tells it to use C:\ProgramData\mongodb\data as its database directory and to install itself as a Windows service.  It is important that you use the full path to the mongod.exe executable or else the Windows service control manager will not be able to find the executable to start the service.  The service can now be started by executing the this command from the administrative command prompt:</p> <blockquote> <p>net start MongoDB</p> </blockquote> <p>I then used the mongo.exe database client application to test the install.  I inserted a simple person record and then queried for that record.  Mongo creates a ‘test’ database and a ‘things’ collection on my behalf and inserts the document into it.  A screen shot is shown below.  You can see the object ID assigned to the document by mongoDB.</p> <p><a href="http://lh5.ggpht.com/_xiL_ba2B_Sc/S-ljnyNoNEI/AAAAAAAAABo/gcDcqVa9e_I/s1600-h/mongo-1%5B3%5D.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="mongo-1" border="0" alt="mongo-1" src="http://lh4.ggpht.com/_xiL_ba2B_Sc/S-ljoUIlJ_I/AAAAAAAAABs/U5NwM3P-1tM/mongo-1_thumb%5B1%5D.png?imgmax=800" width="661" height="237" /></a></p> <p> </p> <p>To access mongoDB from another computer the Windows firewall needs to be configured.  I allowed any domain connections to access this installation of mongo.  This may not be acceptable for your needs.  As this is a test database in my environment, this configuration is acceptable.  Here is a screen shot to show the configuration in Windows firewall.</p> <p><a href="http://lh6.ggpht.com/_xiL_ba2B_Sc/S-ljpOmouVI/AAAAAAAAABw/UE0JXJByG6Q/s1600-h/mongo-2%5B4%5D.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="mongo-2" border="0" alt="mongo-2" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/S-ljpvqWxUI/AAAAAAAAAB0/qEZFIpWK2NI/mongo-2_thumb%5B2%5D.png?imgmax=800" width="556" height="481" /></a></p> <p></p> <p> </p> <p>Now I wanted to connect to the database from another computer.  On my own desktop I then ran the mongo.exe database client to connect to the server and the ‘test’ database.  Then I queried for the known record.  The results are shown below.</p> <p><a href="http://lh6.ggpht.com/_xiL_ba2B_Sc/S-ljqGwscpI/AAAAAAAAAB4/ZuwVXyy-HL0/s1600-h/mongo-3%5B3%5D.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="mongo-3" border="0" alt="mongo-3" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/S-ljrtyOCxI/AAAAAAAAAB8/4aNT4tkuHVA/mongo-3_thumb%5B1%5D.png?imgmax=800" width="654" height="221" /></a> </p> <p>As you can see you use the <server name>/<database name> pair to connect.  There are many more options of course, but this is sufficient if you are using the defaults.  </p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-10504932188883950222010-03-11T22:52:00.001-05:002010-03-11T22:55:05.448-05:00Multiprocessing, Py2exe, and Windows Services<p>I recently ran in to an issue with using the Python standard library module multiprocessing from within a Windows service that had been frozen with Py2exe. First I’ll give a brief overview of the components involved for those that may not be familiar with them.</p> <p>A Windows service is a special type of executable that is started by the service control manager (SCM). Generally you can not just run a Windows service by double clicking on it. The service has a service main function and a control handler function that responds to events sent to the service by the SCM. You can read about services on MSDN <a href="http://msdn.microsoft.com/en-us/library/ms685141(VS.85).aspx" target="_blank">here</a>. Writing a Windows service in Python also requires the PyWin32 package. PyWin32 can be obtained <a href="http://sourceforge.net/projects/pywin32/" target="_blank">here</a></p> <p>Py2exe is an extension of distutils that turns a python module into an executable file that can run on a Windows system on which there is not an installed Python distribution. Py2exe can handle many types of executables, dlls, exe, windows services, COM objects, etc… Read all about Py2exe <a href="http://www.py2exe.org/index.cgi/FrontPage" target="_blank">here</a>.</p> <p>Multiprocessing is a part of the standard Python library in Python 2.6 and later. It is an amazing library that allows you to run any callable Python object in a different process. Read about multiprocessing <a href="http://docs.python.org/library/multiprocessing.html" target="_blank">here</a>.</p> <p>Below is a simple Windows service named MyService in a Python module. NOTE This is not a complete example of a service. The SvcDoRun method must block to keep the service alive. You can accomplish this in many ways, like by waiting on an event. I leave this as an exercise for the reader. The key part of this code is the code after importing the multiprocessing module. <em>You must provide an executable (generally a Python interpreter) that multiprocessing can use to run python scripts because your service executable will not work.</em> In the code below we are indicating to multiprocessing that it should use myapp.exe as the executable file to run processes and that myapp.exe will be in the same directory as our service executable. We will provide another Python module that Py2exe will use to build myapp.exe</p> <div style="background: #f8f8f8" class="highlight"> <pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">os</span><br /><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">sys</span><br /><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">win32security</span><br /><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">win32service</span><br /><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">win32serviceutil</span><br /><br /><span style="font-style: italic; color:#408080;"># Give the multiprocessing module a python interpreter to run</span><br /><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">multiprocessing</span><br />executable <span style="color:#666666;">=</span> os<span style="color:#666666;">.</span>path<span style="color:#666666;">.</span>join(os<span style="color:#666666;">.</span>path<span style="color:#666666;">.</span>dirname(sys<span style="color:#666666;">.</span>executable), <span style="color:#ba2121;">'myapp.exe'</span>)<br />multiprocessing<span style="color:#666666;">.</span>set_executable(executable)<br /><span style=" font-weight: bold;color:#008000;">del</span> executable<br /><br /><br /><span style=" font-weight: bold;color:#008000;">class</span> <span style=" font-weight: bold;color:#0000ff;">MyService</span>(win32serviceutil<span style="color:#666666;">.</span>ServiceFramework):<br /> _svc_name_ <span style="color:#666666;">=</span> <span style="color:#ba2121;">'MyService'</span><br /> _svc_display_name_ <span style="color:#666666;">=</span> <span style="color:#ba2121;">'MyService'</span><br /> _svc_description_ <span style="color:#666666;">=</span> <span style="color:#ba2121;">'MyService Example Program'</span><br /><span style="font-style: italic; color:#408080;"># _exe_name_ = 'pythonservice.exe' # Defaults to PythonService.exe</span><br /><span style="font-style: italic; color:#408080;"># _svc_deps_ = None # sequence of service names on which this depends</span><br /><span style="font-style: italic; color:#408080;"># _exe_args_ = None # Defaults to no arguments</span><br /><br /> <span style=" font-weight: bold;color:#008000;">def</span> <span style="color:#0000ff;">SvcDoRun</span>(<span style="color:#008000;">self</span>):<br /><br /> <span style="font-style: italic; color:#408080;"># Set the current directory to the directory from</span><br /> <span style="font-style: italic; color:#408080;"># which this executable was launched.</span><br /> currentDir <span style="color:#666666;">=</span> os<span style="color:#666666;">.</span>path<span style="color:#666666;">.</span>dirname(sys<span style="color:#666666;">.</span>executable)<br /> os<span style="color:#666666;">.</span>chdir(currentDir)<br /><br /> <span style="font-style: italic; color:#408080;"># Tell Windows which privileges you need, others are removed.</span><br /> set_privileges((win32security<span style="color:#666666;">.</span>SE_ASSIGNPRIMARYTOKEN_NAME,<br /> win32security<span style="color:#666666;">.</span>SE_CHANGE_NOTIFY_NAME,<br /> win32security<span style="color:#666666;">.</span>SE_CREATE_GLOBAL_NAME,<br /> win32security<span style="color:#666666;">.</span>SE_SHUTDOWN_NAME))<br /><br /> <span style="font-style: italic; color:#408080;"># Implement service here, and block</span><br /> <span style="font-style: italic; color:#408080;"># When this method returns the service is stopped.</span><br /><br /><br /><span style=" font-weight: bold;color:#008000;">if</span> __name__ <span style="color:#666666;">==</span> <span style="color:#ba2121;">'__main__'</span>:<br /> <span style="font-style: italic; color:#408080;"># For a service, this never gets called.</span><br /> <span style="font-style: italic; color:#408080;"># </span><br /> <span style="font-style: italic; color:#408080;"># freeze_support must be the first line</span><br /> <span style="font-style: italic; color:#408080;"># after the if __name__ == '__main__'</span><br /> multiprocessing<span style="color:#666666;">.</span>freeze_support()<br /><br /> <span style="font-style: italic; color:#408080;"># Pass the command line to the service utility library.</span><br /> <span style="font-style: italic; color:#408080;"># This can handle start, stop, install, remove and other commands.</span><br /> win32serviceutil<span style="color:#666666;">.</span>HandleCommandLine(MyService)</pre><br /></div><p>Here is the myapp.py module used to generate our executable for the multiprocessing module. This is a very simple Python script that actually does more than it needs to even for this task.</p><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">multiprocessing</span><br /><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">os</span><br /><br /><span style=" font-weight: bold;color:#008000;">def</span> <span style="color:#0000ff;">main</span> ():<br /> <span style=" font-weight: bold;color:#008000;">print</span>(<span style="color:#ba2121;">'myapp: '</span>, os<span style="color:#666666;">.</span>getpid())<br /><br /><br /><span style=" font-weight: bold;color:#008000;">if</span> __name__ <span style="color:#666666;">==</span> <span style="color:#ba2121;">'__main__'</span>:<br /> <span style="font-style: italic; color:#408080;"># freeze_support must be the first line</span><br /> <span style="font-style: italic; color:#408080;"># after the if __name__ == '__main__'</span><br /> multiprocessing<span style="color:#666666;">.</span>freeze_support()<br /> main()</pre><br /></div><p>Now all we need is a setup.py script that tells Py2exe how to build our executables. Here is the code.</p><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">from</span> <span style=" font-weight: bold;color:#0000ff;">distutils.core</span> <span style=" font-weight: bold;color:#008000;">import</span> setup<br /><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">py2exe</span><br /><br /><span style="font-style: italic; color:#408080;"># We must leave the optimization level at 1 if we use the kid template</span><br /><span style="font-style: italic; color:#408080;"># library. This leaves the doc strings in the library code. The kid </span><br /><span style="font-style: italic; color:#408080;"># templating engine parses its doc string at run time, thus if the doc </span><br /><span style="font-style: italic; color:#408080;"># string is not in the pyo file, the program crashes.</span><br /><br /><span style="font-style: italic; color:#408080;"># List of python modules to exclude from the distribution</span><br />excludes <span style="color:#666666;">=</span> [<br /> <span style="color:#ba2121;">"Tkinter"</span>,<br /> <span style="color:#ba2121;">"doctest"</span>,<br /> <span style="color:#ba2121;">"unittest"</span>,<br /> <span style="color:#ba2121;">"pydoc"</span>,<br /> <span style="color:#ba2121;">"pdb"</span><br />]<br /><br /><span style="font-style: italic; color:#408080;"># List of dll's (and apparently exe's) to exclude from the distribution</span><br /><span style="font-style: italic; color:#408080;"># if any Windows system dll appears in the dist folder, add it to this</span><br /><span style="font-style: italic; color:#408080;"># list.</span><br />dll_excludes <span style="color:#666666;">=</span> [<br /> <span style="color:#ba2121;">"API-MS-Win-Core-LocalRegistry-L1-1-0.dll"</span>,<br /> <span style="color:#ba2121;">"MPR.dll"</span>,<br /> <span style="color:#ba2121;">"MSWSOCK.DLL"</span>,<br /> <span style="color:#ba2121;">"POWRPROF.dll"</span>,<br /> <span style="color:#ba2121;">"profapi.dll"</span>,<br /> <span style="color:#ba2121;">"userenv.dll"</span>,<br /> <span style="color:#ba2121;">"w9xpopen.exe"</span>,<br /> <span style="color:#ba2121;">"wtsapi32.dll"</span><br />]<br /><br /><span style="font-style: italic; color:#408080;"># List of python modules that are to be manually included.</span><br />mod_includes <span style="color:#666666;">=</span> []<br /><br />package_includes <span style="color:#666666;">=</span> []<br /><br />py2exe_options <span style="color:#666666;">=</span> {<br /> <span style="color:#ba2121;">"optimize"</span>: <span style="color:#666666;">2</span>, <span style="font-style: italic; color:#408080;"># 0 (None), 1 (-O), 2 (-OO)</span><br /> <span style="color:#ba2121;">"excludes"</span>: excludes,<br /> <span style="color:#ba2121;">"dll_excludes"</span>: dll_excludes,<br /> <span style="color:#ba2121;">"packages"</span>: package_includes,<br /> <span style="color:#ba2121;">"xref"</span>: <span style="color:#008000;">False</span>,<br /> <span style="font-style: italic; color:#408080;"># bundle_files: 1|2|3</span><br /> <span style="font-style: italic; color:#408080;"># 1: executable and library.zip</span><br /> <span style="font-style: italic; color:#408080;"># 2: executable, Python DLL, library.zip</span><br /> <span style="font-style: italic; color:#408080;"># 3: executable, Python DLL, other DLLs and PYDs, library.zip</span><br /> <span style="color:#ba2121;">"bundle_files"</span>: <span style="color:#666666;">3</span><br />}<br /><br />setup(service<span style="color:#666666;">=</span>[{<span style="color:#ba2121;">'modules'</span>: <span style="color:#ba2121;">'myservice'</span>,<br /> <span style="color:#ba2121;">'icon_resources'</span>: [(<span style="color:#666666;">1</span>, <span style="color:#ba2121;">'myapp.ico'</span>)],<br /> }],<br /> console<span style="color:#666666;">=</span>[{<span style="color:#ba2121;">'script'</span>: <span style="color:#ba2121;">'myapp.py'</span>,<br /> <span style="color:#ba2121;">'icon_resources'</span>: [(<span style="color:#666666;">1</span>, <span style="color:#ba2121;">'myapp.ico'</span>)]<br /> }],<br /> version<span style="color:#666666;">=</span><span style="color:#ba2121;">'1.0'</span>,<br /> options<span style="color:#666666;">=</span>{<span style="color:#ba2121;">"py2exe"</span>: py2exe_options}<br /> )</pre><br /></div><p>I have skimmed this down a bit from an actual setup.py that I use at work. In practice I have found that Py2exe sometimes includes modules and libraries that are not necessary. The excludes list is a list of Python modules that you want to exclude from your distribution. Make sure that you know the modules listed here are not actually used. The dll_excludes option is a list of DLL and possibly EXE files that for whatever reason Py2exe is copying to your dist folder event though they may be Windows system DLLs (that you are most likely not allowed to redistribute), or the old w9xpopen.exe (for Windows 9x only). The mod_includes and package_includes options can be used to force inclusion of Python modules or packages that you must have in your distribution but for some reason Py2exe is not placing them in your dist folder. The work is done in the call to setup. Here we are telling it to build a service from the myservice module and a console application using the myapp.py module. Each of these output files uses the same icon as specified. We pass Py2Exe specific options to Py2Exe via the py2exe_options dictionary. Build the executables by running: </p><p><em><strong>python –OO setup.py py2exe</strong></em></p><p>Now that we have provided an executable for multiprocessing we can do this somewhere in our service:</p><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">from</span> <span style=" font-weight: bold;color:#0000ff;">multiprocessing</span> <span style=" font-weight: bold;color:#008000;">import</span> Process<br /><br /><span style=" font-weight: bold;color:#008000;">def</span> <span style="color:#0000ff;">handle_request</span>(req):<br /> <span style="font-style: italic; color:#408080;"># do something useful</span><br /> <span style=" font-weight: bold;color:#008000;">pass</span><br /><br /><span style=" font-weight: bold;color:#008000;">def</span> <span style="color:#0000ff;">on_request</span>(request):<br /> Process(target<span style="color:#666666;">=</span>handle_request, args<span style="color:#666666;">=</span>(request,))<span style="color:#666666;">.</span>start()</pre><br /></div><p><strong>The Point:</strong> In a frozen Windows service, you have to provide an executable to the multiprocessing module that can be used to run Python scripts in a new process.</p>janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com3tag:blogger.com,1999:blog-8601661143216171909.post-50150924956534348672010-03-02T17:16:00.001-05:002010-03-02T22:26:22.808-05:00Using WMI to Query Monitor Information<p>I recently had a need to programmatically determine the number, make, and model of each monitor attached to a Windows computer system. Knowing that WMI provides a bewildering array of such functionality, I started here with the WMI <a href="http://msdn.microsoft.com/en-us/library/aa394122(VS.85).aspx" target="_blank">Win32_DesktopMonitor</a> class.</p> <p align="center"><a href="http://lh4.ggpht.com/_xiL_ba2B_Sc/S42OGJrqtPI/AAAAAAAAABE/FFURASTBe0g/s1600-h/image%5B3%5D.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xiL_ba2B_Sc/S42OG5DuCHI/AAAAAAAAABI/A5Dsi3yEEMA/image_thumb%5B1%5D.png?imgmax=800" width="366" height="457" /></a> <strong>Figure 1: Win32_DesktopMonitor WMI class description.</strong></p> <p align="left">As you can see in figure 1, the information I needed is supplied by this class. I coded up a quick C# application that used this WMI class to report the monitors and thought that I was done. The problem is that each run of the program only ever showed one monitor on my system. I pulled up PythonWin and using <a href="http://timgolden.me.uk/python/wmi/index.html" target="_blank">Tim Golden's excellent WMI Python module</a> I confirmed that WMI provides only one monitor. Searching the Internet told me that I was not the first to have this problem and in fact on Windows Vista and up (I was running on Windows 7) the Win32_DesktopMonitor class only returns one monitor in many cases. The issues has something to do with the video driver changes that were introduced in Windows Vista and improved in Windows 7. Most people that encountered this problem dropped into the Win32 C API to solve the issue. I still had hope for WMI, after all Windows knows how many monitors I have and what kind they are. Once again I used Tim Golden’s WMI Python module to poke around with various WMI classes and I found the <a href="http://msdn.microsoft.com/en-us/library/aa394353(VS.85).aspx" target="_blank">Win32_PnPEntity</a> class.</p> <p align="center"><a href="http://lh3.ggpht.com/_xiL_ba2B_Sc/S42OHAXd07I/AAAAAAAAABM/Wu7fm2R2Ec0/s1600-h/image%5B7%5D.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/S42OH3EtZzI/AAAAAAAAABQ/VkzWPNxhL9Q/image_thumb%5B3%5D.png?imgmax=800" width="340" height="410" /></a> <strong>Figure 2: Win32_PnPEntity WMI class description.</strong></p> <p align="left">I did a quick query to dump all of these out to see if I could use this WMI class.</p> <div style="background: #f8f8f8" class="highlight"> <pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">import</span> <span style=" font-weight: bold;color:#0000ff;">wmi</span><br />obj <span style="color:#666666;">=</span> wmi<span style="color:#666666;">.</span>WMI()<span style="color:#666666;">.</span>Win32_PnPEntity(ConfigManagerErrorCode<span style="color:#666666;">=0</span>)</pre></div><p>The ConfigManagerErrorCode=0 parameter means that I want all devices that are working properly. Looking at my obj variable, there was a ton of data but I noticed some devices with the string “DISPLAY\\…” within it. Here is some of the output:</p><p><a href="http://lh5.ggpht.com/_xiL_ba2B_Sc/S42OIo25k9I/AAAAAAAAABU/ny0W1BEfm6w/s1600-h/image%5B21%5D.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xiL_ba2B_Sc/S42OJabNunI/AAAAAAAAABY/V11UZT_fTYA/image_thumb%5B18%5D.png?imgmax=800" width="719" height="396" /></a> </p><p>I quickly filtered my output in Python with this:</p><div style="background: #f8f8f8" class="highlight"><br /> <pre style="line-height: 125%">displays <span style="color:#666666;">=</span> [x <span style=" font-weight: bold;color:#008000;">for</span> x <span style=" font-weight: bold;color:#aa22ff;">in</span> obj <span style=" font-weight: bold;color:#008000;">if</span> <span style="color:#ba2121;">'DISPLAY'</span> <span style=" font-weight: bold;color:#aa22ff;">in</span> <span style="color:#008000;">str</span>(x)]<br /><span style=" font-weight: bold;color:#008000;">for</span> item <span style=" font-weight: bold;color:#aa22ff;">in</span> displays:<br /> <span style=" font-weight: bold;color:#008000;">print</span> item</pre><br /></div><p>And this is the result:</p><p><a href="http://lh5.ggpht.com/_xiL_ba2B_Sc/S42OJ2_0HTI/AAAAAAAAABc/hYm3hTcE6Sw/s1600-h/image%5B19%5D.png"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xiL_ba2B_Sc/S42OKUHTYlI/AAAAAAAAABg/GQTKZJGLPKk/image_thumb%5B11%5D.png?imgmax=800" width="483" height="657" /></a></p><p>This was the result that I was looking for. I have two Dell E248WFP monitors and finally WMI agreed with me. Every property is exactly the same except for the DeviceID because this is what PnP uses to distinguish between the two monitors. </p><p>I quickly re-coded my C# function to use the WMI class Win32_PnPEntity. I did make a change however. The C# version filters devices where the Service = ‘monitor’ rather than looking for ‘DISPLAY’ in the DeviceID. </p><p>Special Thanks to Tim Golden who makes WMI enjoyable in Python!</p>janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com3tag:blogger.com,1999:blog-8601661143216171909.post-63728899905329962442010-01-28T15:36:00.001-05:002010-01-28T15:36:43.168-05:00Current Python Development Environment<p>In my day job I program exclusively in the Windows environment.  I pushed hard to get Python into our development environment here.  I love Python, what a great language it is!  The problem with Python is the development tools, or as any Windows programmer will whine: “You can’t use Visual Studio!” (insert sobbing noises here).  Visual Studio spoils us, and when we can’t use it, we’re as sad as a MAC fanboi that just dropped his iPhone in the toilet.  I should say the problem with <em>free</em> Python development tools as I had no budget to try commercial tools.  I have heard that some of the commercial Python development tools, like Wing IDE, are quite good. But, after blowing the budget on Visual Studio, I was left to choose from amongst the free tools.</p> <p>Eclipse is almost Visual Studio.  Eclipse is a very nice IDE.  Add the PyDev tools from Aptana and it is a great Python development environment.  It supports Jython and IronPython development as well.  This environment support many features including:</p> <ul> <li>You can configure PyLint for static analysis.  </li> <li>Source level debugging, breakpoints, the whole bit. </li> <li>You can configure and use multiple Python interpreters. </li> <li>Constantly updated and improved, (thanks Fabio!) </li> </ul> <p>Grab the latest Eclipse Galileo at <a href="http://www.eclipse.org/downloads/" target="_blank">http://www.eclipse.org/downloads/</a>  The PyDev home page is here <a href="http://pydev.org" target="_blank">http://pydev.org</a>  Python is available here <a href="http://python.org" target="_blank">http://python.org</a></p> <p>SharpDevelop wants to be Visual Studio.  SharpDevelop is an open source IDE for the .NET world.  It is taking on Visual Studio directly, come one, Visual Studio is like a MacBook Pro, waaayyy overpriced! SharpDevelop supports an impressive array of languages: Boo, C#, F#, ILAsm, IronPython, and VB.NET.  SharpDevelop 3.1.1 comes with IronPython 2.6 in the box.  It also gives you a drag and drop Windows Forms editor just like Visual Studio, except that you can use Python!  </p> <p>Get SharpDevelop here <a href="http://www.icsharpcode.net/OpenSource/SD/Download/" target="_blank">http://www.icsharpcode.net/OpenSource/SD/Download/</a> and IronPython at this <a href="http://ironpython.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=12482#DownloadId=96606" target="_blank">Codeplex download page</a></p> <p>Unfortunately I have not had the opportunity to really use IronPython for anything real.  I have written a few toy applications with it.   I plan to spend more time with SharpDevelop and IronPython in the near future.  I have read the wonderful book “IronPython in Action” by Micheal Foord and Christian Muirhead.  My first project will be to get the cherrypy web framework working under IronPython.  Right now about half of the cherrypy test suite passes, it’s a work in progress.  But that is for another blog entry.</p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-16293006013040541142010-01-28T12:33:00.001-05:002010-01-28T12:33:32.393-05:00Useful Debugging/Reversing Web Sites and Tools<p>IDA Pro Disassembler and Debugger: <br /><a href="http://www.hex-rays.com/idapro">http://www.hex-rays.com/idapro</a></p> <p>Olly Debugger: <br /><a href="http://www.ollydbg.de/">http://www.ollydbg.de</a></p> <p>Immunity Debugger (based on Olly but with bug-fixes and Python scripting!): <br /><a href="http://www.immunityinc.com/products-immdbg.shtml">http://www.immunityinc.com/products-immdbg.shtml</a> <br /><a href="http://forum.immunityinc.com/">http://forum.immunityinc.com/</a></p> <p>PaiMei/PyDbg a reverse engineering framework: <br /><a href="http://paimei.googlecode.com">http://paimei.googlecode.com</a></p> <p>OpenRCE (Open Reverse Code Engineering): <br /><a href="http://www.openrce.org/">http://www.openrce.org</a></p> <p>Dump Analysis: <br /><a href="http://www.dumpanalysis.org/">http://www.dumpanalysis.org</a></p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-72532619384515593332010-01-28T12:29:00.001-05:002010-01-28T12:29:54.785-05:00Using Breakpoints to Skip a Function in WinDbg<p>The following is an example of how to skip a function (even if you don't have the source) in a device driver. Look at the assembly below. This is the function start/end for a 3<sup>rd</sup> party device driver function that I wish to fail without executing. First I let the stack frame get set up so I must also tear it down. I set the breakpoint at instruction f7ed0511 so that before this line executes, the breakpoint will go off. Then I give a command to the break point. The command 'reax = c0000001' sets the eax register to STATUS_UNSUCCESSFUL. The command 'reip = f7ed0735' sets the instruction pointer to the line 'pop edi' to begin the stack frame teardown. The final command 'g' tells the debugger to go. So each time this breakpoint is executed, the function is skipped with a failure code and the debugger continues execution.  You can even use the .echo command to display a message every time the breakpoint goes off.</p> <p>1: kd> u fslx+7506 <br />fslx+0x7506: <br />f7ed0506 8bff             mov edi,edi <br />f7ed0508 55               push ebp <br />f7ed0509 8bec            mov ebp,esp <br />f7ed050b 53               push ebx <br />f7ed050c 8b5d08        mov ebx,dword ptr [ebp+8] <br />f7ed050f 56                push esi <br />f7ed0510 57               push edi <br />f7ed0511 6846583430 push 30345846h <br />1: kd> u fslx+7735 <br />fslx+0x7735: <br />f7ed0735 5f       pop edi <br />f7ed0736 5e      pop esi <br />f7ed0737 5b      pop ebx <br />f7ed0738 5d      pop ebp <br />f7ed0739 c21800     ret 18h </p> <p>1: kd> bp f7ed0511 "reax = c0000001; reip = f7ed0735; g" <br />1: kd> bl <br />1 e f7ed0511 0001 (0001) fslx+0x7511 "reax = c0000001; reip = f7ed0735; g" </p> <p>With the .echo command: <br />1: kd> bp f7ed0511 "reax = c0000001; reip = f7ed0735; .echo \"skipping function...\"; g"</p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-83812934518220983992010-01-28T09:23:00.001-05:002010-02-05T23:02:42.335-05:00Exceptions: Win32 Structured Exceptions, C++ Exceptions, and Compiler Options.<p>In a Windows program that is written in the C++ language there are two types of exceptions that can be handled. The first is the Win32 structured exception that is built into the OS. The second are the C++ exceptions that are generally classes derived from std::exception.</p> <p>To handle a Win32 structured exception you would have code like so:</p> <div style="background: #f8f8f8" class="highlight"><pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">__try</span> {<br /> <span style="font-style: italic; color:#408080;">// here is my code. </span><br />} <span style=" font-weight: bold;color:#008000;">__except</span>(EXCEPTION_EXECUTE_HANDLER) {<br /> <span style="font-style: italic; color:#408080;">// handle the exception here </span><br />}</pre></div><p>To handle a C++ exception you would have code like this:<br /></p><div style="background: #f8f8f8" class="highlight"><pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">try</span> {<br /> <span style="font-style: italic; color:#408080;">// here is my code. </span><br />}<br /><span style=" font-weight: bold;color:#008000;">catch</span>(std<span style="color:#666666;">::</span>exception <span style="color:#666666;">&</span>e) {<br /> <span style="font-style: italic; color:#408080;">// handle exception here, should handle specific </span><br /> <span style="font-style: italic; color:#408080;">// exceptions that you expect in production code </span><br />}<br /><span style=" font-weight: bold;color:#008000;">catch</span>(...) {<br /> <span style="font-style: italic; color:#408080;">// handle any other type of exception </span><br /> <span style="font-style: italic; color:#408080;">// i.e. not derived from std::exception </span><br />}</pre></div><p>The question is: What happens when a win32 SE is thrown and you are using C++ exceptions? </p><p>The answer: It depends on your compiler options! </p><p>Project Properties->Configuration Properties->C/C++->Code Generation->:Enable C++ Exceptions: </p><p>The choices are:<br /> No<br /> Yes (/EHsc)<br /> Yes with with SEH Exceptions (/EHa) </p><p>If you use the setting No, you will get compiler warning C4530 for using C++ exceptions when they are not enabled. If you are treating warnings as errors like all professional programmers do, then you fix this compiler setting before going on. Runtime behavior is similar to Yes (/EHa). </p><p>If you use the setting Yes (/EHsc) C++ exceptions will be caught in catch handlers as you would expect. Win32 Structured Exceptions WILL NOT BE CAUGHT even by a catch(...) block! </p><p>If you use the setting Yes(/EHa) C++ exceptions will be caught in catch handlers as you would expect. Win32 Structured Exceptions WILL BE CAUGHT in catch(...) handlers only. </p><p>The moral of this story is: use the Yes(/EHa) setting at all times! </p><p>With the use of the Yes(/EHa) setting, you can use the function _set_se_translator to register a function that would be responsible for translating all Win32 structured exceptions into C++ exceptions. This helps to unify the error handling framework. Now you can use strongly typed C++ exceptions throughout your program. You should never have to use a catch(...) block again! </p><p><strong>Example:</strong><br /></p><div style="background: #f8f8f8" class="highlight"><pre style="line-height: 125%"><span style="color:#b00040;">void</span> my_translate(<span style="color:#b00040;">unsigned</span> <span style="color:#b00040;">int</span> code, _EXCEPTION_POINTERS <span style="color:#666666;">*</span>ep)<br />{<br /> std<span style="color:#666666;">::</span>runtime_error re(<span style="color:#ba2121;">"translated win32 SE"</span>);<br /> <span style=" font-weight: bold;color:#008000;">throw</span> re;<br />}</pre></div><br /><div style="background: #f8f8f8" class="highlight"><pre style="line-height: 125%"><span style="font-style: italic; color:#408080;">// ... somewhere in WinMain... </span><br />_set_se_translator(my_translate);</pre></div><p>In Windows each thread has its own translator function which means that you must install your translator on each thread that you create.</p>janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-64502914249262051582010-01-28T09:16:00.001-05:002010-02-05T23:05:13.747-05:00auto Keyword Re-purposed for C++ 0x<p>In the coming C++ 0x (1x ?) standard, the auto keyword has been re-purposed to behave like the var keywork in C# 3.0. Currently auto is a storage class specifier that almost no one uses. For example, the following C++ statements are equivalent:</p> <div style="background: #f8f8f8" class="highlight"> <pre style="line-height: 125%"><span style=" font-weight: bold;color:#008000;">auto</span> <span style="color:#b00040;">int</span> x <span style="color:#666666;">=</span> <span style="color:#666666;">5</span>;<br /><span style="color:#b00040;">int</span> x <span style="color:#666666;">=</span> <span style="color:#666666;">5</span>; <span style="font-style: italic; color:#408080;">//implicitly auto</span></pre></div><p>Being that this is the default, no one uses the auto keyword. So now this use of auto has been removed from C++. It is now a note to the compiler to determine the type of a variable from the usage context. For example:</p><div style="background: #f8f8f8" class="highlight"><pre style="line-height: 125%">std<span style="color:#666666;">::</span>vector<span style="color:#666666;"><</span>std<span style="color:#666666;">::</span>string<span style="color:#666666;">></span> vs;<br />std<span style="color:#666666;">::</span>string str <span style="color:#666666;">=</span> <span style="color:#ba2121;">"foo"</span>;<br />vs.push_back(str);<br /><br /><span style="font-style: italic; color:#408080;">// we all hate to type this stuff!</span><br />std<span style="color:#666666;">::</span>vector<span style="color:#666666;"><</span>std<span style="color:#666666;">::</span>string<span style="color:#666666;">>::</span>iterator iter <span style="color:#666666;">=</span> vs.begin();<br /><br /><span style="font-style: italic; color:#408080;">// now we can just type this:</span><br /><span style=" font-weight: bold;color:#008000;">auto</span> iter <span style="color:#666666;">=</span> vs.begin();</pre></div><p>I can't wait until this is supported in Visual Studio, maybe version 13 in ten years or so...</p>janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-46140348949005280832010-01-28T09:11:00.001-05:002010-01-28T09:11:50.017-05:00Install Windows 7 from a USB Flash Drive<p>This is a simple process that will allow you to boot to a USB flash drive to install Windows. First we must prepare the USB flash drive. The flash drive that is selected will be completely wiped out so make sure that it does not contain any data that is important to you. </p> <ol> <li>Run a command prompt as an Administrator </li> <li> <p>Start the diskpart program, type: diskpart </p> <ol> <li>Diskpart is a command line disk partitioning tool that accepts commands that you type. </li> </ol> </li> <li> <p>Type the commands: </p> <ol> <li> <p>List Disk </p> <ol> <li>This show a list of all disk on your computer, make a note of the disk number of your USB flash drive </li> </ol> </li> <li> <p>Select Disk <n> </p> <ol> <li>Where <n> is the disk number from the List disk command, MAKE SURE you enter the correct number. </li> </ol> </li> <li> <p>Clean </p> <ol> <li>Wipe out the disk </li> </ol> </li> <li>Create partition primary </li> <li> <p>Active </p> <ol> <li>These two commands create a primary partition and mark it as active. </li> </ol> </li> <li> <p>Format fs=fat32 quick </p> <ol> <li>Format the disk with the Fat32 file system, quick is optional. </li> </ol> </li> <li> <p>Assign </p> <ol> <li>This assigns a drive letter to the USB flash drive in Windows Explorer. </li> </ol> </li> </ol> </li> <li>Insert the Windows installation disk into your DVD drive. </li> <li>Copy the contents of the Windows Installation disk to your USB flash drive </li> </ol> <p>Now you can take that flash drive over to your netbook and install Windows 7! </p> janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-17271305786085125192010-01-27T12:07:00.001-05:002010-02-05T23:04:29.569-05:00How to Disable Code Analysis on 3rd Party Headers<p>This little snippet will disable the code analysis features of Visual C++ on header files that, for whatever reason, you can not edit or fix. This does include some Windows header files (especially ATL). </p> <div style="background: #f8f8f8" class="highlight"> <pre style="line-height: 125%"><span style="color:#bc7a00;">#include <codeanalysis/warnings.h></span><br /><br /><span style="color:#bc7a00;">#pragma warning (push)</span><br /><span style="color:#bc7a00;">#pragma warning (disable: ALL_CODE_ANALYSIS_WARNINGS)</span><br /><br /><span style="font-style: italic; color:#408080;">// include 3rd party headers here</span><br /><br /><span style="color:#bc7a00;">#pragma warning (pop)</span></pre><br /></div><p>I know this is in MSDN, but it’s easier to search this blog than MSDN!</p><p>I have chosen <a href="http://pygments.org/" target="_blank">Pygments</a> for my source code formatting. It is a Python library that handles many languages. It is the best (of about 10 or so) that I have tried by far. I am very impressed.</p>janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0tag:blogger.com,1999:blog-8601661143216171909.post-81563680299943551622010-01-27T11:40:00.000-05:002010-01-27T11:52:12.948-05:00Hello!This blog has grown out of my own need to remember stuff. It started as an internal blog at work. Many times I found my self wishing that I could access my work's Sharepoint blog from outside of work. Well that's not going to happen, so here I am. <div><br /></div><div>The intention of this blog is to post bits of computer programming knowledge. I am a software engineer (developer/programmer, whatever) by day. I use C, C++, C#, and Python on a regular basis. Most of my blog entries will be about technologies related to these languages, although I may make an occasional disparaging remark about Perl. </div><div><br /></div><div>I will be, at first, taking post from my internal work blog and re-publishing them here. After that I will mostly publish here, unless of course it is work related.</div>janglinhttp://www.blogger.com/profile/09374786046371334109noreply@blogger.com0