<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title>Logos Bible Software Code Blog</title>
  <link rel="alternate" type="text/html" href="http://code.logos.com/blog/" />
  
  <updated>2013-05-20T13:17:35-07:00</updated>
  <id>tag:code.logos.com,2011:/blog/12</id>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/LogosBibleSoftwareCodeBlog" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="logosbiblesoftwarecodeblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Continuation Tasks</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2013/05/continuation-tasks.html" />
    <updated>2013-05-17T14:40:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2013/05/continuation-tasks</id>
    <content type="html">&lt;p&gt;Last week I posted a video on &lt;a href="/blog/2013/05/starting-async-work-using-tasks.html"&gt;Starting Asynchronous Work Using Tasks&lt;/a&gt;. This week's video is on &lt;a href="http://msdn.microsoft.com/en-us/library/ee372288.aspx"&gt;Continuation Tasks&lt;/a&gt;. Continuation tasks allow you to control the flow of asynchronous operations. They are especially useful for passing data between asynchronous operations. Continuation tasks are normally created using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.continuewith.aspx"&gt;Task.ContinueWith&lt;/a&gt; method. They also can be created using methods like &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskfactory.continuewhenall.aspx"&gt;TaskFactory.ContinueWhenAll&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://fast.wistia.net/embed/iframe/u0i2yabkl3?autoPlay=true&amp;playerColor=949494&amp;popover=true&amp;version=v1&amp;videoHeight=1080&amp;videoWidth=1920&amp;volumeControl=true" class="wistia-popover[height=1080,playerColor=949494,width=1920]"&gt;&lt;img src="https://wistia.sslcs.cdngc.net/deliveries/4e8b614758de101e7e6187115f1989332ef47787.jpg?image_play_button=true&amp;image_play_button_color=949494e0&amp;image_crop_resized=580x326" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;script charset="ISO-8859-1" src="https://fast.wistia.com/static/popover-v1.js"&gt;&lt;/script&gt;

&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/qsfnqvdoVmo" height="1" width="1"/&gt;</content>
    <author>
      <name>Scott Fleischman</name>
    </author>
  </entry>

  
  <entry>
    <title>Using native DLLs from ASP.NET apps</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2013/05/using-native-dlls-from-asp-net-apps.html" />
    <updated>2013-05-14T10:06:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2013/05/using-native-dlls-from-asp-net-apps</id>
    <content type="html">&lt;p&gt;By default, ASP.NET uses &lt;a href="http://msdn.microsoft.com/en-us/library/ms404279.aspx"&gt;shadow copying&lt;/a&gt;, which "enables assemblies that are used in an application domain to be updated without unloading the application domain." Basically, it copies your assemblies to a temporary folder and runs your web app from there to avoid locking the assemblies, which would prevent you from updating those assemblies.&lt;/p&gt;

&lt;p&gt;This works great for managed DLLs, but not very well for native DLLs. ASP.NET doesn't copy the native DLLs, so the web app fails with an error that doesn't even make it obvious that a native DLL is missing or which one it is.&lt;/p&gt;

&lt;p&gt;The simplest solution I've found is to turn off shadow copying, which causes the DLLs to be loaded directly from the &lt;code&gt;bin&lt;/code&gt; directory. This is the strategy now being used in production by &lt;a href="http://biblia.com/"&gt;Biblia.com&lt;/a&gt;. Just add a &lt;a href="http://goo.gl/5RDcQ"&gt;&lt;code&gt;&amp;lt;hostingEnvironment&amp;gt;&lt;/code&gt;&lt;/a&gt; element to your &lt;code&gt;web.config&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;configuration&amp;gt;
  ...
  &amp;lt;system.web&amp;gt;
    ...
    &amp;lt;hostingEnvironment shadowCopyBinAssemblies="false" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This also works for local development, but you may find that you need to restart the app pool in order to rebuild the app. Biblia has a pre-build step that runs &lt;code&gt;appcmd stop apppool&lt;/code&gt; and a post-build step that runs &lt;code&gt;appcmd start apppool&lt;/code&gt; with the corresponding &lt;code&gt;/apppool.name&lt;/code&gt; argument.&lt;/p&gt;

&lt;p&gt;Alternatively you could consider removing &lt;code&gt;&amp;lt;hostingEnvironment&amp;gt;&lt;/code&gt; from your local &lt;code&gt;web.config&lt;/code&gt; and putting your &lt;code&gt;bin&lt;/code&gt; folder in the &lt;code&gt;PATH&lt;/code&gt; system environment variable, but that will be problematic if you have multiple web apps that depend on different builds of the native DLLs.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/r7wuxSNakjI" height="1" width="1"/&gt;</content>
    <author>
      <name>Ed Ball</name>
    </author>
  </entry>

  
  <entry>
    <title>Starting Asynchronous Work Using Tasks</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2013/05/starting-async-work-using-tasks.html" />
    <updated>2013-05-10T15:45:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2013/05/starting-async-work-using-tasks</id>
    <content type="html">&lt;p&gt;As multi-core processors are quickly becoming ubiquitous, it becomes increasingly important to use parallel and asynchronous programming techniques to create responsive, high-performance applications. The latest .NET releases have responded to this need by introducing the &lt;a href="http://msdn.microsoft.com/en-us/library/dd460717.aspx"&gt;Task Parallel Library (TPL)&lt;/a&gt; in .NET 4, and the &lt;a href="http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx"&gt;async/await keywords&lt;/a&gt; in C# 5.&lt;/p&gt;

&lt;p&gt;We have created a set of fast-paced, code-driven videos on asynchronous programming in C# using TPL and async/await, with a focus on the &lt;a href="http://msdn.microsoft.com/en-us/library/hh873175.aspx"&gt;Task-based Asynchronous Pattern (TAP)&lt;/a&gt;. If you want a concise introduction to Tasks and async/await, these videos are for you! The videos are under 5 minutes each, and are intended to give a quick overview of each subject. The accompanying blog posts have links for further study.&lt;/p&gt;

&lt;p&gt;This first video shows how to start asynchronous work using the &lt;a href="http://msdn.microsoft.com/en-us/library/hh194919.aspx"&gt;Task.Run&lt;/a&gt; method, which returns a &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx"&gt;Task&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/dd321424.aspx"&gt;Task&amp;lt;TResult&amp;gt;&lt;/a&gt;. The video also shows how to create tasks that are not run on any thread using &lt;a href="http://msdn.microsoft.com/en-us/library/dd449174.aspx"&gt;TaskCompletionSource&amp;lt;TResult&amp;gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;div id="wistia_7xs5u7a659" class="wistia_embed" style="width:580px;height:326px;" data-video-width="580" data-video-height="326"&gt;&lt;div itemprop="video" itemscope itemtype="http://schema.org/VideoObject"&gt;&lt;meta itemprop="duration" content="PT4M7S" /&gt;&lt;meta itemprop="thumbnailUrl" content="https://wistia.sslcs.cdngc.net/deliveries/7ef7af6b4b2ab33e5871ae9826d241083ef4a418.bin" /&gt;&lt;meta itemprop="contentURL" content="https://wistia.sslcs.cdngc.net/deliveries/9bde9552298ba9d9646be49660cf58a353b6909d.bin" /&gt;&lt;meta itemprop="embedURL" content="https://wistia.sslcs.cdngc.net/flash/embed_player_v2.0.swf?2013-01-16&amp;customColor=949494&amp;hdUrl%5Bext%5D=flv&amp;hdUrl%5Bheight%5D=720&amp;hdUrl%5Btype%5D=hdflv&amp;hdUrl%5Burl%5D=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F02f6d2c6442d7d9efd5e95fdeaf331742921d203.bin&amp;hdUrl%5Bwidth%5D=1280&amp;mediaDuration=247.0&amp;showVolume=true&amp;stillUrl=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F7ef7af6b4b2ab33e5871ae9826d241083ef4a418.jpg%3Fimage_crop_resized%3D580x326&amp;unbufferedSeek=false&amp;videoUrl=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F9bde9552298ba9d9646be49660cf58a353b6909d.bin" /&gt;&lt;meta itemprop="uploadDate" content="2013-05-10T15:34:29Z" /&gt;&lt;object id="wistia_7xs5u7a659_seo" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" style="display:block;height:326px;position:relative;width:580px;"&gt;&lt;param name="movie" value="https://wistia.sslcs.cdngc.net/flash/embed_player_v2.0.swf?2013-01-16"&gt;&lt;/param&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;param name="bgcolor" value="#000000"&gt;&lt;/param&gt;&lt;param name="wmode" value="opaque"&gt;&lt;/param&gt;&lt;param name="flashvars" value="customColor=949494&amp;hdUrl%5Bext%5D=flv&amp;hdUrl%5Bheight%5D=720&amp;hdUrl%5Btype%5D=hdflv&amp;hdUrl%5Burl%5D=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F02f6d2c6442d7d9efd5e95fdeaf331742921d203.bin&amp;hdUrl%5Bwidth%5D=1280&amp;mediaDuration=247.0&amp;showVolume=true&amp;stillUrl=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F7ef7af6b4b2ab33e5871ae9826d241083ef4a418.jpg%3Fimage_crop_resized%3D580x326&amp;unbufferedSeek=false&amp;videoUrl=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F9bde9552298ba9d9646be49660cf58a353b6909d.bin"&gt;&lt;/param&gt;&lt;embed src="https://wistia.sslcs.cdngc.net/flash/embed_player_v2.0.swf?2013-01-16" allowfullscreen="true" allowscriptaccess="always" bgcolor=#000000 flashvars="customColor=949494&amp;hdUrl%5Bext%5D=flv&amp;hdUrl%5Bheight%5D=720&amp;hdUrl%5Btype%5D=hdflv&amp;hdUrl%5Burl%5D=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F02f6d2c6442d7d9efd5e95fdeaf331742921d203.bin&amp;hdUrl%5Bwidth%5D=1280&amp;mediaDuration=247.0&amp;showVolume=true&amp;stillUrl=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F7ef7af6b4b2ab33e5871ae9826d241083ef4a418.jpg%3Fimage_crop_resized%3D580x326&amp;unbufferedSeek=false&amp;videoUrl=https%3A%2F%2Fwistia.sslcs.cdngc.net%2Fdeliveries%2F9bde9552298ba9d9646be49660cf58a353b6909d.bin" name="wistia_7xs5u7a659_html" style="display:block;height:100%;position:relative;width:100%;" type="application/x-shockwave-flash" wmode="opaque"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;noscript itemprop="description"&gt;Starting Asynchronous Work Using Tasks&lt;/noscript&gt;&lt;/div&gt;&lt;/div&gt;


&lt;script charset="ISO-8859-1" src="https://fast.wistia.com/static/concat/E-v1.js"&gt;&lt;/script&gt;


&lt;script&gt;
wistiaEmbed = Wistia.embed("7xs5u7a659", {
  version: "v1",
  videoWidth: 580,
  videoHeight: 326,
  volumeControl: true,
  playerColor: "949494"
});
&lt;/script&gt;


&lt;script charset="ISO-8859-1" src="https://fast.wistia.com/embed/medias/7xs5u7a659/metadata.js"&gt;&lt;/script&gt;


&lt;p&gt;For further reading, see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/en-us/download/details.aspx?id=19957"&gt;The Task-based Asynchronous Pattern&lt;/a&gt; by Stephen Toub (Microsoft)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/pfxteam/"&gt;Parallel Programming with .NET blog&lt;/a&gt;: There are many excellent articles here on async/await and tasks.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Next week's video: Continuation Tasks.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/Fxc1RqsPhCA" height="1" width="1"/&gt;</content>
    <author>
      <name>Scott Fleischman</name>
    </author>
  </entry>

  
  <entry>
    <title>Building Code at Logos: Build Repositories</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/11/building-code-at-logos-build-repositories.html" />
    <updated>2012-11-19T13:40:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/11/building-code-at-logos-build-repositories</id>
    <content type="html">&lt;p&gt;As mentioned in my last post (&lt;a href="/blog/2012/11/building-code-at-logos-sharing-code-across-projects.html"&gt;Sharing Code Across Projects&lt;/a&gt;),
developers work on the head of the &lt;code&gt;master&lt;/code&gt; branch “by convention”. This
is fine for day-to-day work, but we’d like something a little more rigorous
for our continuous integration builds.&lt;/p&gt;

&lt;p&gt;For this, we use “build repositories”. A build repository contains a
submodule for each repository required to build the project. (In the App1
example, the App1 build repo would have &lt;em&gt;App1&lt;/em&gt;, &lt;em&gt;Framework&lt;/em&gt; and &lt;em&gt;Utility&lt;/em&gt;
submodules.) The CI server simply gets the most recent commit on the &lt;code&gt;master&lt;/code&gt;
branch of the build repo, recursively updates all the submodules, then builds
the code.&lt;/p&gt;

&lt;p&gt;The problem now: how is the build repository updated? We solve this using a
tool we developed named &lt;a href="https://github.com/LogosBible/Leeroy"&gt;Leeroy&lt;/a&gt;. (So
named because we use &lt;a href="http://jenkins-ci.org/"&gt;Jenkins&lt;/a&gt; as a CI server, and
Leeroy starts the Jenkins builds. We weren’t the first ones to &lt;a href="https://github.com/search?q=leeroy+jenkins&amp;amp;type=Repositories"&gt;think of
this&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;Leeroy uses the &lt;a href="http://developer.github.com/v3/"&gt;GitHub API&lt;/a&gt; on our
&lt;a href="https://enterprise.github.com/"&gt;GitHub Enterprise&lt;/a&gt; instance to watch for
changes to the submodules in a build repo. When it detects one, it creates
a new commit (again, through the GitHub API) that updates that submodule in
the build repo. After committing, it requests the “force build” URL on the
Jenkins server to start a build. Jenkins’ standard git plugin updates the
code to the current commit in each submodule and builds it.&lt;/p&gt;

&lt;p&gt;The benefit is that we now have a permanent record of the code included in
each build (by finding the commit in the build repo for that build, then
following the submodules). For significant public releases, we also tag the
build repo and each of the submodules (for convenience).&lt;/p&gt;

&lt;p&gt;We’ve made Leeroy &lt;a href="https://github.com/LogosBible/Leeroy"&gt;available at GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Posts in the “Building Code at Logos” series:&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-repository-layout.html"&gt;Repository Layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-third-party-repositories.html"&gt;Third-Party Repositories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-sharing-code-across-projects.html"&gt;Sharing Code Across Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build Repositories&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/_I0q0DMPyxM" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Building Code at Logos: Sharing Code Across Projects</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/11/building-code-at-logos-sharing-code-across-projects.html" />
    <updated>2012-11-17T09:00:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/11/building-code-at-logos-sharing-code-across-projects</id>
    <content type="html">&lt;p&gt;We often have common code that we'd like to share across different projects.
(For example, our &lt;em&gt;Utility&lt;/em&gt; library is useful in both the desktop software
and in an ASP.NET website.)&lt;/p&gt;

&lt;p&gt;One way of sharing code is to place it in its own repository, and add it as
a &lt;a href="http://git-scm.com/book/en/Git-Tools-Submodules"&gt;submodule&lt;/a&gt; to all repos
that need it. But submodules are a bit of a pain to work with on a daily
basis (for example, &lt;code&gt;git checkout&lt;/code&gt; doesn't automatically update submodules
when switching branches; you have to remember to do this every time, or
create an alias).&lt;/p&gt;

&lt;p&gt;Submodules also make it difficult to “compose” libraries. For example, &lt;em&gt;App1&lt;/em&gt;
and &lt;em&gt;App2&lt;/em&gt; might both use &lt;em&gt;Utility&lt;/em&gt;, but they might also both use &lt;em&gt;Framework&lt;/em&gt;,
a desktop application framework that's not general-purpose enough to live in
&lt;em&gt;Utility&lt;/em&gt;, but is in its own repo. If &lt;em&gt;Framework&lt;/em&gt; itself uses &lt;em&gt;Utility&lt;/em&gt; as a
submodule, then the &lt;em&gt;App1&lt;/em&gt; and &lt;em&gt;App2&lt;/em&gt; repos might contain both &lt;code&gt;/ext/Utility&lt;/code&gt;
and &lt;code&gt;/ext/Framework/ext/Utility&lt;/code&gt;. This is a maintenance nightmare.&lt;/p&gt;

&lt;p&gt;Our choice at Logos is to clone all necessary repositories as siblings of
each other. In the &lt;em&gt;App1&lt;/em&gt; example above, we might have &lt;code&gt;C:\Code\App1&lt;/code&gt;,
&lt;code&gt;C:\Code\Framework&lt;/code&gt; and &lt;code&gt;C:\Code\Utility&lt;/code&gt; as independent repos. Dependencies
are expressed as relative paths that reference files outside the current
repo, e.g., &lt;code&gt;..\..\..\Utility\src\Utility.csproj&lt;/code&gt;. We've written a shell script
that clones all necessary repos (for a new developer) or updates all
subfolders of &lt;code&gt;C:\Code&lt;/code&gt; (to get the latest code).&lt;/p&gt;

&lt;p&gt;By convention, developers are working on the &lt;code&gt;master&lt;/code&gt; branch on each repo
(or possibly a &lt;code&gt;feature&lt;/code&gt; branch in one or more repos for a complex feature).
It&amp;rsquo;s theoretically possible for someone to push a breaking change to
&lt;em&gt;Utility&lt;/em&gt; and forget to push the corresponding change to &lt;em&gt;App1&lt;/em&gt; (a problem
that submodules do prevent), but this happens very infrequently.&lt;/p&gt;

&lt;h4&gt;Posts in the &amp;ldquo;Building Code at Logos&amp;rdquo; series:&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-repository-layout.html"&gt;Repository Layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-third-party-repositories.html"&gt;Third-Party Repositories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sharing Code Across Projects&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-build-repositories.html"&gt;Build Repositories&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/Rhzr7eBR40A" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Building Code at Logos: Third-Party Repositories</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/11/building-code-at-logos-third-party-repositories.html" />
    <updated>2012-11-16T09:50:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/11/building-code-at-logos-third-party-repositories</id>
    <content type="html">&lt;p&gt;Some of our repositories reference third-party code. In many cases,
this can be managed using &lt;a href="http://www.nuget.org"&gt;NuGet&lt;/a&gt;, but sometimes
we need to make private modifications and build from source.&lt;/p&gt;

&lt;p&gt;We accomplish this by creating a repository for the third-party code. In some cases, this repository is added as a submodule under &lt;code&gt;ext&lt;/code&gt; in the repositories that need it; in other cases, the binaries created from the code are committed to another repository's &lt;code&gt;lib&lt;/code&gt; folder. The decision depends on how complicated it is to build the code versus how useful it is for developers to have the source (and not just precompiled binaries).&lt;/p&gt;

&lt;p&gt;In the third-party repository, the &lt;code&gt;upstream&lt;/code&gt; branch contains the unmodified upstream code, while the &lt;code&gt;master&lt;/code&gt; branch contains the Logos-specific modifications.&lt;/p&gt;

&lt;p&gt;When cloning the repository locally, the &lt;code&gt;origin&lt;/code&gt; remote refers to our repository containing the third-party code. If the original third-party code is available via git, then we add an &lt;code&gt;upstream&lt;/code&gt; remote that references the original maintainer's code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Creating a ThirdParty repo from source on GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="x"&gt;# clone a local copy of the remote third-party repository&lt;/span&gt;
&lt;span class="x"&gt;git clone https://github.com/user/ExampleProject.git&lt;/span&gt;
&lt;span class="x"&gt;cd ExampleProject&lt;/span&gt;

&lt;span class="x"&gt;# rename the &amp;quot;origin&amp;quot; remote (created by clone) to &amp;quot;upstream&amp;quot;&lt;/span&gt;
&lt;span class="x"&gt;git remote rename origin upstream&lt;/span&gt;

&lt;span class="x"&gt;# add Logos&amp;#39; repo as the &amp;quot;origin&amp;quot; remote&lt;/span&gt;
&lt;span class="x"&gt;git remote add origin git@git:ThirdParty/ExampleProject.git&lt;/span&gt;

&lt;span class="x"&gt;# use this code as the &amp;quot;upstream&amp;quot; branch&lt;/span&gt;
&lt;span class="x"&gt;git checkout -b upstream&lt;/span&gt;
&lt;span class="x"&gt;git push origin upstream&lt;/span&gt;

&lt;span class="x"&gt;# work on Logos-specific modifications&lt;/span&gt;
&lt;span class="x"&gt;git checkout master&lt;/span&gt;

&lt;span class="x"&gt;** make modifications&lt;/span&gt;

&lt;span class="x"&gt;git commit -am &amp;quot;Some important changes.&amp;quot;&lt;/span&gt;

&lt;span class="x"&gt;# push the changes to our repo&lt;/span&gt;
&lt;span class="x"&gt;git push origin master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Example: Creating a ThirdParty repo from source in Subversion&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="x"&gt;# create the git repo&lt;/span&gt;
&lt;span class="x"&gt;mkdir ExampleProject&lt;/span&gt;
&lt;span class="x"&gt;cd ExampleProject&lt;/span&gt;
&lt;span class="x"&gt;git init&lt;/span&gt;

&lt;span class="x"&gt;# add Logos&amp;#39; repo as the &amp;quot;origin&amp;quot; remote&lt;/span&gt;
&lt;span class="x"&gt;git remote add origin git@git:ThirdParty/ExampleProject.git&lt;/span&gt;

&lt;span class="x"&gt;# seed it with the upstream code&lt;/span&gt;
&lt;span class="x"&gt;svn export --force http://source.example.org/repos/example/tags/1.0 .&lt;/span&gt;

&lt;span class="x"&gt;# add all the code&lt;/span&gt;
&lt;span class="x"&gt;git add -A&lt;/span&gt;
&lt;span class="x"&gt;git commit -m &amp;quot;Add Example 1.0&amp;quot;&lt;/span&gt;

&lt;span class="x"&gt;# use this code as the &amp;quot;upstream&amp;quot; branch&lt;/span&gt;
&lt;span class="x"&gt;git checkout -b upstream&lt;/span&gt;
&lt;span class="x"&gt;git push origin upstream&lt;/span&gt;

&lt;span class="x"&gt;# work on Logos-specific modifications&lt;/span&gt;
&lt;span class="x"&gt;git checkout master&lt;/span&gt;

&lt;span class="x"&gt;** make modifications&lt;/span&gt;

&lt;span class="x"&gt;git commit -am &amp;quot;Some important changes.&amp;quot;&lt;/span&gt;

&lt;span class="x"&gt;# push the changes to our repo&lt;/span&gt;
&lt;span class="x"&gt;git push origin master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Once the repository is created, we will want to update it with new versions of the third-party code when they are released (then merge in our changes).&lt;/p&gt;

&lt;p&gt;The new code gets committed to the &lt;code&gt;upstream&lt;/code&gt; branch, then that gets merged into &lt;code&gt;master&lt;/code&gt;. If necessary, conflicts are resolved, or our changes are edited/removed to reflect changes in the upstream code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Updating a ThirdParty repository from source on GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="x"&gt;# switch to the &amp;quot;upstream&amp;quot; branch, which contains the latest external code&lt;/span&gt;
&lt;span class="x"&gt;git checkout upstream&lt;/span&gt;

&lt;span class="x"&gt;# get the latest code from the &amp;quot;master&amp;quot; branch in the &amp;quot;upstream&amp;quot; repo&lt;/span&gt;
&lt;span class="x"&gt;git pull upstream master&lt;/span&gt;

&lt;span class="x"&gt;# switch to our local &amp;quot;master&amp;quot; branch, which contains Logos changes&lt;/span&gt;
&lt;span class="x"&gt;git checkout master&lt;/span&gt;

&lt;span class="x"&gt;# merge in the latest upstream code&lt;/span&gt;
&lt;span class="x"&gt;git merge upstream&lt;/span&gt;

&lt;span class="x"&gt;** fix any conflicts, and commit if necessary&lt;/span&gt;

&lt;span class="x"&gt;# push the latest merged code to our repo&lt;/span&gt;
&lt;span class="x"&gt;git push origin master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Example: Updating a ThirdParty repository from source in Subversion&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="php"&gt;&lt;span class="x"&gt;# switch to the &amp;quot;upstream&amp;quot; branch, which contains the latest external code&lt;/span&gt;
&lt;span class="x"&gt;git checkout upstream&lt;/span&gt;

&lt;span class="x"&gt;** delete all files in the working copy, except the &amp;#39;.git&amp;#39; directory&lt;/span&gt;

&lt;span class="x"&gt;# get the latest version of the third-party code&lt;/span&gt;
&lt;span class="x"&gt;svn export --force http://source.example.org/repos/example/tags/1.1 .&lt;/span&gt;

&lt;span class="x"&gt;# add all files in the working copy, then commit them&lt;/span&gt;
&lt;span class="x"&gt;git add -A&lt;/span&gt;
&lt;span class="x"&gt;git commit -m &amp;quot;Update to Example 1.1.&amp;quot;&lt;/span&gt;

&lt;span class="x"&gt;# switch to our local &amp;quot;master&amp;quot; branch, which contains Logos changes&lt;/span&gt;
&lt;span class="x"&gt;git checkout master&lt;/span&gt;

&lt;span class="x"&gt;# merge in the latest upstream code&lt;/span&gt;
&lt;span class="x"&gt;git merge upstream&lt;/span&gt;

&lt;span class="x"&gt;** fix any conflicts, and commit if necessary&lt;/span&gt;

&lt;span class="x"&gt;# push the latest merged code to our repo&lt;/span&gt;
&lt;span class="x"&gt;git push origin master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;Posts in the &amp;ldquo;Building Code at Logos&amp;rdquo; series:&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-repository-layout.html"&gt;Repository Layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Third-Party Repositories&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-sharing-code-across-projects.html"&gt;Sharing Code Across Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-build-repositories.html"&gt;Build Repositories&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/3NazpFUzHqk" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Building Code at Logos: Repository Layout</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/11/building-code-at-logos-repository-layout.html" />
    <updated>2012-11-15T09:30:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/11/building-code-at-logos-repository-layout</id>
    <content type="html">&lt;p&gt;We use &lt;a href="http://www.git-scm.com"&gt;git&lt;/a&gt; for source control, and have adopted a
standardised reposistory layout for our projects.&lt;/p&gt;

&lt;p&gt;The following example is for a Visual Studio solution on Windows, but can be
adapted for other platforms.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Repo\                  -- this is the root of the repository
  Repo.build             -- NAnt build script (or equivalent)
  Repo.sln               -- Visual Studio solution file (at root)

  src\                   -- contains primary source code
    Logos.Project\         -- one subfolder per project
      Logos.Project.csproj
      *.cs
      Properties\
        AssemblyInfo.cs
    other projects\      -- as above
  tests\                 -- contains tests for each 'src' project
    Logos.Project.Tests\   -- one subfolder per test project
      Logos.Project.Tests.csproj
      *.cs
    other test projects\ -- as above

  ext\                   -- contains submodules
    Submodule\             -- third-party source
  lib\                   -- precompiled third-party code
    *.dll
  packages\              -- NuGet packages
    Package.1.0\           -- various packages
    repositories.config    -- configuration

  build\                 -- .gitignore'd, contains build output
  tools\                 -- build tools
    NUnit\                 -- test framework
    other tools\           -- other tools as necessary
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At the root of the repository, we have the Visual Studio solution file (used
by developers) and the build script (used by the build server). This might be
a &lt;a href="http://nant.sourceforge.net/"&gt;NAnt&lt;/a&gt; build file, a
&lt;a href="https://github.com/psake/psake"&gt;psake&lt;/a&gt; build script, a shell script, or
something similar.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;src&lt;/code&gt; and &lt;code&gt;tests&lt;/code&gt; folders contain the bulk of the code we write; this is
the code that gets shipped to users or deployed to a web server, and tests
that get run by the build server.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ext&lt;/code&gt;, &lt;code&gt;lib&lt;/code&gt;, and &lt;code&gt;packages&lt;/code&gt; contain third-party code (or sometimes Logos code
that is consumed as a precompiled binary, rather than as source). Folders
under &lt;code&gt;ext&lt;/code&gt; are git submodules that reference third-party repos. &lt;code&gt;lib&lt;/code&gt;
contains pre-compiled DLLs and static libraries. &lt;code&gt;packages&lt;/code&gt; is reserved for
use by &lt;a href="http://www.nuget.org/"&gt;NuGet&lt;/a&gt;. (This folder is added to &lt;code&gt;.gitignore&lt;/code&gt;
if this repo uses NuGet Package Restore.)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;build&lt;/code&gt; is never committed, but is reserved to contain build output. &lt;code&gt;tools&lt;/code&gt;
contains code that is required to build the project, but doesn't get shipped.
This would include things like &lt;a href="http://nunit.org"&gt;NUnit&lt;/a&gt; (or another test
framework), &lt;a href="http://stylecop.codeplex.com/"&gt;StyleCop&lt;/a&gt; plugins, NAnt
extensions, mocking frameworks, etc.&lt;/p&gt;

&lt;h4&gt;Posts in the &amp;ldquo;Building Code at Logos&amp;rdquo; series:&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Repository Layout&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-third-party-repositories.html"&gt;Third-Party Repositories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-sharing-code-across-projects.html"&gt;Sharing Code Across Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/blog/2012/11/building-code-at-logos-build-repositories.html"&gt;Build Repositories&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/7Lma7jbOQmY" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>How to Crash Many WPF Applications (WPF 4 Edition)</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/11/how-to-crash-many-wpf-applications-wpf-4-edition.html" />
    <updated>2012-11-05T10:24:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/11/how-to-crash-many-wpf-applications-wpf-4-edition</id>
    <content type="html">&lt;p&gt;This is a follow-up to my three-year-old post: &lt;a href="http://code.logos.com/blog/2009/11/how_to_crash_every_wpf_application.html"&gt;How to Crash every WPF
Application&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that we’ve &lt;a href="http://blog.logos.com/2012/11/introducing-logos-bible-software-5/"&gt;released Logos 5&lt;/a&gt;,
which updates the version of WPF we target from WPF 3.5 to WPF 4.5, our
customers are really helping us stress-test WPF 4.x. (It’s now a little
sad that &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/10/26/wpf-4-vs-2010-and-net-4-0-series.aspx"&gt;after three years&lt;/a&gt;,
ours is the first (and only!) WPF 4 application installed on many of our
users’ systems.)&lt;/p&gt;

&lt;p&gt;On some systems, the application was crashing at startup with the following
exception:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;System.ArgumentException: An item with the same key has already been added.
  at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
  at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
  at MS.Internal.FontFace.PhysicalFontFamily.ConvertDictionary(IDictionary`2 dictionary)
  at MS.Internal.FontFace.PhysicalFontFamily.MS.Internal.FontFace.IFontFamily.get_Names()
  at System.Windows.Media.FontFamily.get_FamilyNames()
  at Libronix.Utility.Windows.FontFamilyUtility.&amp;lt;&amp;gt;c__DisplayClass2.&amp;lt;FindSystemFontByTitle&amp;gt;b__0(FontFamily font)
  at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
  at Libronix.Utility.Windows.FontFamilyUtility.FindSystemFontByTitle(String strTitle)
  at LDLS4.AppModel.CreateMainWindow()
  at LDLS4.OurApp.StartupCompleted()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We traced this to having a font with multiple family names in the same
culture (or two cultures that WPF considers equivalent; in this particular
case, &lt;code&gt;es-ES&lt;/code&gt; and &lt;code&gt;es-ES_tradnl&lt;/code&gt; were considered identical).
&lt;code&gt;PhysicalFontFamily.ConvertDictionary&lt;/code&gt; tries to build a dictionary mapping
cultures to names, but assumes the cultures from the font are all unique,
so inserting a duplicate value crashes.&lt;/p&gt;

&lt;p&gt;The result of this bug is that any WPF 4 application that tries to enumerate
the system fonts and get their names will crash. The most common font that
causes this bug appears to be "DiagramTTBlindAll", a symbol font installed
with ChessBase 11.&lt;/p&gt;

&lt;p&gt;Although new to us, this is not a new bug. It was &lt;a href="http://social.expression.microsoft.com/Forums/is/blend/thread/162a1356-144a-449a-b986-88f798fc8bc2"&gt;reported against Expression
Blend&lt;/a&gt;
in March 2010, and identified as a WPF bug. In February 2012, it was
&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/4cc63a4c-b611-4b1b-9114-c10ae78444e9/"&gt;re-reported&lt;/a&gt;
against the WPF designer in Visual Studio 2010. At that point a &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/568541/wpf-an-item-with-the-same-key-has-already-been-added-system-argumentexception"&gt;Connect
issue&lt;/a&gt;
already existed (but is unavailable now).&lt;/p&gt;

&lt;p&gt;Microsoft, we love WPF, but the fact that simple bugs go unfixed for 30 months
is frustrating. I know that open sourcing WPF would be much more complex
than &lt;a href="http://aspnetwebstack.codeplex.com/"&gt;open sourcing ASP.NET&lt;/a&gt;
(due to the unmanaged milcore portion and the deployment considerations), but
if you put WPF on CodePlex, I'll submit a pull request with a fix the very
next day. :-)&lt;/p&gt;

&lt;p&gt;Meanwhile, if you're a WPF 4.5 developer, here's a workaround for the crash.
Use &lt;code&gt;FontUtility.GetSystemFontFamilies()&lt;/code&gt; instead of &lt;code&gt;Fonts.SystemFontFamilies&lt;/code&gt;
if you will be accessing the names of the returned fonts.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// Provides utility methods for fonts.&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FontUtility&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// Gets the system font families.&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;A collection of system font families.&amp;lt;/returns&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;ReadOnlyCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FontFamily&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetSystemFontFamilies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FontFamily&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;systemFontFamilies&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FontFamily&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FontFamily&lt;/span&gt; &lt;span class="n"&gt;fontFamily&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Fonts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SystemFontFamilies&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// trigger the exception&lt;/span&gt;
                &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;unused&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FamilyNames&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="c1"&gt;// add the font if it didn&amp;#39;t throw&lt;/span&gt;
                &lt;span class="n"&gt;systemFontFamilies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArgumentException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// certain fonts cause WPF 4 to throw an exception when the FamilyNames property is accessed; ignore them&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;systemFontFamilies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsReadOnly&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/Kiwonj4cdok" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Always wrap GZipStream with BufferedStream</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/06/always-wrap-gzipstream-with-bufferedstream.html" />
    <updated>2012-06-08T21:55:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2012/06/always-wrap-gzipstream-with-bufferedstream</id>
    <content type="html">&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.io.compression.gzipstream.aspx"&gt;&lt;code&gt;GZipStream&lt;/code&gt;&lt;/a&gt;
and &lt;a href="http://msdn.microsoft.com/en-us/library/system.io.compression.deflatestream.aspx"&gt;&lt;code&gt;DeflateStream&lt;/code&gt;&lt;/a&gt;
don't buffer their input, so they will only compress the individual chunks
that are passed to &lt;code&gt;Write&lt;/code&gt; (or, worst-case, &lt;code&gt;WriteByte&lt;/code&gt;). Unless you can
guarantee that large blocks of data are being passed to &lt;code&gt;GZipStream.Write&lt;/code&gt;,
always wrap &lt;code&gt;GZipStream&lt;/code&gt; in a &lt;code&gt;BufferedStream&lt;/code&gt; when using &lt;code&gt;CompressionMode.Compress&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In fact, if you call only &lt;code&gt;WriteByte&lt;/code&gt; on a compressing &lt;code&gt;GZipStream&lt;/code&gt;, it will
create &amp;ldquo;compressed&amp;rdquo; output that's almost double the size of
the input.&lt;/p&gt;

&lt;p&gt;Experimentation determined that the optimal buffer size is 8K; above
this, no further compression is gained. So, to create a &lt;code&gt;GZipStream&lt;/code&gt;, use
a method similar to the following:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="nf"&gt;CreateCompressingGZipStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;leaveOpen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;BufferedStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;GZipStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CompressionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Compress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveOpen&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="m"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This chart shows how the compressed output keeps getting smaller as the
buffer size increases (and how writing just one or two bytes at a time almost
doubles the 1MB input):&lt;/p&gt;

&lt;p&gt;&lt;img src="/blog/images/gzipstream-output-size.png" alt="GZipStream output size versus buffer size" /&gt;&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;&lt;span class="c1"&gt;// determine best buffer size&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;bufferSize&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1536&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;6144&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;8192&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;16384&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;32768&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;65536&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;131072&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;262144&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MemoryStream&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GZipStream&lt;/span&gt; &lt;span class="n"&gt;compressor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;GZipStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CompressionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Compress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;leaveOpen&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BufferedStream&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BufferedStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compressor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bufferSize&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// write simple data that will compress easily&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
                &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteByte&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Buffer Size: {0:n0}, Compressed size: {1:n0}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;bufferSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/VqI0Uprvzh8" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Run MbUnit v2 tests under .NET 4</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/05/run-mbunit-v2-tests-under-net-4.html" />
    <updated>2012-05-01T07:30:00-07:00</updated>
    <id>http://code.logos.com/blog/blog/2012/05/run-mbunit-v2-tests-under-net-4</id>
    <content type="html">&lt;p&gt;We still use &lt;a href="http://www.mbunit.com/"&gt;MbUnit v2&lt;/a&gt; for some of our assemblies,
primarily because the items mentioned in the &lt;a href="http://blog.bits-in-motion.com/2008/10/announcing-gallio-and-mbunit-v304.html"&gt;migration guide&lt;/a&gt;
still haven't been implemented in MbUnit v3, and we haven't taken the time
to port the tests to NUnit.&lt;/p&gt;

&lt;p&gt;I wanted to compile our code for .NET 4 and still run all the existing tests
against it.&lt;/p&gt;

&lt;p&gt;The test runner (&lt;code&gt;MbUnit.Cons.exe&lt;/code&gt;) is a .NET 1.1 app, so by default it will
fail to load a .NET 4 test assembly. You can use the &lt;a href="http://msdn.microsoft.com/en-us/library/w4atty68.aspx"&gt;&lt;code&gt;&amp;lt;supportedRuntime&amp;gt;&lt;/code&gt;&lt;/a&gt; configuration element
to &lt;a href="http://social.msdn.microsoft.com/Forums/en/netfxsetupprerelease/thread/d6d8957e-742a-4cc2-b5c1-d9130ea423d0"&gt;force the program to run under .NET 4&lt;/a&gt;,
but it still fails to load the test assembly.&lt;/p&gt;

&lt;p&gt;The message printed at the console isn't helpful, but if you debug the test
runner, the following exception occurs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NotSupportedException: This method implicitly uses CAS
policy, which has been obsoleted by the .NET Framework.
In order to enable CAS policy for compatibility reasons,
please use the NetFx40_LegacySecurityPolicy configuration
switch.
Please see http://go.microsoft.com/fwlink/?LinkID=155570
for more information.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This occurs because MbUnit uses the obsolete &lt;a href="http://msdn.microsoft.com/en-us/library/0wcskf6d.aspx"&gt;&lt;code&gt;Assembly.Load(string, Evidence)&lt;/code&gt;&lt;/a&gt;
method. To fix this, add the &lt;code&gt;NetFx40_LegacySecurityPolicy&lt;/code&gt; configuration
element, as instructed by the exception message.&lt;/p&gt;

&lt;p&gt;Ultimately, your MbUnit.Cons.exe.config file should look as follows:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="xml"&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;runtime&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- Don&amp;#39;t kill application on first uncaught exception. --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;legacyUnhandledExceptionPolicy&lt;/span&gt; &lt;span class="na"&gt;enabled=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- Use legacy CAS policy so MbUnit&amp;#39;s assembly loading succeeds. --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NetFx40_LegacySecurityPolicy&lt;/span&gt; &lt;span class="na"&gt;enabled=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/runtime&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- Force use of .NET 4. --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;startup&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;supportedRuntime&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;v4.0&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/startup&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;With this new configuration, MbUnit can successfully run under .NET 4 and
load .NET 4 assemblies. However, it still runs as a 32-bit process, so
"Any CPU" test assemblies will get loaded as 32-bit. To make it run as 64-bit,
you can use the &lt;a href="http://msdn.microsoft.com/en-us/library/ms164699.aspx"&gt;CorFlags&lt;/a&gt;
utility. As per the &lt;a href="http://stackoverflow.com/tags/corflags/info"&gt;StackOverflow wiki&lt;/a&gt;,
an "Any CPU" application should be a PE32 executable with the 32BIT flag cleared.&lt;/p&gt;

&lt;p&gt;To change MbUnit to an "Any CPU" executable (so it runs as 64-bit on an
x64 system), run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CorFlags /UpgradeCLRHeader /32BIT- MbUnit.Cons.exe
&lt;/code&gt;&lt;/pre&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/3ubtYpr8SXg" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Persistent Hash Codes</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/02/persistent-hash-codes.html" />
    <updated>2012-02-23T06:32:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/02/persistent-hash-codes</id>
    <content type="html">&lt;p&gt;What does &lt;code&gt;"hello".GetHashCode()&lt;/code&gt; return?&lt;/p&gt;

&lt;p&gt;The answer is: it depends.&lt;/p&gt;

&lt;p&gt;Under the Microsoft .NET 4 CLR, that method returns &lt;code&gt;0xFFF561E1&lt;/code&gt; in a 32-bit application,
but &lt;code&gt;0xEC7BF82A&lt;/code&gt; in a 64-bit build. Other runtimes, such as Mono and the Compact Framework,
might return other values.&lt;/p&gt;

&lt;p&gt;As per &lt;a href="http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx"&gt;the documentation&lt;/a&gt;,
&amp;ldquo;The behavior of GetHashCode is dependent on its implementation, which might change from one version of the common language runtime to another. &amp;hellip; The value returned by GetHashCode is platform-dependent. It differs on the 32-bit and 64-bit versions of the .NET Framework.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;In certain scenarios (e.g., saving a hash code to a file, or creating a hash code on a 32-bit
client and using it on a 64-bit server), it's useful to have an algorithm that will always
generate the same hash code for the same input.&lt;/p&gt;

&lt;p&gt;Based on Paul Hsieh&amp;lsquo;s &lt;a href="http://www.azillionmonkeys.com/qed/hash.html"&gt;SuperFastHash&lt;/a&gt;,
Bob Jenkin&amp;lsquo;s &lt;a href="http://www.burtleburtle.net/bob/hash/doobs.html"&gt;hash function&lt;/a&gt;, and
Thomas Wang&amp;lsquo;s &lt;a href="http://www.concentric.net/~Ttwang/tech/inthash.htm"&gt;Integer Hash Function&lt;/a&gt;,
we developed &lt;code&gt;HashCodeUtility.GetPersistentHashCode&lt;/code&gt;. (The C# methods are basically a straightforward
port of the corresponding C functions.)&lt;/p&gt;

&lt;p&gt;These methods perform a thorough mixing of their input (so the return value works well as a
key in a hashtable), have good performance, and will always return the same result no matter
what version of the CLR they're running on.&lt;/p&gt;

&lt;p&gt;The source is available on GitHub: &lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/HashCodeUtility.cs"&gt;HashCodeUtility.cs&lt;/a&gt;,
&lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/tests/Logos.Utility.Tests/HashCodeUtilityTests.cs"&gt;HashCodeUtilityTests.cs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For information about the &lt;code&gt;CombineHashCodes&lt;/code&gt; method in those files, see my earlier post,
&lt;a href="http://code.logos.com/blog/2010/02/creating_hash_codes.html"&gt;Creating hash codes&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/oGUUbgZQcqs" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Ascii85 implementation in C#</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/02/ascii85-implementation-in-csharp.html" />
    <updated>2012-02-18T11:25:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/02/ascii85-implementation-in-csharp</id>
    <content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Ascii85"&gt;Ascii85&lt;/a&gt; is an encoding scheme that converts 4 bytes into 5 ASCII characters (in the range &lt;code&gt;!&lt;/code&gt; through &lt;code&gt;u&lt;/code&gt;). As a result, it only has 25% encoding overhead compared to the 33% of &lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;Base64&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I recently needed to smuggle some binary data through HTTP headers without &lt;a href="http://code.logos.com/blog/2012/01/webexception-the-message-limit-length-was-exceeded.html"&gt;exceeding the message length limit&lt;/a&gt;; Ascii85 seemed like the best choice.&lt;/p&gt;

&lt;p&gt;There were a couple of implementations available on the &lt;a href="http://www.codinghorror.com/blog/2009/05/the-bathroom-wall-of-code.html"&gt;bathroom wall of code&lt;/a&gt;, but they had various problems that precluded their use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No tests&lt;/li&gt;
&lt;li&gt;Few comments&lt;/li&gt;
&lt;li&gt;Unknown license&lt;/li&gt;
&lt;li&gt;Violated .NET Framework Design Guidelines&lt;/li&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Not_invented_here"&gt;NIH&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So I wrote my own. The code is available on GitHub: &lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/src/Logos.Utility/Ascii85.cs"&gt;Ascii85.cs&lt;/a&gt;, &lt;a href="https://github.com/LogosBible/Logos.Utility/blob/master/tests/Logos.Utility.Tests/Ascii85Tests.cs"&gt;Ascii85Tests.cs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As with the other code on this blog, it's released under a &lt;a href="http://code.logos.com/blog/2008/09/logos_code_blog_license.html"&gt;MIT-style license&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/XqWgO4ZbDRs" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>WebException: "The message length limit was exceeded"</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/01/webexception-the-message-limit-length-was-exceeded.html" />
    <updated>2012-01-04T13:04:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/01/webexception-the-message-limit-length-was-exceeded</id>
    <content type="html">&lt;p&gt;An uncommon &lt;code&gt;WebException&lt;/code&gt; thrown by &lt;code&gt;HttpWebRequest.GetResponse()&lt;/code&gt; has the message
"The underlying connection was closed: The message length limit was exceeded."&lt;/p&gt;

&lt;p&gt;By default, &lt;code&gt;HttpWebResponse&lt;/code&gt; only allows 64KB of HTTP headers; any more and
it will throw this exception.&lt;/p&gt;

&lt;p&gt;To resolve the issue, set the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.maximumresponseheaderslength.aspx"&gt;MaximumResponseHeadersLength&lt;/a&gt;
property on the request to a larger value, or to &lt;code&gt;-1&lt;/code&gt; for no limit. (Note that the value is
expressed in kilobytes, so the default value &lt;code&gt;64&lt;/code&gt; allows 65,536 bytes of headers.)&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/Rn9S4wz0Hig" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Avoid System.Windows.Rect.ToString()</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2012/01/avoid-system-windows-rect-tostring.html" />
    <updated>2012-01-02T12:03:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2012/01/avoid-system-windows-rect-tostring</id>
    <content type="html">&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms521832.aspx"&gt;System.Windows.Rect.ToString()&lt;/a&gt; is
documented as returning a string in &amp;ldquo;the following form: "X,Y,Width,Height"&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;It seems like this method is the complement to the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.rect.parse.aspx"&gt;Parse&lt;/a&gt;
method, which accepts the &amp;ldquo;string representation of the rectangle, in the form "x, y, width, height"&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;Unfortunately, while &lt;code&gt;Parse&lt;/code&gt; is culture-invariant (as documented), &lt;code&gt;ToString&lt;/code&gt; follows the .NET convention
of returning locale-sensitive results; you need to call the &lt;code&gt;ToString(IFormatProvider)&lt;/code&gt; overload
to produce a string in the "x,y,width,height" format (that can be accepted by &lt;code&gt;Parse&lt;/code&gt;).&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="n"&gt;Rect&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;quot;1.5,2,3.5,4&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// success&lt;/span&gt;

    &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentThread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentCulture&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CultureInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;de&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// or &amp;quot;es&amp;quot;, &amp;quot;fr&amp;quot;, etc.&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;quot;1,5;2;3,5;4&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// throws FormatException&lt;/span&gt;

    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CultureInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvariantCulture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// success&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I filed a &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/716279/rect-tostring-behavior-doesnt-match-documentation"&gt;bug report&lt;/a&gt;,
even though this is arguably an error in the documentation, not in the .NET Framework itself.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/Ui8prnilc8Y" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  
  <entry>
    <title>Printing from .NET 3.5 in Windows 7</title>
    <link rel="alternate" type="text/html" href="http://code.logos.com/blog/2011/12/printing-from-net35-in-windows7.html" />
    <updated>2011-12-30T16:01:00-08:00</updated>
    <id>http://code.logos.com/blog/blog/2011/12/printing-from-net35-in-windows7</id>
    <content type="html">&lt;p&gt;Our users discovered a curious bug that appears to be caused by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Printing an &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.xps.packaging.xpsdocument.aspx"&gt;XpsDocument&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;that uses a font embedded in the application's resources&lt;/li&gt;
&lt;li&gt;from a .NET 3.5 application&lt;/li&gt;
&lt;li&gt;running on Windows 7&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The printed output looks like the following image; various glyphs are substituted
with larger sans-serif versions of themselves, causing a ransom-note-like appearance.&lt;/p&gt;

&lt;p&gt;&lt;img src="/blog/images/corrupted-print-output.png" alt="Corrupted print output from .NET 3.5" /&gt;&lt;/p&gt;

&lt;p&gt;We found that changing any one of the conditions above fixes the problem, but
unfortunately we need to print XPS using an embedded font, we're still using .NET 3.5,
and we have to run on Windows 7.&lt;/p&gt;

&lt;p&gt;Strangely enough, printing to the XPS Document Writer print driver, and then printing
that document with the XPS Viewer built into Windows 7 doesn't reproduce the problem;
it only happens when our app prints directly to an actual printer.&lt;/p&gt;

&lt;h4&gt;&lt;strong&gt;Workaround&lt;/strong&gt;&lt;/h4&gt;

&lt;p&gt;I noticed that the XPS Viewer is a native application; this led me to
discover the Windows 7 &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff686814.aspx"&gt;XPS Print API&lt;/a&gt;.
In conjunction with the (also new in Windows 7)
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd316976.aspx"&gt;XPS Document API&lt;/a&gt;,
this lets you print XPS documents from native code.&lt;/p&gt;

&lt;p&gt;We were able to solve the problem by automating the workaround described above:
our code writes its output to an &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.xps.xpsdocumentwriter.aspx"&gt;XpsDocumentWriter&lt;/a&gt;
backed by a temporary file (instead of a &lt;a href="http://msdn.microsoft.com/en-us/library/system.printing.printqueue.aspx"&gt;PrintQueue&lt;/a&gt;);
we then use the native APIs to print the temporary XPS file to the currently-selected printer.&lt;/p&gt;

&lt;p&gt;The first part is to define the native methods and COM interfaces we will need.
(And, as noted in this &lt;a href="http://stackoverflow.com/questions/6123507/xps-printing-from-windows-service"&gt;StackOverflow question&lt;/a&gt;,
the &lt;code&gt;IXpsPrintJobStream&lt;/code&gt; interface is either declared or implemented incorrectly, so we
have to call the &lt;code&gt;Close&lt;/code&gt; method as if it existed on &lt;code&gt;ISequentialStream&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;With those declared, the printing code can be written. This method (which should be called on a
background thread), prints a XPS file to a specific printer, returning &lt;code&gt;true&lt;/code&gt; if printing
succeeded. (If it fails, the application should fall back to the .NET printing APIs.)&lt;/p&gt;

&lt;p&gt;All the code below is also available &lt;a href="https://gist.github.com/1541424"&gt;in a gist&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NativeMethods&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;        [DllImport(&amp;quot;XpsPrint.dll&amp;quot;, ExactSpelling = true, CharSet = CharSet.Unicode)]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;StartXpsPrintJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;printerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;jobName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;outputFileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;progressEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;SafeWaitHandle&lt;/span&gt; &lt;span class="n"&gt;completionEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPArray&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;printablePagesOn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;printablePagesOnCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJob&lt;/span&gt; &lt;span class="n"&gt;xpsPrintJob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;documentStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;printTicketStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;E974D26D-3D9B-4D47-88CC-3872F2DC3585&amp;quot;), ClassInterface(ClassInterfaceType.None)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XpsOMObjectFactory&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;F9B2A685-A50D-4FC2-B764-B56E093EA0CA&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsOMObjectFactory&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="na"&gt;        [return: MarshalAs(UnmanagedType.Interface)]&lt;/span&gt;
        &lt;span class="n"&gt;IXpsOMPackage&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageFromFile&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPWStr&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;reuseObjects&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageFromStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateStoryFragmentsResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDocumentStructureResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateSignatureBlockResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateRemoteDictionaryResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateRemoteDictionaryResourceFromStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePartResources&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDocumentSequence&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePageReference&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePageFromStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateCanvas&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGlyphs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGeometry&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGeometryFigure&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateMatrixTransform&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateSolidColorBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateColorProfileResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateImageBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateVisualBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateImageResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePrintTicketResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateFontResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateGradientStop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateLinearGradientBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateRadialGradientBrush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateCoreProperties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateDictionary&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePartUriCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageWriterOnFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePackageWriterOnStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreatePartUri&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;CreateReadOnlyStreamOnFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;18C3DF65-81E1-4674-91DC-FC452F5A416F&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsOMPackage&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetDocumentSequence&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetDocumentSequence&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetCoreProperties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetCoreProperties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetDiscardControlPartName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetDiscardControlPartName&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetThumbnailResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetThumbnailResource&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WriteToFile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WriteToStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;optimizeMarkupSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// NOTE: It appears that the IID for IXpsPrintJobStream specified in XpsPrint.h --  &lt;/span&gt;
    &lt;span class="c1"&gt;// MIDL_INTERFACE(&amp;quot;7a77dc5f-45d6-4dff-9307-d8cb846347ca&amp;quot;) -- is not correct, or the object&lt;/span&gt;
    &lt;span class="c1"&gt;// doesn&amp;#39;t implement QueryInterface correctly. However, we can QI for ISequentialStream and&lt;/span&gt;
    &lt;span class="c1"&gt;// successfully (at least in Windows 7 SP1 x86) call the Close method as if it existed on that&lt;/span&gt;
    &lt;span class="c1"&gt;// interface.&lt;/span&gt;
    &lt;span class="c1"&gt;// That is, we obtain the ISequentialStream interface, but work with it as the IXpsPrintJobStream interface.&lt;/span&gt;
    &lt;span class="c1"&gt;// Thanks to http://stackoverflow.com/questions/6123507/xps-printing-from-windows-service for this tip.&lt;/span&gt;
&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;0C733A30-2A1C-11CE-ADE5-00AA0044773D&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ISequentialStream methods&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPArray&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;pcbRead&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;MarshalAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UnmanagedType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LPArray&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;pcbWritten&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// IXpsPrintJobStream methods&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="na"&gt;    [ComImport, Guid(&amp;quot;5AB89B06-8194-425F-AB3B-D7A96E350161&amp;quot;), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="n"&gt;IXpsPrintJob&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="nf"&gt;GetJobStatus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;div class="highlight"&gt;&lt;pre&gt;&lt;code class="csharp"&gt;    &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// Prints the specified XPS document to a printer using the native XPS Print API.&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name=&amp;quot;xpsFilePath&amp;quot;&amp;gt;The path to the XPS document.&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name=&amp;quot;printerName&amp;quot;&amp;gt;The printer name.&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;param name=&amp;quot;printTicket&amp;quot;&amp;gt;A PrintTicket with settings for this print job.&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;c&amp;gt;true&amp;lt;/c&amp;gt; if the document was successfully printed; otherwise, &amp;lt;c&amp;gt;false&amp;lt;/c&amp;gt;.&amp;lt;/returns&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;/// &amp;lt;remarks&amp;gt;This method should be called from a background thread.&amp;lt;/remarks&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;Print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;xpsFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;printerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PrintTicket&lt;/span&gt; &lt;span class="n"&gt;printTicket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// try to create the XPS Object Model factory (only available on Windows 7 and Vista with the Platform Update)&lt;/span&gt;
        &lt;span class="n"&gt;IXpsOMObjectFactory&lt;/span&gt; &lt;span class="n"&gt;xpsFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;xpsFactory&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IXpsOMObjectFactory&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;XpsOMObjectFactory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;COMException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// OS doesn&amp;#39;t support the XPS Document API&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;IXpsOMPackage&lt;/span&gt; &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// load the saved document as a native XpsOMPackage&lt;/span&gt;
            &lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xpsFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreatePackageFromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xpsFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ManualResetEvent&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ManualResetEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// attempt to start the print job&lt;/span&gt;
                &lt;span class="n"&gt;IXpsPrintJob&lt;/span&gt; &lt;span class="n"&gt;printJob&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;IXpsPrintJobStream&lt;/span&gt; &lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;hresult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NativeMethods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartXpsPrintJob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;printerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jobTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SafeWaitHandle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;printJob&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="c1"&gt;// check for success (NOTE: checking HRESULT value directly instead of calling Marshal.ThrowExceptionForHR&lt;/span&gt;
                &lt;span class="c1"&gt;//   to avoid proliferation of &amp;#39;catch&amp;#39; blocks)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hresult&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// write the current printer settings to the print ticket stream&lt;/span&gt;
                    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;ticketData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;printTicket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetXmlStream&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="n"&gt;bytesWritten&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticketData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ticketData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;bytesWritten&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;ticketStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                    &lt;span class="c1"&gt;// write the XPS package to the document stream&lt;/span&gt;
                    &lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteToStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;docStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

                    &lt;span class="c1"&gt;// wait for printing to finish&lt;/span&gt;
                    &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WaitOne&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;COMException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// printing failed&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DllNotFoundException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// OS doesn&amp;#39;t support XPS Print API&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EntryPointNotFoundException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// OS doesn&amp;#39;t support XPS Print API&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// force the XPS package to be released, so that the temporary file can be deleted&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;package&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FinalReleaseComObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;img src="http://feeds.feedburner.com/~r/LogosBibleSoftwareCodeBlog/~4/YBJTTyhHap4" height="1" width="1"/&gt;</content>
    <author>
      <name>Bradley Grainger</name>
    </author>
  </entry>

  

</feed>
