<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Damir's Corner - Software</title>
    <link>http://www.damirscorner.com/</link>
    <description>Notes from Daily Encounters with Technology</description>
    <language>en-us</language>
    <copyright>Damir Arh, M. Sc.</copyright>
    <lastBuildDate>Sat, 07 Aug 2010 19:19:23 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>damir.arh@gmail.com</managingEditor>
    <webMaster>damir.arh@gmail.com</webMaster>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=d71190ab-f7ab-42cc-a3a0-9f3aa53d6014</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,d71190ab-f7ab-42cc-a3a0-9f3aa53d6014.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,d71190ab-f7ab-42cc-a3a0-9f3aa53d6014.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=d71190ab-f7ab-42cc-a3a0-9f3aa53d6014</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Since version 1.5 CruiseControl.NET includes an <a href="http://confluence.public.thoughtworks.org/display/CCNET/Ftp+task+-+Publisher">FTP
Task</a> which can be used for uploading build results to a remote FTP server. Its
most typical use case is for publishing websites to a remote server. Configuring this
correctly requires some thought and at the moment there are very few helpful resources
available. Below are some suggestions for the most simple case when the files to be
uploaded only have to be retrieved from the source control and there is no additional
build process involved.
</p>
        <p>
The core of the configuration is of course the FTP task. Its configuration is pretty
straightforward. You only need to supply it with login details and the path to the
local and the remote folder. This also means that there are almost no configuration
options available – you can only choose between uploading the files recursively or
not.
</p>
        <p>
The problem with the lack of options is that most source control systems put additional
files in the local folder which you don’t want to upload. In the case of Subversion
this is a .svn folder in every local folder. Because the FTP task can’t be configured
to skip or ignore certain files, these files have to be deleted before the FTP task
is executed. The best way to do that is by executing a batch file:
</p>
        <pre class="brush: batch;">FOR /F "tokens=*" %%G IN ('DIR /B /AD /S *.svn*') DO RMDIR /S /Q "%%G"</pre>
        <p>
If you do this directly in the working directory where the files are retrieved from
Subversion, then the next retrieval from source control will fail unless you set the <a href="http://confluence.public.thoughtworks.org/display/CCNET/Subversion+Source+Control+Block">cleanCopy</a> configuration
element to true and retrieve all of the files from Subversion every time. Doing this
has two downsides:
</p>
        <ul>
          <li>
If the project is large, this will significantly decrease performance. Downloading
lots of files from Subversion takes time. 
</li>
          <li>
The file timestamps will be reset every time. This information could potentially be
useful for the FTP task (but isn’t yet as I explain at the end of the post).</li>
        </ul>
        <p>
To avoid this you should first copy the retrieved files to a different folder. The
best way to do this is by using the <a href="http://confluence.public.thoughtworks.org/display/CCNET/Build+Publisher">build
publisher</a>. Just don’t forget to set the alwaysPublish configuration element to
true. Otherwise it won’t copy anything because you are using it in the tasks section
where the build is not yet successful.
</p>
        <p>
To sum it all up, your tasks section should something look like this (I’ve used <a href="http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor">preprocessor
constants</a> for most of the values to increase readability):
</p>
        <pre class="brush: xml;">&lt;tasks&gt;
    &lt;buildpublisher&gt;
        &lt;sourceDir&gt;$(WorkingDir)&lt;/sourceDir&gt;
        &lt;publishDir&gt;$(PublishDir)&lt;/publishDir&gt;
        &lt;cleanPublishDirPriorToCopy&gt;true&lt;/cleanPublishDirPriorToCopy&gt;
        &lt;useLabelSubDirectory&gt;false&lt;/useLabelSubDirectory&gt;
        &lt;alwaysPublish&gt;true&lt;/alwaysPublish&gt;
    &lt;/buildpublisher&gt;
    &lt;exec&gt;
        &lt;executable&gt;$(ClearSvnFilesBatch)&lt;/executable&gt;
        &lt;baseDirectory&gt;$(PublishDir)&lt;/baseDirectory&gt;
    &lt;/exec&gt;
    &lt;ftp&gt;
        &lt;serverName&gt;$(FtpServerName)&lt;/serverName&gt;
        &lt;userName&gt;$(FtpUserName)&lt;/userName&gt;
        &lt;password&gt;$(FtpPassword)&lt;/password&gt;
        &lt;action&gt;UploadFolder&lt;/action&gt;
        &lt;ftpFolderName&gt;$(FtpRemoteFolder)&lt;/ftpFolderName&gt;
        &lt;localFolderName&gt;$(PublishDir)&lt;/localFolderName&gt;
        &lt;recursiveCopy&gt;true&lt;/recursiveCopy&gt;
    &lt;/ftp&gt;
&lt;/tasks&gt;</pre>
        <p>
I’ll conclude this post with a bad news. Unfortunately there is no support in the
FTP task to only upload the files that have changed since the previous build. For
a small website this might not be an issue but for larger ones this is quite a problem.
You really don’t want to upload tens or even hundreds of megabytes every time. Let’s
just hope that the <a href="http://jira.public.thoughtworks.org/browse/CCNET-1938">issue</a> will
be fixed soon. 
</p>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=d71190ab-f7ab-42cc-a3a0-9f3aa53d6014" />
      </body>
      <title>Using FTP Task in CruiseControl.NET for Publishing Websites</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,d71190ab-f7ab-42cc-a3a0-9f3aa53d6014.aspx</guid>
      <link>http://www.damirscorner.com/UsingFTPTaskInCruiseControlNETForPublishingWebsites.aspx</link>
      <pubDate>Sat, 07 Aug 2010 19:19:23 GMT</pubDate>
      <description>&lt;p&gt;
Since version 1.5 CruiseControl.NET includes an &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Ftp+task+-+Publisher"&gt;FTP
Task&lt;/a&gt; which can be used for uploading build results to a remote FTP server. Its
most typical use case is for publishing websites to a remote server. Configuring this
correctly requires some thought and at the moment there are very few helpful resources
available. Below are some suggestions for the most simple case when the files to be
uploaded only have to be retrieved from the source control and there is no additional
build process involved.
&lt;/p&gt;
&lt;p&gt;
The core of the configuration is of course the FTP task. Its configuration is pretty
straightforward. You only need to supply it with login details and the path to the
local and the remote folder. This also means that there are almost no configuration
options available – you can only choose between uploading the files recursively or
not.
&lt;/p&gt;
&lt;p&gt;
The problem with the lack of options is that most source control systems put additional
files in the local folder which you don’t want to upload. In the case of Subversion
this is a .svn folder in every local folder. Because the FTP task can’t be configured
to skip or ignore certain files, these files have to be deleted before the FTP task
is executed. The best way to do that is by executing a batch file:
&lt;/p&gt;
&lt;pre class="brush: batch;"&gt;FOR /F "tokens=*" %%G IN ('DIR /B /AD /S *.svn*') DO RMDIR /S /Q "%%G"&lt;/pre&gt;
&lt;p&gt;
If you do this directly in the working directory where the files are retrieved from
Subversion, then the next retrieval from source control will fail unless you set the &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Subversion+Source+Control+Block"&gt;cleanCopy&lt;/a&gt; configuration
element to true and retrieve all of the files from Subversion every time. Doing this
has two downsides:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
If the project is large, this will significantly decrease performance. Downloading
lots of files from Subversion takes time. 
&lt;li&gt;
The file timestamps will be reset every time. This information could potentially be
useful for the FTP task (but isn’t yet as I explain at the end of the post).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
To avoid this you should first copy the retrieved files to a different folder. The
best way to do this is by using the &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Build+Publisher"&gt;build
publisher&lt;/a&gt;. Just don’t forget to set the alwaysPublish configuration element to
true. Otherwise it won’t copy anything because you are using it in the tasks section
where the build is not yet successful.
&lt;/p&gt;
&lt;p&gt;
To sum it all up, your tasks section should something look like this (I’ve used &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor"&gt;preprocessor
constants&lt;/a&gt; for most of the values to increase readability):
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;tasks&amp;gt;
    &amp;lt;buildpublisher&amp;gt;
        &amp;lt;sourceDir&amp;gt;$(WorkingDir)&amp;lt;/sourceDir&amp;gt;
        &amp;lt;publishDir&amp;gt;$(PublishDir)&amp;lt;/publishDir&amp;gt;
        &amp;lt;cleanPublishDirPriorToCopy&amp;gt;true&amp;lt;/cleanPublishDirPriorToCopy&amp;gt;
        &amp;lt;useLabelSubDirectory&amp;gt;false&amp;lt;/useLabelSubDirectory&amp;gt;
        &amp;lt;alwaysPublish&amp;gt;true&amp;lt;/alwaysPublish&amp;gt;
    &amp;lt;/buildpublisher&amp;gt;
    &amp;lt;exec&amp;gt;
        &amp;lt;executable&amp;gt;$(ClearSvnFilesBatch)&amp;lt;/executable&amp;gt;
        &amp;lt;baseDirectory&amp;gt;$(PublishDir)&amp;lt;/baseDirectory&amp;gt;
    &amp;lt;/exec&amp;gt;
    &amp;lt;ftp&amp;gt;
        &amp;lt;serverName&amp;gt;$(FtpServerName)&amp;lt;/serverName&amp;gt;
        &amp;lt;userName&amp;gt;$(FtpUserName)&amp;lt;/userName&amp;gt;
        &amp;lt;password&amp;gt;$(FtpPassword)&amp;lt;/password&amp;gt;
        &amp;lt;action&amp;gt;UploadFolder&amp;lt;/action&amp;gt;
        &amp;lt;ftpFolderName&amp;gt;$(FtpRemoteFolder)&amp;lt;/ftpFolderName&amp;gt;
        &amp;lt;localFolderName&amp;gt;$(PublishDir)&amp;lt;/localFolderName&amp;gt;
        &amp;lt;recursiveCopy&amp;gt;true&amp;lt;/recursiveCopy&amp;gt;
    &amp;lt;/ftp&amp;gt;
&amp;lt;/tasks&amp;gt;&lt;/pre&gt;
&lt;p&gt;
I’ll conclude this post with a bad news. Unfortunately there is no support in the
FTP task to only upload the files that have changed since the previous build. For
a small website this might not be an issue but for larger ones this is quite a problem.
You really don’t want to upload tens or even hundreds of megabytes every time. Let’s
just hope that the &lt;a href="http://jira.public.thoughtworks.org/browse/CCNET-1938"&gt;issue&lt;/a&gt; will
be fixed soon. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=d71190ab-f7ab-42cc-a3a0-9f3aa53d6014" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,d71190ab-f7ab-42cc-a3a0-9f3aa53d6014.aspx</comments>
      <category>Software</category>
      <category>Software/CruiseControl</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=6a11ed69-42b3-4380-89db-b0dac78d6447</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,6a11ed69-42b3-4380-89db-b0dac78d6447.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,6a11ed69-42b3-4380-89db-b0dac78d6447.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=6a11ed69-42b3-4380-89db-b0dac78d6447</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently I’ve been solving some issues with queue starvation in CruiseControl.NET.
Since I haven’t found much information about this problem I’ve decided to round up
my findings in this blog post.
</p>
        <p>
So, what is queue starvation? It’s a problem that can occur when scheduling tasks
in priority queues if there are too many high priority tasks so that lower priority
tasks never get scheduled and are just waiting indefinitely. For example, let’s say
we have three queues: high, medium and low priority. Tasks in the high priority one
always get processed first. Once this queue is empty the tasks from the medium priority
queue get processed. Of course the tasks in the low priority queue get processed only
if the other two queues are empty. If there are too many high and medium priority
tasks incoming all the time so that the queues never get empty, then the low priority
tasks are not processed at all.
</p>
        <p>
And how is this related to CruiseControl.NET? As you might be aware, projects can
be assigned to different <a href="http://ccnetlive.thoughtworks.com/ccnet/doc/CCNET/Queue%20Configuration.html">queues</a>.
Only projects in the same queue (as the name implies) are built sequentially while
projects in different queues are built in parallel to one another. Queues themselves
therefore cannot cause starvation because different queues don’t depend on one another
and projects are always put at the end of its queue. This means that sooner or later
each project will be built.
</p>
        <p>
Now, queue <a href="http://confluence.public.thoughtworks.org/display/CCNET/Integration+Queues">priorities</a> enter
the stage. Each project can be given a priority defining where the project will be
put into the queue: before all of the lower priority projects already in the queue
instead of at the end. Effectively this partitions a single sequential queue into
multiple queues with different priorities as described at the beginning of the post.
We have all the necessary prerequisites for queue starvation. If too many projects
with higher priorities have to be built (typically caused by checking in code or triggering
a forced build), the projects with lower priorities will never get processed.
</p>
        <p>
What I have observed is that this can happen even if higher priority projects don’t
have to be built at all. The reason for that is in the way CruiseControl.NET is processing
the projects to determine whether there were any source code changes. This is taken
care of with an <a href="http://confluence.public.thoughtworks.org/display/CCNET/Interval+Trigger">interval
trigger</a> which puts a project in the queue, but it only gets built if a modification
exists. Nevertheless, even checking if such a modification does exists, takes some
time. In extreme cases this can be enough to cause queue starvation and this is also
what happened in my case. Lower priority projects never got built, not even during
the night and no matter how often a build was forced for them.
</p>
        <p>
Fortunately there is a solution for this problem: the seconds attribute which specifies
how often the project is put into the queue for checking if a modification exists.
By default it is set to 60 seconds. Increasing the value can solve the queue starvation
issue. Instead of simply defining the trigger:
</p>
        <pre class="brush: xml;">&lt;intervalTrigger /&gt;</pre>
        <p>
A longer period can be specified:
</p>
        <pre class="brush: xml;">&lt;intervalTrigger seconds="300" /&gt;</pre>
        <p>
Of course this has its downside: the latency before the project gets built after a
modification increases. Therefore you should use this solution with caution. Only
increase the value as much as you have to. And don’t do it at all if you can apply
any of the other solutions:
</p>
        <ul>
          <li>
Increase the performance of the build server to speed up the processing and building
of the projects.</li>
          <li>
Parallelize the build process by using more queues. Put the projects in the same queue
only if you have to.</li>
          <li>
Don’t use queue priorities if it’s not necessary. In most cases you can get by without
them.</li>
        </ul>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=6a11ed69-42b3-4380-89db-b0dac78d6447" />
      </body>
      <title>Avoiding Queue Starvation in CruiseControl.NET</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,6a11ed69-42b3-4380-89db-b0dac78d6447.aspx</guid>
      <link>http://www.damirscorner.com/AvoidingQueueStarvationInCruiseControlNET.aspx</link>
      <pubDate>Wed, 28 Jul 2010 20:05:47 GMT</pubDate>
      <description>&lt;p&gt;
Recently I’ve been solving some issues with queue starvation in CruiseControl.NET.
Since I haven’t found much information about this problem I’ve decided to round up
my findings in this blog post.
&lt;/p&gt;
&lt;p&gt;
So, what is queue starvation? It’s a problem that can occur when scheduling tasks
in priority queues if there are too many high priority tasks so that lower priority
tasks never get scheduled and are just waiting indefinitely. For example, let’s say
we have three queues: high, medium and low priority. Tasks in the high priority one
always get processed first. Once this queue is empty the tasks from the medium priority
queue get processed. Of course the tasks in the low priority queue get processed only
if the other two queues are empty. If there are too many high and medium priority
tasks incoming all the time so that the queues never get empty, then the low priority
tasks are not processed at all.
&lt;/p&gt;
&lt;p&gt;
And how is this related to CruiseControl.NET? As you might be aware, projects can
be assigned to different &lt;a href="http://ccnetlive.thoughtworks.com/ccnet/doc/CCNET/Queue%20Configuration.html"&gt;queues&lt;/a&gt;.
Only projects in the same queue (as the name implies) are built sequentially while
projects in different queues are built in parallel to one another. Queues themselves
therefore cannot cause starvation because different queues don’t depend on one another
and projects are always put at the end of its queue. This means that sooner or later
each project will be built.
&lt;/p&gt;
&lt;p&gt;
Now, queue &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Integration+Queues"&gt;priorities&lt;/a&gt; enter
the stage. Each project can be given a priority defining where the project will be
put into the queue: before all of the lower priority projects already in the queue
instead of at the end. Effectively this partitions a single sequential queue into
multiple queues with different priorities as described at the beginning of the post.
We have all the necessary prerequisites for queue starvation. If too many projects
with higher priorities have to be built (typically caused by checking in code or triggering
a forced build), the projects with lower priorities will never get processed.
&lt;/p&gt;
&lt;p&gt;
What I have observed is that this can happen even if higher priority projects don’t
have to be built at all. The reason for that is in the way CruiseControl.NET is processing
the projects to determine whether there were any source code changes. This is taken
care of with an &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Interval+Trigger"&gt;interval
trigger&lt;/a&gt; which puts a project in the queue, but it only gets built if a modification
exists. Nevertheless, even checking if such a modification does exists, takes some
time. In extreme cases this can be enough to cause queue starvation and this is also
what happened in my case. Lower priority projects never got built, not even during
the night and no matter how often a build was forced for them.
&lt;/p&gt;
&lt;p&gt;
Fortunately there is a solution for this problem: the seconds attribute which specifies
how often the project is put into the queue for checking if a modification exists.
By default it is set to 60 seconds. Increasing the value can solve the queue starvation
issue. Instead of simply defining the trigger:
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;intervalTrigger /&amp;gt;&lt;/pre&gt;
&lt;p&gt;
A longer period can be specified:
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;intervalTrigger seconds="300" /&amp;gt;&lt;/pre&gt;
&lt;p&gt;
Of course this has its downside: the latency before the project gets built after a
modification increases. Therefore you should use this solution with caution. Only
increase the value as much as you have to. And don’t do it at all if you can apply
any of the other solutions:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Increase the performance of the build server to speed up the processing and building
of the projects.&lt;/li&gt;
&lt;li&gt;
Parallelize the build process by using more queues. Put the projects in the same queue
only if you have to.&lt;/li&gt;
&lt;li&gt;
Don’t use queue priorities if it’s not necessary. In most cases you can get by without
them.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=6a11ed69-42b3-4380-89db-b0dac78d6447" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,6a11ed69-42b3-4380-89db-b0dac78d6447.aspx</comments>
      <category>Software</category>
      <category>Software/CruiseControl</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=79ac29a8-2be0-4c04-9e54-19794e92eda5</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,79ac29a8-2be0-4c04-9e54-19794e92eda5.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,79ac29a8-2be0-4c04-9e54-19794e92eda5.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=79ac29a8-2be0-4c04-9e54-19794e92eda5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A few months ago I worked on a small spare time project which included some manipulation
of binary Excel (.xls) files. This seemingly simple task soon turned out to be quite
a challenge if you want to handle it right. The post you are reading is a short summary
of my experiences. They should make your choices easier if you are about to tackle
a similar problem.
</p>
        <p>
The most obvious choice for handling .xls files is Excel automation using the <a href="http://msdn.microsoft.com/en-us/library/wss56bz7%28VS.80%29.aspx">Excel
object model</a>. As long as your application is always going to be used interactively,
you should be fine. It’s probably the best method to use in spite of a few downsides:
</p>
        <ul>
          <li>
The object model is COM based which means you’ll have to do interop if you are developing
a .NET application. Fortunately there are some <a href="http://msmvps.com/blogs/paulomorgado/archive/2010/04/19/c-4-0-com-interop-improvements.aspx">nice
improvements</a> in .NET Framework which make coping with COM in C# much easier.</li>
          <li>
Your application will have to be compiled in 32-bit in order for it to work on 64-bit
Windows. This usually isn’t a real limitation just don’t forget to switch the target
platform from Any CPU to x86 if you’re doing development on a 32-bit OS to avoid the
problem. (You’re going to notice it yourself when developing on a 64-bit OS.)</li>
          <li>
Don’t try unit testing the Excel automation code outside your IDE (e.g. on your continuous
integration server). As described below this scenario is not supported.</li>
        </ul>
        <p>
As soon as you want your code to be run non-interactively, you’re out of luck with
Excel automation. Since all Office applications assume to be running on the interactive
desktop, there are <a href="http://support.microsoft.com/kb/257757">several reasons</a> why
such usage is not supported and is even strongly discouraged by Microsoft. If you
want to run your code on a web server, as a Windows service, a scheduled task or just
automatically test it on your build server, you’ll have to find a different approach.
And in this case there are no obvious choices.
</p>
        <p>
Your best bet is to use Open XML file format (.xlsx, .xlsm) instead of the binary
one (.xls) if this is an option for you. Since this is a well documented XML based
format you can manipulate it directly without running Excel at all. You can even use <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;displaylang=en">Open
XML SDK for Microsoft Office</a> which includes strongly typed classes that simplify
many common tasks.
</p>
        <p>
This is not the case with the binary format. Microsoft doesn’t provide or support
any SDK or API for manipulating the files directly. You are only provided with <a href="http://msdn.microsoft.com/en-us/library/cc313154%28v=office.12%29.aspx">detailed
documentation</a> of the format. Based on it some third party solutions have been
developed. <a href="http://www.aspose.com/categories/.net-components/aspose.cells-for-.net/default.aspx">Aspose</a> and <a href="http://officewriter.softartisans.com/default.aspx?pageid=257">SoftArtisans</a> have
their own commercial offerings which I haven’t evaluated because as such they weren’t
suitable for me.
</p>
        <p>
On the other hand the only free library that I have found is <a href="http://sourceforge.net/projects/myxls/">MyXLS</a> and
this one leaves much to be desired. It also seems to be pretty much abandoned with
the latest release almost a year ago and only a single commit to the repository in
this year so far. That being said, it still might prove useful if you only want to
create the files, mostly focusing on the appearance with only minimal requirements
regarding formulas. According to the samples this seems to work fine. Reading existing
files is another story. You are more or less on your own as soon as you need to read
cells with formulas. This made the library useless for me therefore I used another
approach based on the fact that the OLE DB Provider for Jet can be used to read and
write data in Excel worksheets. 
</p>
        <p>
At first I haven’t even considered this possibility because I was convinced that this
method can only be used on worksheets designed as database tables (having columns
of data with or without header columns). <a href="http://www.codeproject.com/KB/office/excel_using_oledb.aspx">This
article</a> proved me wrong and in spite of many issues in the demo project it showed
off techniques which turned out really useful for me. The most important one was the
possibility to address regions, not only complete worksheets – this can be used to
retrieve and set individual cell values as well as for accessing database table-like
blocks of data in a part of the worksheet. Let’s take a look at a sample:
</p>
        <pre class="brush: sql;">SELECT F1 FROM [Sheet1$C2:C2];</pre>
        <p>
This query retrieves a value of a single cell. The same syntax can be used to access
any region: after the worksheet name with a trailing $ character the region is defined
just like in Excel formulas. If the region doesn’t include column headers (specified
by including HDR=No in the Extended Properties of the connection string) the columns
are named F# where # is the sequential number of the column in the defined region.
Similarly the following query can be used to set a value of an individual cell:
</p>
        <pre class="brush: sql;">UPDATE [Sheet1$C2:C2] SET F1 = 'Value';</pre>
        <p>
A few more things worth mentioning:
</p>
        <ul>
          <li>
Be aware of the IMEX option in the connection string. It doesn’t seem to be documented
very well, probably its best description is <a href="http://sqlblog.de/blog/2009/04/ssis-excel-import-column-data-types/">here</a>.</li>
          <li>
Make sure you keep the connection to the file open if you plan to do more data access
later. Opening the connection takes quite some time therefore the performance will
be terrible if you keep closing and reopening it.</li>
          <li>
The technique doesn’t seem to work if the worksheet name begins with a space. At least
I couldn’t make it work, no matter how I set the quotes.</li>
          <li>
I encountered a file which couldn’t be opened in this way but the problem was resolved
after I opened the file in Excel and saved it again.</li>
        </ul>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=79ac29a8-2be0-4c04-9e54-19794e92eda5" />
      </body>
      <title>Programmatic Manipulation of Binary Excel (.xls) Files</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,79ac29a8-2be0-4c04-9e54-19794e92eda5.aspx</guid>
      <link>http://www.damirscorner.com/ProgrammaticManipulationOfBinaryExcelXlsFiles.aspx</link>
      <pubDate>Sun, 13 Jun 2010 11:47:10 GMT</pubDate>
      <description>&lt;p&gt;
A few months ago I worked on a small spare time project which included some manipulation
of binary Excel (.xls) files. This seemingly simple task soon turned out to be quite
a challenge if you want to handle it right. The post you are reading is a short summary
of my experiences. They should make your choices easier if you are about to tackle
a similar problem.
&lt;/p&gt;
&lt;p&gt;
The most obvious choice for handling .xls files is Excel automation using the &lt;a href="http://msdn.microsoft.com/en-us/library/wss56bz7%28VS.80%29.aspx"&gt;Excel
object model&lt;/a&gt;. As long as your application is always going to be used interactively,
you should be fine. It’s probably the best method to use in spite of a few downsides:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The object model is COM based which means you’ll have to do interop if you are developing
a .NET application. Fortunately there are some &lt;a href="http://msmvps.com/blogs/paulomorgado/archive/2010/04/19/c-4-0-com-interop-improvements.aspx"&gt;nice
improvements&lt;/a&gt; in .NET Framework which make coping with COM in C# much easier.&lt;/li&gt;
&lt;li&gt;
Your application will have to be compiled in 32-bit in order for it to work on 64-bit
Windows. This usually isn’t a real limitation just don’t forget to switch the target
platform from Any CPU to x86 if you’re doing development on a 32-bit OS to avoid the
problem. (You’re going to notice it yourself when developing on a 64-bit OS.)&lt;/li&gt;
&lt;li&gt;
Don’t try unit testing the Excel automation code outside your IDE (e.g. on your continuous
integration server). As described below this scenario is not supported.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As soon as you want your code to be run non-interactively, you’re out of luck with
Excel automation. Since all Office applications assume to be running on the interactive
desktop, there are &lt;a href="http://support.microsoft.com/kb/257757"&gt;several reasons&lt;/a&gt; why
such usage is not supported and is even strongly discouraged by Microsoft. If you
want to run your code on a web server, as a Windows service, a scheduled task or just
automatically test it on your build server, you’ll have to find a different approach.
And in this case there are no obvious choices.
&lt;/p&gt;
&lt;p&gt;
Your best bet is to use Open XML file format (.xlsx, .xlsm) instead of the binary
one (.xls) if this is an option for you. Since this is a well documented XML based
format you can manipulate it directly without running Excel at all. You can even use &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=c6e744e5-36e9-45f5-8d8c-331df206e0d0&amp;amp;displaylang=en"&gt;Open
XML SDK for Microsoft Office&lt;/a&gt; which includes strongly typed classes that simplify
many common tasks.
&lt;/p&gt;
&lt;p&gt;
This is not the case with the binary format. Microsoft doesn’t provide or support
any SDK or API for manipulating the files directly. You are only provided with &lt;a href="http://msdn.microsoft.com/en-us/library/cc313154%28v=office.12%29.aspx"&gt;detailed
documentation&lt;/a&gt; of the format. Based on it some third party solutions have been
developed. &lt;a href="http://www.aspose.com/categories/.net-components/aspose.cells-for-.net/default.aspx"&gt;Aspose&lt;/a&gt; and &lt;a href="http://officewriter.softartisans.com/default.aspx?pageid=257"&gt;SoftArtisans&lt;/a&gt; have
their own commercial offerings which I haven’t evaluated because as such they weren’t
suitable for me.
&lt;/p&gt;
&lt;p&gt;
On the other hand the only free library that I have found is &lt;a href="http://sourceforge.net/projects/myxls/"&gt;MyXLS&lt;/a&gt; and
this one leaves much to be desired. It also seems to be pretty much abandoned with
the latest release almost a year ago and only a single commit to the repository in
this year so far. That being said, it still might prove useful if you only want to
create the files, mostly focusing on the appearance with only minimal requirements
regarding formulas. According to the samples this seems to work fine. Reading existing
files is another story. You are more or less on your own as soon as you need to read
cells with formulas. This made the library useless for me therefore I used another
approach based on the fact that the OLE DB Provider for Jet can be used to read and
write data in Excel worksheets. 
&lt;/p&gt;
&lt;p&gt;
At first I haven’t even considered this possibility because I was convinced that this
method can only be used on worksheets designed as database tables (having columns
of data with or without header columns). &lt;a href="http://www.codeproject.com/KB/office/excel_using_oledb.aspx"&gt;This
article&lt;/a&gt; proved me wrong and in spite of many issues in the demo project it showed
off techniques which turned out really useful for me. The most important one was the
possibility to address regions, not only complete worksheets – this can be used to
retrieve and set individual cell values as well as for accessing database table-like
blocks of data in a part of the worksheet. Let’s take a look at a sample:
&lt;/p&gt;
&lt;pre class="brush: sql;"&gt;SELECT F1 FROM [Sheet1$C2:C2];&lt;/pre&gt;
&lt;p&gt;
This query retrieves a value of a single cell. The same syntax can be used to access
any region: after the worksheet name with a trailing $ character the region is defined
just like in Excel formulas. If the region doesn’t include column headers (specified
by including HDR=No in the Extended Properties of the connection string) the columns
are named F# where # is the sequential number of the column in the defined region.
Similarly the following query can be used to set a value of an individual cell:
&lt;/p&gt;
&lt;pre class="brush: sql;"&gt;UPDATE [Sheet1$C2:C2] SET F1 = 'Value';&lt;/pre&gt;
&lt;p&gt;
A few more things worth mentioning:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Be aware of the IMEX option in the connection string. It doesn’t seem to be documented
very well, probably its best description is &lt;a href="http://sqlblog.de/blog/2009/04/ssis-excel-import-column-data-types/"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
Make sure you keep the connection to the file open if you plan to do more data access
later. Opening the connection takes quite some time therefore the performance will
be terrible if you keep closing and reopening it.&lt;/li&gt;
&lt;li&gt;
The technique doesn’t seem to work if the worksheet name begins with a space. At least
I couldn’t make it work, no matter how I set the quotes.&lt;/li&gt;
&lt;li&gt;
I encountered a file which couldn’t be opened in this way but the problem was resolved
after I opened the file in Excel and saved it again.&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=79ac29a8-2be0-4c04-9e54-19794e92eda5" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,79ac29a8-2be0-4c04-9e54-19794e92eda5.aspx</comments>
      <category>Development</category>
      <category>Development/.NET</category>
      <category>Software</category>
      <category>Software/Office</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://subversion.apache.org/">Subversion</a> and <a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET">CruiseControl.NET</a> can
be invaluable tools in your .NET development process. There are many resources available
to help you get started which I’ll try to gather in this post along with some of my
personal experiences.
</p>
        <p>
Let me start with the list of recommended software:
</p>
        <ul>
          <li>
            <a href="http://www.visualsvn.com/server/">VisualSVN Server</a> is the ultimate Windows
version of Subversion including a simple setup and powerful management tools. If you
are planning to install a Subversion server on Windows it should be your first choice. 
</li>
          <li>
            <a href="http://ankhsvn.open.collab.net/">AnkhSVN</a> is a Subversion Source Control
Provider (SCC) for Visual Studio. As long as you’re not using <a href="http://www.microsoft.com/express/">Express
editions of Visual Studio</a>, this is the suggested way of working with SVN directly
from Visual Studio IDE. 
</li>
          <li>
            <a href="http://tortoisesvn.net/downloads">TortoiseSVN</a> is a Windows shell extension
for working with Subversion from within Windows Explorer. When you're not working
with Visual Studio solutions this is the best choice for using SVN. 
</li>
          <li>
            <a href="http://sourceforge.net/projects/ccnet/files/CruiseControl.NET%20Releases/">CruiseControl.NET</a> is
a continuous integration server including a web dashboard and <a href="http://confluence.public.thoughtworks.org/display/CCNET/CCTray">CCTray</a> -
a system tray client application for monitoring and controlling builds.</li>
        </ul>
        <p>
If you’re not already familiar with the above mentioned products, you should consult
their documentation or search for tutorials. I will rather focus on setting up your
development and release process. If you haven’t done so already I suggest you first
read the following articles by <a href="http://ariejan.net/">Ariejan de Vroom</a>:
</p>
        <ul>
          <li>
            <a href="http://ariejan.net/2006/11/24/svn-how-to-structure-your-repository/">How
to structure your repository</a>
          </li>
          <li>
            <a href="http://ariejan.net/2006/11/21/svn-how-to-release-software-properly/">How
to release software properly</a>
          </li>
          <li>
            <a href="http://ariejan.net/2006/11/22/svn-how-to-fix-bugs-properly/">How to fix bugs
properly</a>
          </li>
        </ul>
        <p>
I mostly based my configuration on the ideas in these articles. I have projects configured
in CC.NET to build all copies of the project: trunk (ProjectName-Trunk), all branches
(ProjectName-REL-#.#) and all tags (ProjectName-v#.#.#). To identify individual builds
I am using CC.NET’s <a href="http://confluence.public.thoughtworks.org/display/CCNET/Assembly+Version+Labeller">Assembly
Version Labeller</a> together with <a href="http://msbuildtasks.tigris.org/">AssemblyInfo
MsBuild Community Task</a>.
</p>
        <p>
Assembly Version Labeller is really simple to configure. You only need to add a short
snippet to each project:
</p>
        <pre class="brush: xml;">&lt;labeller type="assemblyVersionLabeller"&gt;
    &lt;major&gt;1&lt;/major&gt;
    &lt;minor&gt;0&lt;/minor&gt;
    &lt;build&gt;0&lt;/build&gt;
&lt;/labeller&gt;</pre>
        <p>
I’m using the following versioning policy:
</p>
        <ul>
          <li>
I start each project with version 1.0.0.</li>
          <li>
Once it’s ready for release I make a copy of the trunk in the branches directory,
named REL-#.# containing the major and the minor version number. Immediately afterwards
I bump the version of the trunk (only minor or major and minor, depending on the nature
of the new features planned).</li>
          <li>
In the release branch I make the necessary changes before release (e.g. I change the
AssemblyProduct name to distinguish between development and release quality builds)
and make another copy in the tags directory, named v#.#.# containing the major, minor
and build version numbers. Immediately afterwards I increase the build version number
in the release branch.</li>
          <li>
I make no changes to the copies in the tags directory. All bug fixes go to the release
branch. Once I’m ready for a new release I repeat the previous step.</li>
        </ul>
        <p>
Since I don’t specify the revision number directly, the SVN Revision number gets used
automatically. This makes it possible to match each build to the revision of the code
in SVN.
</p>
        <p>
To put the generated assembly version in the build I am using the AssemblyInfo MsBuild
task. There are two steps involved in doing this.
</p>
        <p>
First you need to move the AssemblyProduct, AssemblyInfo and AssemblyFileVersion attributes
from the auto generated AssemblyInfo.cs file into a new file. In my case the AssemblyVersion.cs
has the following contents:
</p>
        <pre class="brush: csharp;">using System.Reflection;

[assembly: AssemblyProduct("ProjectName DEV")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]</pre>
        <p>
Next you have to modify your project file (*.csproj) by importing the community tasks
and adding a call to the AssemblyInfo MsBuild task:
</p>
        <pre class="brush: xml;">&lt;Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" /&gt;
&lt;Target Name="BeforeBuild"&gt;
    &lt;AssemblyInfo Condition="'$(CCNetLabel)' != ''"
        CodeLanguage="CS" 
        OutputFile="Properties\AssemblyVersion.cs" 
        AssemblyProduct="ProjectName TRUNK" 
        AssemblyVersion="$(CCNetLabel)" 
        AssemblyFileVersion="$(CCNetLabel)" /&gt;
&lt;/Target&gt;</pre>
        <p>
If you have never edited a project file before, you might want to read these first:
</p>
        <ul>
          <li>
            <a href="http://msdn.microsoft.com/en-us/library/ms171487%28VS.80%29.aspx">How to:
Edit Project Files</a>
          </li>
          <li>
            <a href="http://msdn.microsoft.com/en-us/library/ms366724%28VS.80%29.aspx">How to:
Extend the Visual Studio Build Process</a>
          </li>
        </ul>
        <p>
One more thing to note which might not be all that obvious. The Condition in the AssemblyInfo
task is met only when building from CC.NET. For builds in Visual Studio the task doesn’t
regenerate the AssemblyVersion.cs file therefore the revision number is always 0 and
the AssemblyProduct has a DEV suffix as defined in the original file. Also I remove
the TRUNK suffix from the AssemblyProduct attribute of the AssemblyInfo task when
moving code from trunk to release branches to separate between the two.
</p>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c" />
      </body>
      <title>Setting Up SVN and CC.NET for .NET Development</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c.aspx</guid>
      <link>http://www.damirscorner.com/SettingUpSVNAndCCNETForNETDevelopment.aspx</link>
      <pubDate>Sun, 30 May 2010 10:45:16 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://subversion.apache.org/"&gt;Subversion&lt;/a&gt; and &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl.NET&lt;/a&gt; can
be invaluable tools in your .NET development process. There are many resources available
to help you get started which I’ll try to gather in this post along with some of my
personal experiences.
&lt;/p&gt;
&lt;p&gt;
Let me start with the list of recommended software:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.visualsvn.com/server/"&gt;VisualSVN Server&lt;/a&gt; is the ultimate Windows
version of Subversion including a simple setup and powerful management tools. If you
are planning to install a Subversion server on Windows it should be your first choice. 
&lt;li&gt;
&lt;a href="http://ankhsvn.open.collab.net/"&gt;AnkhSVN&lt;/a&gt; is a Subversion Source Control
Provider (SCC) for Visual Studio. As long as you’re not using &lt;a href="http://www.microsoft.com/express/"&gt;Express
editions of Visual Studio&lt;/a&gt;, this is the suggested way of working with SVN directly
from Visual Studio IDE. 
&lt;li&gt;
&lt;a href="http://tortoisesvn.net/downloads"&gt;TortoiseSVN&lt;/a&gt; is a Windows shell extension
for working with Subversion from within Windows Explorer. When you're not working
with Visual Studio solutions this is the best choice for using SVN. 
&lt;li&gt;
&lt;a href="http://sourceforge.net/projects/ccnet/files/CruiseControl.NET%20Releases/"&gt;CruiseControl.NET&lt;/a&gt; is
a continuous integration server including a web dashboard and &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/CCTray"&gt;CCTray&lt;/a&gt; -
a system tray client application for monitoring and controlling builds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
If you’re not already familiar with the above mentioned products, you should consult
their documentation or search for tutorials. I will rather focus on setting up your
development and release process. If you haven’t done so already I suggest you first
read the following articles by &lt;a href="http://ariejan.net/"&gt;Ariejan de Vroom&lt;/a&gt;:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://ariejan.net/2006/11/24/svn-how-to-structure-your-repository/"&gt;How
to structure your repository&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://ariejan.net/2006/11/21/svn-how-to-release-software-properly/"&gt;How
to release software properly&lt;/a&gt; 
&lt;li&gt;
&lt;a href="http://ariejan.net/2006/11/22/svn-how-to-fix-bugs-properly/"&gt;How to fix bugs
properly&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I mostly based my configuration on the ideas in these articles. I have projects configured
in CC.NET to build all copies of the project: trunk (ProjectName-Trunk), all branches
(ProjectName-REL-#.#) and all tags (ProjectName-v#.#.#). To identify individual builds
I am using CC.NET’s &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Assembly+Version+Labeller"&gt;Assembly
Version Labeller&lt;/a&gt; together with &lt;a href="http://msbuildtasks.tigris.org/"&gt;AssemblyInfo
MsBuild Community Task&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Assembly Version Labeller is really simple to configure. You only need to add a short
snippet to each project:
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;labeller type="assemblyVersionLabeller"&amp;gt;
    &amp;lt;major&amp;gt;1&amp;lt;/major&amp;gt;
    &amp;lt;minor&amp;gt;0&amp;lt;/minor&amp;gt;
    &amp;lt;build&amp;gt;0&amp;lt;/build&amp;gt;
&amp;lt;/labeller&amp;gt;&lt;/pre&gt;
&lt;p&gt;
I’m using the following versioning policy:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I start each project with version 1.0.0.&lt;/li&gt;
&lt;li&gt;
Once it’s ready for release I make a copy of the trunk in the branches directory,
named REL-#.# containing the major and the minor version number. Immediately afterwards
I bump the version of the trunk (only minor or major and minor, depending on the nature
of the new features planned).&lt;/li&gt;
&lt;li&gt;
In the release branch I make the necessary changes before release (e.g. I change the
AssemblyProduct name to distinguish between development and release quality builds)
and make another copy in the tags directory, named v#.#.# containing the major, minor
and build version numbers. Immediately afterwards I increase the build version number
in the release branch.&lt;/li&gt;
&lt;li&gt;
I make no changes to the copies in the tags directory. All bug fixes go to the release
branch. Once I’m ready for a new release I repeat the previous step.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Since I don’t specify the revision number directly, the SVN Revision number gets used
automatically. This makes it possible to match each build to the revision of the code
in SVN.
&lt;/p&gt;
&lt;p&gt;
To put the generated assembly version in the build I am using the AssemblyInfo MsBuild
task. There are two steps involved in doing this.
&lt;/p&gt;
&lt;p&gt;
First you need to move the AssemblyProduct, AssemblyInfo and AssemblyFileVersion attributes
from the auto generated AssemblyInfo.cs file into a new file. In my case the AssemblyVersion.cs
has the following contents:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;using System.Reflection;

[assembly: AssemblyProduct("ProjectName DEV")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]&lt;/pre&gt;
&lt;p&gt;
Next you have to modify your project file (*.csproj) by importing the community tasks
and adding a call to the AssemblyInfo MsBuild task:
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" /&amp;gt;
&amp;lt;Target Name="BeforeBuild"&amp;gt;
    &amp;lt;AssemblyInfo Condition="'$(CCNetLabel)' != ''"
        CodeLanguage="CS" 
        OutputFile="Properties\AssemblyVersion.cs" 
        AssemblyProduct="ProjectName TRUNK" 
        AssemblyVersion="$(CCNetLabel)" 
        AssemblyFileVersion="$(CCNetLabel)" /&amp;gt;
&amp;lt;/Target&amp;gt;&lt;/pre&gt;
&lt;p&gt;
If you have never edited a project file before, you might want to read these first:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ms171487%28VS.80%29.aspx"&gt;How to:
Edit Project Files&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ms366724%28VS.80%29.aspx"&gt;How to:
Extend the Visual Studio Build Process&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
One more thing to note which might not be all that obvious. The Condition in the AssemblyInfo
task is met only when building from CC.NET. For builds in Visual Studio the task doesn’t
regenerate the AssemblyVersion.cs file therefore the revision number is always 0 and
the AssemblyProduct has a DEV suffix as defined in the original file. Also I remove
the TRUNK suffix from the AssemblyProduct attribute of the AssemblyInfo task when
moving code from trunk to release branches to separate between the two.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,e4f8f3a6-b787-4ce2-b7c6-31fdbc67580c.aspx</comments>
      <category>Development</category>
      <category>Development/.NET</category>
      <category>Software</category>
      <category>Software/CruiseControl</category>
      <category>Software/VisualStudio</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=c2921994-0b38-4e21-84c7-a957f35d162a</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,c2921994-0b38-4e21-84c7-a957f35d162a.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,c2921994-0b38-4e21-84c7-a957f35d162a.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=c2921994-0b38-4e21-84c7-a957f35d162a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Query parameters are a very useful <a href="http://office.microsoft.com/en-us/excel/HP051995481033.aspx">Excel
feature</a> allowing parameterization of database queries used to import data in Excel.
They are really simple to use as well. On the Definition tab of the Connection Properties
dialog there is a Parameters… button at the bottom. It gets enabled as soon as there
is a parameter defined in the Command text – you define it by typing in a question
mark (?) instead of a value in the WHERE clause of the query, as seen in the image
below.
</p>
        <p>
 <img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Connection Propertie dialog" border="0" alt="Connection Propertie dialog" src="http://www.damirscorner.com/content/binary/WindowsLiveWriter/Excel2007QueryParameters_77B4/image_17.png" width="407" height="462" /></p>
        <p>
Unfortunately there is a limitation for using this functionality which turns out pretty
unintuitive in Excel 2007. It is only supported for Microsoft Query based queries.
For all other types of queries available in Excel you get the error “No value given
for one or more parameters.” when you add a parameter to the Command text. Since the
error doesn’t even hint at the real cause of the problem it took me some time before
I figured it out. The thing to remember is: If you want to use query parameters, you
must select Microsoft Query as the external data source when importing the data for
the first time. This can’t be changed at a later time.
</p>
        <p>
          <img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Get External Data From Microsof Query" border="0" alt="Get External Data From Microsof Query" src="http://www.damirscorner.com/content/binary/WindowsLiveWriter/Excel2007QueryParameters_77B4/image_20.png" width="320" height="282" />
        </p>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=c2921994-0b38-4e21-84c7-a957f35d162a" />
      </body>
      <title>Excel 2007 Query Parameters</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,c2921994-0b38-4e21-84c7-a957f35d162a.aspx</guid>
      <link>http://www.damirscorner.com/Excel2007QueryParameters.aspx</link>
      <pubDate>Wed, 28 Apr 2010 18:01:23 GMT</pubDate>
      <description>&lt;p&gt;
Query parameters are a very useful &lt;a href="http://office.microsoft.com/en-us/excel/HP051995481033.aspx"&gt;Excel
feature&lt;/a&gt; allowing parameterization of database queries used to import data in Excel.
They are really simple to use as well. On the Definition tab of the Connection Properties
dialog there is a Parameters… button at the bottom. It gets enabled as soon as there
is a parameter defined in the Command text – you define it by typing in a question
mark (?) instead of a value in the WHERE clause of the query, as seen in the image
below.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Connection Propertie dialog" border="0" alt="Connection Propertie dialog" src="http://www.damirscorner.com/content/binary/WindowsLiveWriter/Excel2007QueryParameters_77B4/image_17.png" width="407" height="462"&gt;
&lt;/p&gt;
&lt;p&gt;
Unfortunately there is a limitation for using this functionality which turns out pretty
unintuitive in Excel 2007. It is only supported for Microsoft Query based queries.
For all other types of queries available in Excel you get the error “No value given
for one or more parameters.” when you add a parameter to the Command text. Since the
error doesn’t even hint at the real cause of the problem it took me some time before
I figured it out. The thing to remember is: If you want to use query parameters, you
must select Microsoft Query as the external data source when importing the data for
the first time. This can’t be changed at a later time.
&lt;/p&gt;
&lt;p&gt;
&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Get External Data From Microsof Query" border="0" alt="Get External Data From Microsof Query" src="http://www.damirscorner.com/content/binary/WindowsLiveWriter/Excel2007QueryParameters_77B4/image_20.png" width="320" height="282"&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=c2921994-0b38-4e21-84c7-a957f35d162a" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,c2921994-0b38-4e21-84c7-a957f35d162a.aspx</comments>
      <category>Software</category>
      <category>Software/Office</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=21209566-9f7f-4939-ace5-d224080bb8b1</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,21209566-9f7f-4939-ace5-d224080bb8b1.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,21209566-9f7f-4939-ace5-d224080bb8b1.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=21209566-9f7f-4939-ace5-d224080bb8b1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Microsoft Exchange supports Send As and Send On Behalf Of permissions to be granted
to users for individual e-mail addresses. Sending e-mail from Outlook for these users
is very simple – they just enter the desired address in the From field of a new message
(toggled with the Show From command on the Options ribbon) and if they have the required
permission it will be sent accordingly – either as if it was actually sent from that
address or as sent by the user on behalf of the address in the From field.
</p>
        <p>
If you want to achieve this from code there is a little more work involved. First
of all the user must be authenticated on the server using one of the methods below:
</p>
        <p>
          <font face="Courier New">SmtpClient smtp = new SmtpClient("smtp.domain.com");</font>
        </p>
        <p>
          <font face="Courier New">// use user’s existing credentials<br />
smtp.UseDefaultCredentials = true;</font>
        </p>
        <p>
          <font face="Courier New">// pass username and password<br />
smtp.Credentials = new NetworkCredentials("username", "password");</font>
        </p>
        <p>
The next step is to set up the correct headers in the message otherwise the server
will return error code 5.7.1 describing the permission the user does not have.
</p>
        <p>
To send the e-mail as only the From property has to contain the desired address:
</p>
        <p>
          <font face="Courier New">MailMessage mail = new MailMessage();<br />
mail.From = new MailAddress("send.as@domain.com");</font>
        </p>
        <p>
To send the e-mail on behalf of another user the Sender property must additionally
contain the user’s e-mail address:
</p>
        <p>
          <font face="Courier New">MailMessage mail = new MailMessage();<br />
mail.From = new MailAddress("send.as@domain.com");<br />
mail.Sender = new MailAddress("user.address@domain.com");</font>
        </p>
        <p>
On a related note, the required permissions can be granted using PowerShell.
</p>
        <p>
To grant the Send As permission:
</p>
        <p>
          <font face="Courier New">Add-ADPermission –Identity "user1" –User "user2" –ExtendedRights
Send-As</font>
        </p>
        <p>
To grant the Send On Behalf Of permission:
</p>
        <p>
          <font face="Courier New">Set-Mailbox "user1" -GrantSendOnBehalfTo "user2"</font>
        </p>
        <p>
In both cases the user1 specifies the mailbox to grant the permission for and the
user2 specifies the user to grant the permission to.
</p>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=21209566-9f7f-4939-ace5-d224080bb8b1" />
      </body>
      <title>Send E-Mail As and On Behalf Of</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,21209566-9f7f-4939-ace5-d224080bb8b1.aspx</guid>
      <link>http://www.damirscorner.com/SendEMailAsAndOnBehalfOf.aspx</link>
      <pubDate>Sun, 09 Aug 2009 17:39:38 GMT</pubDate>
      <description>&lt;p&gt;
Microsoft Exchange supports Send As and Send On Behalf Of permissions to be granted
to users for individual e-mail addresses. Sending e-mail from Outlook for these users
is very simple – they just enter the desired address in the From field of a new message
(toggled with the Show From command on the Options ribbon) and if they have the required
permission it will be sent accordingly – either as if it was actually sent from that
address or as sent by the user on behalf of the address in the From field.
&lt;/p&gt;
&lt;p&gt;
If you want to achieve this from code there is a little more work involved. First
of all the user must be authenticated on the server using one of the methods below:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;SmtpClient smtp = new SmtpClient("smtp.domain.com");&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;// use user’s existing credentials&lt;br&gt;
smtp.UseDefaultCredentials = true;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;// pass username and password&lt;br&gt;
smtp.Credentials = new NetworkCredentials("username", "password");&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
The next step is to set up the correct headers in the message otherwise the server
will return error code 5.7.1 describing the permission the user does not have.
&lt;/p&gt;
&lt;p&gt;
To send the e-mail as only the From property has to contain the desired address:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;MailMessage mail = new MailMessage();&lt;br&gt;
mail.From = new MailAddress("send.as@domain.com");&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
To send the e-mail on behalf of another user the Sender property must additionally
contain the user’s e-mail address:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;MailMessage mail = new MailMessage();&lt;br&gt;
mail.From = new MailAddress("send.as@domain.com");&lt;br&gt;
mail.Sender = new MailAddress("user.address@domain.com");&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
On a related note, the required permissions can be granted using PowerShell.
&lt;/p&gt;
&lt;p&gt;
To grant the Send As permission:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;Add-ADPermission –Identity "user1" –User "user2" –ExtendedRights
Send-As&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
To grant the Send On Behalf Of permission:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;Set-Mailbox "user1" -GrantSendOnBehalfTo "user2"&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
In both cases the user1 specifies the mailbox to grant the permission for and the
user2 specifies the user to grant the permission to.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=21209566-9f7f-4939-ace5-d224080bb8b1" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,21209566-9f7f-4939-ace5-d224080bb8b1.aspx</comments>
      <category>Development</category>
      <category>Development/.NET</category>
      <category>Software</category>
      <category>Software/Exchange</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=0db675f9-82f2-4907-933d-9dccc5f07115</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,0db675f9-82f2-4907-933d-9dccc5f07115.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,0db675f9-82f2-4907-933d-9dccc5f07115.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=0db675f9-82f2-4907-933d-9dccc5f07115</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today I decided to get to the bottom of the missing driver issue on my computer running
Windows 7 RC. It shows up as PCI Simple Communications controller and it really bugged
me since I don't have a modem or a similar device on the motherboard.
</p>
        <p>
          <img style="border: 0px none; display: block; float: none; margin-left: auto; margin-right: auto;" title="PCI Simple Communications Controller" alt="PCI Simple Communications Controller" src="http://www.damirscorner.com/content/binary/IdentifyingunrecognizeddevicesinDeviceMa_F2FE/PCISimpleCommunicationsController.png" border="0" height="36" width="268" />It
turned out that there is a away to identify such a device from the information available
in Device Manager. The first step is to open the Properties window for this device
and move to the Details tab. After selecting the Hardware Ids in the Property dropdown
the device identifiers are displayed.
</p>
        <p>
          <img style="border: 0px none; display: block; float: none; margin-left: auto; margin-right: auto;" title="HardwareIds" alt="HardwareIds" src="http://www.damirscorner.com/content/binary/IdentifyingunrecognizeddevicesinDeviceMa_F2FE/HardwareIds.png" border="0" height="461" width="414" />
        </p>
        <p>
The important ones are the numbers written after the VEN and DEV keywords. The first
one is the Vendor ID and the second one is the Device ID. So in my case the Vendor
ID is 8086 (from VEN_8086) and the Device ID is 29A4 (from DEV_29A4).
</p>
        <p>
All that's left to do know is to go to <a href="http://www.pcidatabase.com" target="_blank">PCIDatabase.com</a> and
enter the ids into the corresponding search boxes. In my case it turned out that it
was a device from Intel - Intel Management Engine Interface (HECI). Unfortunately
it doesn't have <a href="http://downloadcenter.intel.com/filter_results.aspx?strTypes=all&amp;ProductID=2374&amp;OSFullName=Windows+7%2C+64-bit*&amp;lang=eng&amp;strOSs=190&amp;submit=Go%21" target="_blank">a
driver for Windows 7</a> yet and <a href="http://downloadcenter.intel.com/filter_results.aspx?strTypes=all&amp;ProductID=2374&amp;OSFullName=Windows+Vista+64*&amp;lang=eng&amp;strOSs=150&amp;submit=Go%21" target="_blank">the
Vista one</a> doesn't install. But hey, at least I know which driver is missing.
</p>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=0db675f9-82f2-4907-933d-9dccc5f07115" />
      </body>
      <title>Identifying unrecognized devices in Device Manager</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,0db675f9-82f2-4907-933d-9dccc5f07115.aspx</guid>
      <link>http://www.damirscorner.com/IdentifyingUnrecognizedDevicesInDeviceManager.aspx</link>
      <pubDate>Sat, 01 Aug 2009 17:09:49 GMT</pubDate>
      <description>&lt;p&gt;
Today I decided to get to the bottom of the missing driver issue on my computer running
Windows 7 RC. It shows up as PCI Simple Communications controller and it really bugged
me since I don't have a modem or a similar device on the motherboard.
&lt;/p&gt;
&lt;p&gt;
&lt;img style="border: 0px none; display: block; float: none; margin-left: auto; margin-right: auto;" title="PCI Simple Communications Controller" alt="PCI Simple Communications Controller" src="http://www.damirscorner.com/content/binary/IdentifyingunrecognizeddevicesinDeviceMa_F2FE/PCISimpleCommunicationsController.png" border="0" height="36" width="268"&gt;It
turned out that there is a away to identify such a device from the information available
in Device Manager. The first step is to open the Properties window for this device
and move to the Details tab. After selecting the Hardware Ids in the Property dropdown
the device identifiers are displayed.
&lt;/p&gt;
&lt;p&gt;
&lt;img style="border: 0px none; display: block; float: none; margin-left: auto; margin-right: auto;" title="HardwareIds" alt="HardwareIds" src="http://www.damirscorner.com/content/binary/IdentifyingunrecognizeddevicesinDeviceMa_F2FE/HardwareIds.png" border="0" height="461" width="414"&gt; 
&lt;/p&gt;
&lt;p&gt;
The important ones are the numbers written after the VEN and DEV keywords. The first
one is the Vendor ID and the second one is the Device ID. So in my case the Vendor
ID is 8086 (from VEN_8086) and the Device ID is 29A4 (from DEV_29A4).
&lt;/p&gt;
&lt;p&gt;
All that's left to do know is to go to &lt;a href="http://www.pcidatabase.com" target="_blank"&gt;PCIDatabase.com&lt;/a&gt; and
enter the ids into the corresponding search boxes. In my case it turned out that it
was a device from Intel - Intel Management Engine Interface (HECI). Unfortunately
it doesn't have &lt;a href="http://downloadcenter.intel.com/filter_results.aspx?strTypes=all&amp;amp;ProductID=2374&amp;amp;OSFullName=Windows+7%2C+64-bit*&amp;amp;lang=eng&amp;amp;strOSs=190&amp;amp;submit=Go%21" target="_blank"&gt;a
driver for Windows 7&lt;/a&gt; yet and &lt;a href="http://downloadcenter.intel.com/filter_results.aspx?strTypes=all&amp;amp;ProductID=2374&amp;amp;OSFullName=Windows+Vista+64*&amp;amp;lang=eng&amp;amp;strOSs=150&amp;amp;submit=Go%21" target="_blank"&gt;the
Vista one&lt;/a&gt; doesn't install. But hey, at least I know which driver is missing.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=0db675f9-82f2-4907-933d-9dccc5f07115" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,0db675f9-82f2-4907-933d-9dccc5f07115.aspx</comments>
      <category>Software</category>
      <category>Software/Windows</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=de988151-8abf-4eef-bdc2-1126b05812b1</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,de988151-8abf-4eef-bdc2-1126b05812b1.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,de988151-8abf-4eef-bdc2-1126b05812b1.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=de988151-8abf-4eef-bdc2-1126b05812b1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today I've taken my new <a href="http://buy.garmin.com/shop/shop.do?pID=8703">handeld
GPS device</a> for a test run. It did its job pretty well but the real challenge started
afterwards when I tried geotagging the photos I've taken. I decided to use <a href="http://www.microsoft.com/prophoto/downloads/tools.aspx">Microsoft
Pro Photo Tools</a> which have just been released with geotagging as its main feature.
Downloading the track data from the GPS device with Garmin MapSource software was
quick and simple. But the problems started soon afterwards. MapSource can only export
track data in its proprietary format GDB which can't be used in Microsoft Pro Photo
Tools.
</p>
        <p>
          <a href="http://www.gpsbabel.org/">GPSBabel</a> came to the rescue. This free tool
can probably convert files between any two existing GPS formats, at least judging
from its <a href="http://www.gpsbabel.org/capabilities.html">list of supported formats</a>.
I used it to convert my data to the GPX XML format only to find out that Microsoft
Pro Photo Tools have problems with it. Converting to NMEA or KML instead didn't help
either. Fortunately the latter returned a strange error (Degrees must be between 0
and 90, found degree 46298501) which put me on the right track. Of course there was
no such value in the KML file so I correctly deduced that the decimal separator was
to blame.
</p>
        <p>
The value in the file was 46.298501 but the Slovenian regional settings have comma
as the decimal separator therefore the value was misinterpreted. Temporarily changing
the decimal separator to dot solved the problem - the track was successfully imported
immediately afterwards. This issue won't keep me from using this otherwise very useful
tool with a really nice feature set. It could even fix the mismatching time settings
between my GPS unit and the camera with a single setting. I just hope they address
this bug soon so that I won't have to change my regional settings every time I use
the program.
</p>
        <p>
The only thing I still have to figure out is why the geotags somehow lost resolution
when I uploaded the photos from <a href="http://picasa.google.com/">Picasa</a> to <a href="http://picasaweb.google.com/">Picasa
Web Albums</a>. I just fixed them manually and decided to address the issue next time.
Any tips are welcome.
</p>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=de988151-8abf-4eef-bdc2-1126b05812b1" />
      </body>
      <title>Microsoft Pro Photo Tools decimal separator problem</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,de988151-8abf-4eef-bdc2-1126b05812b1.aspx</guid>
      <link>http://www.damirscorner.com/MicrosoftProPhotoToolsDecimalSeparatorProblem.aspx</link>
      <pubDate>Sun, 15 Jun 2008 20:03:01 GMT</pubDate>
      <description>&lt;p&gt;
Today I've taken my new &lt;a href="http://buy.garmin.com/shop/shop.do?pID=8703"&gt;handeld
GPS device&lt;/a&gt; for a test run. It did its job pretty well but the real challenge started
afterwards when I tried geotagging the photos I've taken. I decided to use &lt;a href="http://www.microsoft.com/prophoto/downloads/tools.aspx"&gt;Microsoft
Pro Photo Tools&lt;/a&gt; which have just been released with geotagging as its main feature.
Downloading the track data from the GPS device with Garmin MapSource software was
quick and simple. But the problems started soon afterwards. MapSource can only export
track data in its proprietary format GDB which can't be used in Microsoft Pro Photo
Tools.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.gpsbabel.org/"&gt;GPSBabel&lt;/a&gt; came to the rescue. This free tool
can probably convert files between any two existing GPS formats, at least judging
from its &lt;a href="http://www.gpsbabel.org/capabilities.html"&gt;list of supported formats&lt;/a&gt;.
I used it to convert my data to the GPX XML format only to find out that Microsoft
Pro Photo Tools have problems with it. Converting to NMEA or KML instead didn't help
either. Fortunately the latter returned a strange error (Degrees must be between 0
and 90, found degree 46298501) which put me on the right track. Of course there was
no such value in the KML file so I correctly deduced that the decimal separator was
to blame.
&lt;/p&gt;
&lt;p&gt;
The value in the file was 46.298501 but the Slovenian regional settings have comma
as the decimal separator therefore the value was misinterpreted. Temporarily changing
the decimal separator to dot solved the problem - the track was successfully imported
immediately afterwards. This issue won't keep me from using this otherwise very useful
tool with a really nice feature set. It could even fix the mismatching time settings
between my GPS unit and the camera with a single setting. I just hope they address
this bug soon so that I won't have to change my regional settings every time I use
the program.
&lt;/p&gt;
&lt;p&gt;
The only thing I still have to figure out is why the geotags somehow lost resolution
when I uploaded the photos from &lt;a href="http://picasa.google.com/"&gt;Picasa&lt;/a&gt; to &lt;a href="http://picasaweb.google.com/"&gt;Picasa
Web Albums&lt;/a&gt;. I just fixed them manually and decided to address the issue next time.
Any tips are welcome.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=de988151-8abf-4eef-bdc2-1126b05812b1" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,de988151-8abf-4eef-bdc2-1126b05812b1.aspx</comments>
      <category>Software</category>
      <category>Software/Imaging</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=fcd08df4-c6f8-4a1f-ae1f-c5ed70431510</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,fcd08df4-c6f8-4a1f-ae1f-c5ed70431510.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,fcd08df4-c6f8-4a1f-ae1f-c5ed70431510.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=fcd08df4-c6f8-4a1f-ae1f-c5ed70431510</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The Xbox 360 Dashboard update released on 4th December 2007 added support for playing
DivX and XviD videos natively, i.e. without installing <a href="http://www.runtime360.com/projects/transcode-360/">Transcode
360</a> for Windows Media Center. Unfortunatelly this only works for media played
directly from the dashboard and not within Media Center Extender. Since I didn't want
to copy my videos to CDs, DVDs or other external devices, the only thing left to do
was to setup Windows Media Player media sharing which I never had to use before.
</p>
        <p>
This turned out to be more difficult than I expected - the reason being that the media
I wanted to share wasn't stored locally but on a separate file server. By default
such media is not shared and there are few steps one has to follow to make this work,
as thoroughly explained <a href="http://www.microsoft.com/windows/windowsmedia/player/faq/sharing.mspx#q20_17">here</a>:
</p>
        <ul>
          <li>
Enable remote content sharing by adding the following entry into the registry:<br /><font face="Courier New">[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MediaPlayer\Preferences\HME]<br />
"EnableRemoteContentSharing"=dword:00000001</font></li>
          <li>
Grant anonymous users access to the shared folders on the file server by adding the
read permission on the folder and on the share to the <font face="Courier New">ANONYMOUS
LOGON</font> user 
</li>
          <li>
Modify the file server's group policy to allow anonymous access to the selected shares
by listing them in the <font face="Courier New">Network access: Shares that can be
accessed anonymously</font> policy in the <font face="Courier New">Computer Configuration,
Windows Settings, Security Settings, Local Policies, Security Options</font> branch
of the group policy tree (just run <font face="Courier New">gpedit.msc</font> to start
the Group Policy Object Editor)</li>
        </ul>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=fcd08df4-c6f8-4a1f-ae1f-c5ed70431510" />
      </body>
      <title>Playing DivX and XviD videos natively on Xbox 360</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,fcd08df4-c6f8-4a1f-ae1f-c5ed70431510.aspx</guid>
      <link>http://www.damirscorner.com/PlayingDivXAndXviDVideosNativelyOnXbox360.aspx</link>
      <pubDate>Mon, 31 Dec 2007 11:34:14 GMT</pubDate>
      <description>&lt;p&gt;
The Xbox 360 Dashboard update released on 4th December 2007 added support for playing
DivX and XviD videos natively, i.e. without installing &lt;a href="http://www.runtime360.com/projects/transcode-360/"&gt;Transcode
360&lt;/a&gt; for Windows Media Center. Unfortunatelly this only works for media played
directly from the dashboard and not within Media Center Extender. Since I didn't want
to copy my videos to CDs, DVDs or other external devices, the only thing left to do
was to setup Windows Media Player media sharing which I never had to use before.
&lt;/p&gt;
&lt;p&gt;
This turned out to be more difficult than I expected - the reason being that the media
I wanted to share wasn't stored locally but on a separate file server. By default
such media is not shared and there are few steps one has to follow to make this work,
as thoroughly explained &lt;a href="http://www.microsoft.com/windows/windowsmedia/player/faq/sharing.mspx#q20_17"&gt;here&lt;/a&gt;:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Enable remote content sharing by adding the following entry into the registry:&lt;br&gt;
&lt;font face="Courier New"&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MediaPlayer\Preferences\HME]&lt;br&gt;
"EnableRemoteContentSharing"=dword:00000001&lt;/font&gt; 
&lt;/li&gt;
&lt;li&gt;
Grant anonymous users access to the shared folders on the file server by adding the
read permission on the folder and on the share to the &lt;font face="Courier New"&gt;ANONYMOUS
LOGON&lt;/font&gt; user 
&lt;/li&gt;
&lt;li&gt;
Modify the file server's group policy to allow anonymous access to the selected shares
by listing them in the &lt;font face="Courier New"&gt;Network access: Shares that can be
accessed anonymously&lt;/font&gt; policy in the &lt;font face="Courier New"&gt;Computer Configuration,
Windows Settings, Security Settings, Local Policies, Security Options&lt;/font&gt; branch
of the group policy tree (just run &lt;font face="Courier New"&gt;gpedit.msc&lt;/font&gt; to start
the Group Policy Object Editor)&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=fcd08df4-c6f8-4a1f-ae1f-c5ed70431510" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,fcd08df4-c6f8-4a1f-ae1f-c5ed70431510.aspx</comments>
      <category>Gadgets</category>
      <category>Gadgets/Xbox</category>
      <category>Software</category>
      <category>Software/Windows</category>
    </item>
    <item>
      <trackback:ping>http://www.damirscorner.com/Trackback.aspx?guid=90fc52c2-c73a-4709-900b-6f96fb4c9f1e</trackback:ping>
      <pingback:server>http://www.damirscorner.com/pingback.aspx</pingback:server>
      <pingback:target>http://www.damirscorner.com/PermaLink,guid,90fc52c2-c73a-4709-900b-6f96fb4c9f1e.aspx</pingback:target>
      <dc:creator>Damir Arh</dc:creator>
      <wfw:comment>http://www.damirscorner.com/CommentView,guid,90fc52c2-c73a-4709-900b-6f96fb4c9f1e.aspx</wfw:comment>
      <wfw:commentRss>http://www.damirscorner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=90fc52c2-c73a-4709-900b-6f96fb4c9f1e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Not so long ago I've been called to my boss's office to prevent him losing unsaved
work in a PowerPoint presentation. It turned out that when he tried to save the file
to a new location the message box with the overwrite warning for some reason didn't
render completely and it was impossible to close it. As it turned out at the end I
could have just killed the application and restart it, since the AutoRecover feature
kicked in and offered a version of the file with all changes applied.
</p>
        <p>
But just to be on the save side I wanted to copy the AutoRecover files to a save location
before actually killing the application. But unlike Word or Excel where the location
of these files is set in the options, PowerPoint does not have such an option. After
some googling I finally stumbled across <a href="http://office.microsoft.com/en-us/help/HA101578851033.aspx">a
page</a>, correctly stating that the files are stored in the %temp% folder and named
ppt*.tmp. I decided to publish this info here just in case I need it again.
</p>
        <img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=90fc52c2-c73a-4709-900b-6f96fb4c9f1e" />
      </body>
      <title>Location of PowerPoint AutoRecover files</title>
      <guid isPermaLink="false">http://www.damirscorner.com/PermaLink,guid,90fc52c2-c73a-4709-900b-6f96fb4c9f1e.aspx</guid>
      <link>http://www.damirscorner.com/LocationOfPowerPointAutoRecoverFiles.aspx</link>
      <pubDate>Sat, 24 Nov 2007 14:11:03 GMT</pubDate>
      <description>&lt;p&gt;
Not so long ago I've been called to my boss's office to prevent him losing unsaved
work in a PowerPoint presentation. It turned out that when he tried to save the file
to a new location the message box with the overwrite warning for some reason didn't
render completely and it was impossible to close it. As it turned out at the end I
could have just killed the application and restart it, since the AutoRecover feature
kicked in and offered a version of the file with all changes applied.
&lt;/p&gt;
&lt;p&gt;
But just to be on the save side I wanted to copy the AutoRecover files to a save location
before actually killing the application. But unlike Word or Excel where the location
of these files is set in the options, PowerPoint does not have such an option. After
some googling I finally stumbled across &lt;a href="http://office.microsoft.com/en-us/help/HA101578851033.aspx"&gt;a
page&lt;/a&gt;, correctly stating that the files are stored in the %temp% folder and named
ppt*.tmp. I decided to publish this info here just in case I need it again.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.damirscorner.com/aggbug.ashx?id=90fc52c2-c73a-4709-900b-6f96fb4c9f1e" /&gt;</description>
      <comments>http://www.damirscorner.com/CommentView,guid,90fc52c2-c73a-4709-900b-6f96fb4c9f1e.aspx</comments>
      <category>Software</category>
      <category>Software/Office</category>
    </item>
  </channel>
</rss>