<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4143403277186065643</id><updated>2011-07-08T10:02:56.605+02:00</updated><category term='versioning'/><category term='Software Factories'/><category term='ETL'/><category term='Oslo'/><category term='DSL'/><category term='WiX'/><category term='howto'/><category term='development'/><category term='ASP .NET'/><category term='requirements'/><category term='scripts'/><category term='x64'/><category term='.NET'/><category term='oracle'/><category term='database'/><title type='text'>Mac in Soft</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-6196734150093085670</id><published>2009-09-18T11:38:00.002+02:00</published><updated>2009-09-18T11:41:24.463+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>Beware the Image object !</title><content type='html'>&lt;p&gt;One requirement on the project I am working on (.NET 2.0, Windows Forms) was to make the end-user able to load a background image to an &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/microsoft.ink.inkpicture.aspx" target="_blank"&gt;InkPicture&lt;/a&gt;&lt;/code&gt; (which is just a special &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.picturebox.aspx" target="_blank"&gt;PictureBox&lt;/a&gt;&lt;/code&gt; control, with the ability to be drawn upon on a TabletPC). That did not seem very difficult at first : just create an &lt;code&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.openfiledialog.aspx" target="_blank"&gt;OpenFileDialog&lt;/a&gt;&lt;/code&gt; and there you go.&lt;/p&gt;  &lt;pre class="csharp" name="code"&gt;// WRONG ! DO NOT USE THIS CODE !&lt;br /&gt;if (_OpenFileDialog.ShowDialog()==DialogResult.OK)&lt;br /&gt;    using (Stream ims=_OpenFileDialog.OpenFile())&lt;br /&gt;        _InkPicture.Image=Image.FromStream(ims);&lt;/pre&gt; &lt;p&gt;Clean, straightforward and ... wrong ! It took me quite some time to realize it though. My application started to throw occasional and rather erratic exceptions in completely unrelated places, and it kind of reminded me of the strange ways a native application could crash after a buffer had been overrun. But in a managed application ?...&lt;/p&gt; &lt;p&gt;As often, the answer is &lt;a href="http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx" target="_blank"&gt;in the documentation&lt;/a&gt; (check the &lt;em&gt;Remarks&lt;/em&gt; section) :&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;You must keep the stream open for the lifetime of the Image.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Uh ? Any more information on why I should do this, and perhaps more importantly &lt;em&gt;how&lt;/em&gt; I should do this ? Because my &lt;code&gt;Image&lt;/code&gt; could be replaced from anywhere in the code. And even if I wanted to track the changes, there is no &lt;code&gt;ImageChanged&lt;/code&gt; event on a &lt;code&gt;PictureBox&lt;/code&gt;. And it feels weird to retain a reference to a &lt;code&gt;Stream&lt;/code&gt; I never use...&lt;/p&gt; &lt;p&gt;As for the first question, the answer lies in &lt;a href="http://support.microsoft.com/?id=814675" target="_blank"&gt;KB 814675&lt;/a&gt; : &lt;code&gt;Image&lt;/code&gt; is just a wrapper around the native GDI+ library, which has specific requirements :&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;To retain access to the source bits, GDI+ locks any source file, and forces the application to maintain the life of any source stream, for the life of the Bitmap or the Image object.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;As for the second question, tips can be found in the referenced article above. And here is my solution : use a copy of the stream based image that is unrelated to the original stream. Here is some code to create such a copy :&lt;/p&gt; &lt;pre class="csharp" name="code"&gt;public static Image Copy(Image original)&lt;br /&gt;{&lt;br /&gt;    // cf. http://support.microsoft.com/?id=814675&lt;br /&gt;&lt;br /&gt;    Image ret=new Bitmap(original.Width, original.Height);&lt;br /&gt;    using (Graphics g=Graphics.FromImage(ret))&lt;br /&gt;    {&lt;br /&gt;        g.DrawImageUnscaled(original, 0, 0);&lt;br /&gt;        g.Save();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return ret;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;And here is the correct code on how to load an &lt;code&gt;Image&lt;/code&gt; into an &lt;code&gt;InkPicture&lt;/code&gt; :&lt;/p&gt; &lt;pre class="csharp" name="code"&gt;if (_OpenFileDialog.ShowDialog()==DialogResult.OK)&lt;br /&gt;    using (Stream ims=_OpenFileDialog.OpenFile())&lt;br /&gt;        using (Image image=Image.FromStream(ims))&lt;br /&gt;            _InkPicture.Image=Copy(image);&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-6196734150093085670?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/6196734150093085670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=6196734150093085670' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/6196734150093085670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/6196734150093085670'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2009/09/beware-image-object.html' title='Beware the Image object !'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-8617128892421359122</id><published>2009-05-15T16:28:00.002+02:00</published><updated>2009-05-15T16:29:06.711+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='WiX'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>Encrypt configuration file in a custom managed action on x64</title><content type='html'>&lt;p&gt;When I install a .NET (or ASP .NET) application, I like to encrypt the sensitive parts of the configuration file like the connection strings. So I have been used to create a &lt;a href="http://msdn.microsoft.com/en-us/library/system.configuration.install.installer.aspx" target="_blank"&gt;Custom Installer class&lt;/a&gt; to achieve this. There are a few tricky things to take into account, like :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;when your configuration is loaded by the installer, it should be able to resolve embedded dependencies (like Enterprise Library assemblies) even when they are not in the GAC. &lt;/li&gt;    &lt;li&gt;this class accepts a &lt;em&gt;EXEPATH&lt;/em&gt; parameter that contains the path of the application which application file is to be encrypted. It should then be terminated &lt;a href="http://msdn.microsoft.com/en-us/library/2w2fhwzz.aspx" target="_blank"&gt;by an extra \ character&lt;/a&gt;. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For the record, here is how I do this :&lt;/p&gt;  &lt;pre class="csharp" name="code"&gt;[RunInstaller(true)]&lt;br /&gt;public partial class EncryptConfigInstaller:&lt;br /&gt;    Installer&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    public EncryptConfigInstaller()&lt;br /&gt;    {&lt;br /&gt;        InitializeComponent();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public override void Install(IDictionary stateSaver)&lt;br /&gt;    {&lt;br /&gt;        base.Install(stateSaver);&lt;br /&gt;&lt;br /&gt;        string exePath=Context.Parameters[&amp;quot;exepath&amp;quot;].TrimEnd('\\');&lt;br /&gt;&lt;br /&gt;        AppDomain.CurrentDomain.SetData(&amp;quot;EXEDIR&amp;quot;, Path.GetDirectoryName(exePath));&lt;br /&gt;        AppDomain.CurrentDomain.AssemblyResolve+=_AssemblyResolver;&lt;br /&gt;        try&lt;br /&gt;        {&lt;br /&gt;            EncryptConfiguration(ConfigurationManager.OpenExeConfiguration(exePath));&lt;br /&gt;        } finally&lt;br /&gt;        {&lt;br /&gt;            AppDomain.CurrentDomain.AssemblyResolve-=_AssemblyResolver;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)&lt;br /&gt;    {&lt;br /&gt;        AssemblyName name=new AssemblyName(args.Name);&lt;br /&gt;&lt;br /&gt;        return Assembly.LoadFile(Path.Combine((string)AppDomain.CurrentDomain.GetData(&amp;quot;EXEDIR&amp;quot;), string.Concat(name.Name, &amp;quot;.dll&amp;quot;)));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void EncryptConfiguration(Configuration config)&lt;br /&gt;    {&lt;br /&gt;        EncryptSection(config.GetSection(&amp;quot;connectionStrings&amp;quot;));&lt;br /&gt;&lt;br /&gt;        config.Save(ConfigurationSaveMode.Modified);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static void EncryptSection(ConfigurationSection section)&lt;br /&gt;    {&lt;br /&gt;        if ((section!=null) &amp;amp;&amp;amp; (!section.SectionInformation.IsProtected))&lt;br /&gt;        {&lt;br /&gt;            section.SectionInformation.ProtectSection(&amp;quot;DataProtectionConfigurationProvider&amp;quot;);&lt;br /&gt;            section.SectionInformation.ForceSave=true;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private static ResolveEventHandler _AssemblyResolver=new ResolveEventHandler(CurrentDomain_AssemblyResolve);&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt; &lt;p&gt;Then even if I know that &lt;a href="http://www.msifaq.com/a/1044.htm" target="_blank"&gt;managed actions are considered evil&lt;/a&gt;, as I do not think I have a choice here, I am using the well known &lt;a href="http://blogs.msdn.com/josealmeida/archive/2004/11/08/253831.aspx" target="_blank"&gt;WiX Custom Managed Actions&lt;/a&gt; trick. So everything is fine in a perfect world.&lt;/p&gt; &lt;p&gt;Except when a client tried to install one of my applications on a x64 platform (namely Windows Server 2008). Once solved the obvious &lt;a href="http://macinsoft.blogspot.com/2009/05/oracle-not-so-instant-client.html"&gt;native libraries problem&lt;/a&gt;, I was still puzzled by the fact that the user who had installed the application was the only one able to run it ! It was only after a couple of days of wrong conjectures, poor tricks and unproductive Google searches that I cornered the problem : the encryption process was broken.&lt;/p&gt; &lt;p&gt;Extensive reasons behind that &lt;a href="http://blogs.msdn.com/heaths/archive/2006/02/01/64-bit-managed-custom-actions-with-visual-studio.aspx"&gt;can be found here,&lt;/a&gt; but basically it is because &lt;em&gt;InstallUtilLib.dll&lt;/em&gt;, which is used to launch Installer classes, is a native library. As such, you should use the 64 bits version on a x64 platform. So I ended up copying both versions in an independent lib folder, and here is the magic corresponding WiX line :&lt;/p&gt; &lt;pre class="xml" name="code"&gt;&amp;lt;Binary Id=&amp;quot;InstallUtilBinary&amp;quot; SourceFile=&amp;quot;$(sys.CURRENTDIR)..\..\lib\$(sys.BUILDARCH)\InstallUtilLib.dll&amp;quot; /&amp;gt;&lt;/pre&gt; &lt;p&gt;Yes, I learned a lot about x64 lately. But I guess I am not done yet :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-8617128892421359122?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/8617128892421359122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=8617128892421359122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/8617128892421359122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/8617128892421359122'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2009/05/encrypt-configuration-file-in-custom.html' title='Encrypt configuration file in a custom managed action on x64'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-2838076790232806307</id><published>2009-05-15T14:42:00.002+02:00</published><updated>2009-05-15T14:43:38.025+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Oracle Instant Client in Visual Studio</title><content type='html'>&lt;p&gt;In &lt;a href="http://macinsoft.blogspot.com/2009/05/oracle-not-so-instant-client.html"&gt;my previous post&lt;/a&gt;, I mentioned the fact that I added the Oracle &lt;a href="http://www.oracle.com/technology/tech/oci/instantclient/index.html" target="_blank"&gt;Instant Client&lt;/a&gt; files as Content files in a Visual Studio project. I would like to write more about this here.&lt;/p&gt;  &lt;p&gt;If you intend to use your application with Instant Client, you will want to be able to debug it with Instant Client. Which means that the libraries have to be copied along your generated application in the &lt;em&gt;bin\Debug&lt;/em&gt; folder. The best way to achieve this is to include then as Content files in your project.&lt;/p&gt;  &lt;p&gt;But it gets more tricky if you want to be able to debug it on 32 bits platform as well as on a 64 bits platform : the source code is the same (I am obviously writing about a .NET application, here), you just have to pick the correct library depending on the platform you are debugging on.&lt;/p&gt;  &lt;p&gt;My way to do this is :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;I store the Instant Client libraries in an independent folder, say &lt;em&gt;lib\Oracle\Instant Client&lt;/em&gt;. &lt;/li&gt;    &lt;li&gt;Each platform lies in a dedicated subfolder : &lt;em&gt;x86&lt;/em&gt; for the 32 bits version, &lt;em&gt;x64&lt;/em&gt; for the 64 bits version. &lt;/li&gt;    &lt;li&gt;I manually tweak the &lt;em&gt;.csproj&lt;/em&gt; project file so that it picks the right version depending on the platform I am running Visual Studio on :       &lt;pre class="xml" name="code"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;br /&gt;  &amp;lt;ProcessorArchitecture&amp;gt;x86&amp;lt;/ProcessorArchitecture&amp;gt;&lt;br /&gt;  &amp;lt;ProcessorArchitecture Condition=&amp;quot; '$(PROCESSOR_ARCHITECTURE)' == 'AMD64' &amp;quot;&amp;gt;x64&amp;lt;/ProcessorArchitecture&amp;gt;&lt;br /&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;br /&gt;&amp;lt;ItemGroup&amp;gt;&lt;br /&gt;  &amp;lt;Content Include=&amp;quot;..\..\lib\Oracle\InstantClient\$(ProcessorArchitecture)\oci.dll&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;Link&amp;gt;oci.dll&amp;lt;/Link&amp;gt;&lt;br /&gt;    &amp;lt;CopyToOutputDirectory&amp;gt;PreserveNewest&amp;lt;/CopyToOutputDirectory&amp;gt;&lt;br /&gt;  &amp;lt;/Content&amp;gt;&lt;br /&gt;  &amp;lt;Content Include=&amp;quot;..\..\lib\Oracle\InstantClient\$(ProcessorArchitecture)\orannzsbb11.dll&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;Link&amp;gt;orannzsbb11.dll&amp;lt;/Link&amp;gt;&lt;br /&gt;    &amp;lt;CopyToOutputDirectory&amp;gt;PreserveNewest&amp;lt;/CopyToOutputDirectory&amp;gt;&lt;br /&gt;  &amp;lt;/Content&amp;gt;&lt;br /&gt;  &amp;lt;Content Include=&amp;quot;..\..\lib\Oracle\InstantClient\$(ProcessorArchitecture)\oraociei11.dll&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;Link&amp;gt;oraociei11.dll&amp;lt;/Link&amp;gt;&lt;br /&gt;    &amp;lt;CopyToOutputDirectory&amp;gt;PreserveNewest&amp;lt;/CopyToOutputDirectory&amp;gt;&lt;br /&gt;  &amp;lt;/Content&amp;gt;&lt;br /&gt;&amp;lt;/ItemGroup&amp;gt;&lt;br /&gt;&amp;lt;ItemGroup Condition=&amp;quot; '$(ProcessorArchitecture)' == 'x86' &amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;Content Include=&amp;quot;..\..\lib\Oracle\InstantClient\$(ProcessorArchitecture)\msvcr71.dll&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;Link&amp;gt;msvcr71.dll&amp;lt;/Link&amp;gt;&lt;br /&gt;    &amp;lt;CopyToOutputDirectory&amp;gt;PreserveNewest&amp;lt;/CopyToOutputDirectory&amp;gt;&lt;br /&gt;  &amp;lt;/Content&amp;gt;&lt;br /&gt;&amp;lt;/ItemGroup&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_dR4_IBKyRV0/Sg1jN_WwwxI/AAAAAAAAAEE/cQ4pjgR9mks/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-right-width: 0px; margin: 10px 10px 0px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://lh6.ggpht.com/_dR4_IBKyRV0/Sg1jOQbjHZI/AAAAAAAAAEI/3UngfKfutc0/image_thumb%5B2%5D.png?imgmax=800" width="172" height="86" /&gt;&lt;/a&gt;This code is based on the &lt;code&gt;PROCESSOR_ARCHITECTURE&lt;/code&gt; environment variable. This will be set to &lt;em&gt;x86&lt;/em&gt; on a 32 bits platform, as expected, but &lt;a href="http://support.microsoft.com/kb/888731" target="_blank"&gt;to AMD64 on a 64 bits platform&lt;/a&gt;. That is why I am using a custom property to get the &lt;em&gt;x64&lt;/em&gt; value back.&lt;/p&gt; &lt;p&gt;I could also simply rename the library subfolder to &lt;em&gt;AMD64&lt;/em&gt;, but I like &lt;em&gt;x64 &lt;/em&gt;more (I know : I am picky). And besides, it makes my WiX files more straightforward…&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-2838076790232806307?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/2838076790232806307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=2838076790232806307' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/2838076790232806307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/2838076790232806307'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2009/05/oracle-instant-client-in-visual-studio.html' title='Oracle Instant Client in Visual Studio'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_dR4_IBKyRV0/Sg1jOQbjHZI/AAAAAAAAAEI/3UngfKfutc0/s72-c/image_thumb%5B2%5D.png?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-1881885122145169150</id><published>2009-05-15T11:55:00.002+02:00</published><updated>2009-05-15T11:57:33.800+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='WiX'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Oracle (Not So) Instant Client</title><content type='html'>&lt;p&gt;Developing database oriented .NET applications is quite a no brainer once you are used to your API (ADO.NET, Enterprise Library Data Application Block…) or your ORM (NHibernate…). Just pick your database vendor ADO .NET provider, which usually consists of one assembly that you distribute with your application, and that’s it. That is how it works with SQL Server (of course), but also &lt;a href="http://www.teradata.com/td/page/149889" target="_blank"&gt;Teradata&lt;/a&gt;,&amp;#160; &lt;a href="http://dev.mysql.com/downloads/connector/net/6.0.html" target="_blank"&gt;MySQL&lt;/a&gt;, &lt;a href="http://pgfoundry.org/projects/npgsql/" target="_blank"&gt;PostgreSQL&lt;/a&gt;, &lt;a href="http://sqlite.phxsoftware.com/" target="_blank"&gt;SQLite&lt;/a&gt;… You name it, that is the way it works.&lt;/p&gt;  &lt;p&gt;Oracle, you said ? Well, that must be the exception that confirms the rule (along with DB2, but I would like to focus my rant on Oracle, if I may). It works &lt;em&gt;quite&lt;/em&gt; like this. You need an ADO .NET provider AND a native client. The problems with this are :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;it takes &lt;a href="http://www.oracle.com/technology/software/products/database/oracle10g/htdocs/10201winsoft.html" target="_blank"&gt;more than 450Mb to download&lt;/a&gt; ! &lt;/li&gt;    &lt;li&gt;you may have to install several clients on the same computer (a 11.1 client will not connect to a 8i server). &lt;/li&gt;    &lt;li&gt;good luck to you if you intended to &lt;a href="http://support.microsoft.com/kb/255084" target="_blank"&gt;make it work from an ASP .NET application&lt;/a&gt; (especially with &lt;a href="http://msdn.microsoft.com/en-us/library/aa292118(VS.71).aspx" target="_blank"&gt;impersonation&lt;/a&gt;) ! &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;But thanks to the Oracle guys, there is another solution : Oracle &lt;a href="http://www.oracle.com/technology/tech/oci/instantclient/index.html" target="_blank"&gt;Instant Client&lt;/a&gt;. It consists of just a few DLLs that you can distribute along with your application and that allow connection to Oracle databases. If you are not too picky about character sets and supported languages, &lt;a href="http://stackoverflow.com/questions/70602/what-is-the-minimum-client-footprint-required-to-connect-c-to-an-oracle-database/70901#70901" target="_blank"&gt;you can trim it down do 19Mb&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I became quite efficient with this : I add the necessary files as Content in my Visual Studio project, and a simple Setup project makes a good enough installer for my solution.&lt;/p&gt;  &lt;p&gt;Then this week, a client called me about how one of these applications just crashed after he installed it on a Windows 2008 Server. The fact was : it was a 64 bits Windows. As the .NET application was compiled as AnyCPU, it was automatically launched as a 64 bits application, and then you can guess by yourself what happened when the 32 bits Oracle client was loaded in memory. At this point, my options were :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;compile the application as x86, so that it would be launched as a 32 bits application even on a x64 platform. But why tweak my application when it is really Oracle that was at fault ? &lt;/li&gt;    &lt;li&gt;leave the application as AnyCPU, but distribute a different client depending on the platform it is installed on. This is the (more interesting) road I took. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I decided to give up on the standard Setup project (had I any other option ?) and use &lt;a href="http://wix.sourceforge.net/" target="_blank"&gt;WiX&lt;/a&gt; 3.0 instead. My first attempt was to use a single installer to be used on both platforms (x86 and x64), and distribute the Oracle Instant Client 11 depending on the platform (I found that version 10 made my application crash on Windows Vista x64, while version 11 worked fine…). This is how I achieved this :&lt;/p&gt;  &lt;pre class="xml" name="code"&gt;&amp;lt;Wix xmlns=&amp;quot;http://schemas.microsoft.com/wix/2006/wi&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;Fragment&amp;gt;&lt;br /&gt;    &amp;lt;DirectoryRef Id=&amp;quot;INSTALLLOCATION&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;?if $(sys.BUILDARCH) = &amp;quot;x86&amp;quot; ?&amp;gt;&lt;br /&gt;      &amp;lt;Component Id=&amp;quot;OracleInstantClientFiles_x86&amp;quot; Guid=&amp;quot;{AA0076CE-F7B6-4cd8-9B67-199F665A8E77}&amp;quot; KeyPath=&amp;quot;yes&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;Condition&amp;gt;&lt;br /&gt;          &amp;lt;![CDATA[Installed OR NOT VersionNT64]]&amp;gt;&lt;br /&gt;        &amp;lt;/Condition&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x86_msvcr71.dll&amp;quot; Name=&amp;quot;msvcr71.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x86\msvcr71.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x86_oci.dll&amp;quot; Name=&amp;quot;oci.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x86\oci.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x86_orannzsbb11.dll&amp;quot; Name=&amp;quot;orannzsbb11.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x86\orannzsbb11.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x86_oraociei11.dll&amp;quot; Name=&amp;quot;oraociei11.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x86\oraociei11.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/Component&amp;gt;&lt;br /&gt;&amp;lt;?endif ?&amp;gt;&lt;br /&gt;      &amp;lt;Component Id=&amp;quot;OracleInstantClientFiles_x64&amp;quot; Guid=&amp;quot;{3CCDBDB6-D45A-4523-8CC7-730D3A8851D3}&amp;quot; KeyPath=&amp;quot;yes&amp;quot;&amp;gt;&lt;br /&gt;        &amp;lt;Condition&amp;gt;&lt;br /&gt;          &amp;lt;![CDATA[Installed OR VersionNT64]]&amp;gt;&lt;br /&gt;        &amp;lt;/Condition&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x64_oci.dll&amp;quot; Name=&amp;quot;oci.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x64\oci.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x64_orannzsbb11.dll&amp;quot; Name=&amp;quot;orannzsbb11.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x64\orannzsbb11.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x64_oraociei11.dll&amp;quot; Name=&amp;quot;oraociei11.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x64\oraociei11.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/Component&amp;gt;&lt;br /&gt;    &amp;lt;/DirectoryRef&amp;gt;&lt;br /&gt;  &amp;lt;/Fragment&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;Fragment&amp;gt;&lt;br /&gt;    &amp;lt;ComponentGroup Id=&amp;quot;OracleInstantClientFiles&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;?if $(sys.BUILDARCH) = &amp;quot;x86&amp;quot; ?&amp;gt;&lt;br /&gt;      &amp;lt;ComponentRef Id=&amp;quot;OracleInstantClientFiles_x86&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;?endif ?&amp;gt;&lt;br /&gt;      &amp;lt;ComponentRef Id=&amp;quot;OracleInstantClientFiles_x64&amp;quot; /&amp;gt;&lt;br /&gt;    &amp;lt;/ComponentGroup&amp;gt;&lt;br /&gt;  &amp;lt;/Fragment&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/Wix&amp;gt;&lt;/pre&gt; &lt;p&gt;This works alright. Just reference the &lt;code&gt;OracleInstantClientFiles&lt;/code&gt; component and there you have it. But I was annoyed by the fact that my application would install in the &lt;i&gt;Program Files (x86)&lt;/i&gt; folder by default. So I went with the dual installer solution. And the source code became :&lt;/p&gt; &lt;pre class="xml" name="code"&gt;&amp;lt;Wix xmlns=&amp;quot;http://schemas.microsoft.com/wix/2006/wi&amp;quot;&amp;gt;&lt;br /&gt; &amp;lt;Fragment&amp;gt;&lt;br /&gt;    &amp;lt;DirectoryRef Id=&amp;quot;INSTALLLOCATION&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;Component Id=&amp;quot;OracleInstantClientFiles&amp;quot; Guid=&amp;quot;{AA0076CE-F7B6-4cd8-9B67-199F665A8E77}&amp;quot; KeyPath=&amp;quot;yes&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;?if $(sys.BUILDARCH) = &amp;quot;x86&amp;quot; ?&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_x86_msvcr71.dll&amp;quot; Name=&amp;quot;msvcr71.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\x86\msvcr71.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;?endif ?&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_oci.dll&amp;quot; Name=&amp;quot;oci.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\$(sys.BUILDARCH)\oci.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_orannzsbb11.dll&amp;quot; Name=&amp;quot;orannzsbb11.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\$(sys.BUILDARCH)\orannzsbb11.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;        &amp;lt;File Id=&amp;quot;OracleInstantClientFiles_oraociei11.dll&amp;quot; Name=&amp;quot;oraociei11.dll&amp;quot; Source=&amp;quot;$(sys.CURRENTDIR)..\..\lib\Oracle\InstantClient\$(sys.BUILDARCH)\oraociei11.dll&amp;quot; DiskId=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;      &amp;lt;/Component&amp;gt;&lt;br /&gt;    &amp;lt;/DirectoryRef&amp;gt;&lt;br /&gt;  &amp;lt;/Fragment&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/Wix&amp;gt;&lt;/pre&gt; &lt;p&gt;So now I can distribute the correct Oracle files (worth 130Mb per platform) along with my less than 2Mb application !&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-1881885122145169150?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/1881885122145169150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=1881885122145169150' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/1881885122145169150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/1881885122145169150'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2009/05/oracle-not-so-instant-client.html' title='Oracle (Not So) Instant Client'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-6075634193633112587</id><published>2008-10-29T18:44:00.002+01:00</published><updated>2008-10-29T18:46:14.803+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='Oslo'/><title type='text'>How to install Oslo with SQL Server Express Edition ?</title><content type='html'>&lt;p&gt;As I was delving into the &lt;a href="http://msdn.microsoft.com/en-us/library/bb126235.aspx" target="_blank"&gt;Visual Studio DSL Tools&lt;/a&gt; to design my first DSL for &lt;a href="http://www.codeplex.com/salamanca" target="_blank" rel="tag"&gt;Salamanca&lt;/a&gt;, I came across this new modeling platform by Microsoft : &lt;a href="http://msdn.microsoft.com/en-us/oslo/default.aspx" target="_blank"&gt;Oslo&lt;/a&gt;. In fact, it is so new that the first CTP has just &lt;a href="http://code.msdn.microsoft.com/oslo/Release/ProjectReleases.aspx" target="_blank"&gt;been released&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a title="Haven van Oslo by cinevideogroup, on Flickr" href="http://www.flickr.com/photos/cinevideogroup/2947630330/"&gt;&lt;img height="281" alt="Haven van Oslo" src="http://farm4.static.flickr.com/3139/2947630330_9f0f9e5ccc.jpg" width="500" align="right" /&gt;&lt;/a&gt;As I already wrote on &lt;a href="http://salamanca.nourysolutions.com/road/index.php?post/2008/10/29/To-Salamanca-via-Oslo" target="_blank"&gt;the blog of Salamanca&lt;/a&gt;, the vision for this new tool seems to be exactly what I had been needing :&lt;/p&gt;  &lt;blockquote&gt;It's actually taking the kind of models that you're seeing arising in specific domains, like software management in System Center, or your data design over in SQL, or your process activities over in BizTalk and saying, we need to take all these domains and be able to put them into one model space. In fact, we need to let people create their own domains that aren't just isolated, but that exist in this one modeling space. And that's what Oslo is about.&lt;/blockquote&gt;  &lt;p&gt;That's it. I just quoted Bill Gates !&lt;/p&gt;  &lt;p&gt;So it was unavoidable that I tried to download and install the &lt;a href="http://code.msdn.microsoft.com/oslo/Release/ProjectReleases.aspx?ReleaseId=1707" target="_blank"&gt;October 2008 CTP&lt;/a&gt; on my computer. Everything was OK, except for the fact that the installer could not create the repository on my SQL Server 2008 Express Edition database. The message was :&lt;/p&gt;  &lt;blockquote&gt;Create repository database failed, please try later&lt;/blockquote&gt;  &lt;p&gt;So I tried later, as suggested in the installed ReadMe file. Indeed, my SQL Server instance not being the default instance on my system, but rather being a named instance (the name being &amp;quot;SQLEXPRESS&amp;quot;), I understand why the repository creation failed. The trouble is that the command lines included in the file to manually create the repository are incorrect. So here are the correct ones :&lt;/p&gt;  &lt;pre&gt;CreateRepository.exe /db:.\SQLEXPRESS&lt;br /&gt;mx.exe -i:Models.mx -db:Repository -s:.\SQLEXPRESS&lt;/pre&gt;  &lt;p&gt;Please note that the second command failed at first with the following message :&lt;/p&gt;  &lt;blockquote&gt;There is insufficient system memory in resource pool 'internal' to run this query.&lt;/blockquote&gt;  &lt;p&gt;But, as suggested on &lt;a href="https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=342696" target="_blank"&gt;this Microsoft Connect SQL Server issue&lt;/a&gt;, letting the server &amp;quot;sit for a moment&amp;quot; solved the problem...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-6075634193633112587?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/6075634193633112587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=6075634193633112587' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/6075634193633112587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/6075634193633112587'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2008/10/how-to-install-oslo-with-sql-server.html' title='How to install Oslo with SQL Server Express Edition ?'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3139/2947630330_9f0f9e5ccc_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-56731043591439865</id><published>2008-08-25T14:40:00.001+02:00</published><updated>2008-08-25T14:40:36.179+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Software Factories'/><title type='text'>The road to Salamanca</title><content type='html'>&lt;p&gt;I haven't been around this blog for quite some time now. Don't take this as another useless and meaningless apology for not sticking to a self assigned schedule. The reason for this short post is just to tell the world that &lt;a href="http://www.nourysolutions.com/" target="_blank"&gt;we&lt;/a&gt; have decided to turn our software factory into an open source project, hosted on &lt;a href="http://www.codeplex.com/" target="_blank"&gt;CodePlex&lt;/a&gt; : &lt;a href="http://www.codeplex.com/salamanca" target="_blank" rel="tag"&gt;Salamanca&lt;/a&gt;. And there is even &lt;a href="http://salamanca.nourysolutions.com/road/" target="_blank"&gt;a blog&lt;/a&gt; attached to it, for which I am the main contributor. So that will be a excellent reason (I hope) for me not to find the time to update this one :-)&lt;/p&gt;  &lt;p&gt;Salamanca is a product I really grew found of, and which I think brings great promises, especially in the field of &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns" target="_blank" rel="tag"&gt;separation of concerns&lt;/a&gt; with the concept of &lt;a href="http://salamanca.nourysolutions.com/road/index.php?post/2008/08/20/Visiting-Salamanca" target="_blank"&gt;activities&lt;/a&gt;, that can be thought of as a View-Controller pattern.&lt;/p&gt;  &lt;p&gt;Granted, as the size of the observable world seen from this blog is rather small, this post will also be used as a test for the trackback and reactions mechanisms on &lt;a href="http://salamanca.nourysolutions.com/road/" target="_blank"&gt;The road to Salamanca&lt;/a&gt;.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-56731043591439865?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/56731043591439865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=56731043591439865' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/56731043591439865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/56731043591439865'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2008/08/road-to-salamanca.html' title='The road to Salamanca'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-2531404632674466303</id><published>2008-06-05T13:22:00.003+02:00</published><updated>2008-06-05T13:28:52.253+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP .NET'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Missing</title><content type='html'>&lt;p&gt;I got stuck with this error message yesterday :&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;System.Data.OracleClient requires Oracle client software version 8.1.7 or greater&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Mmmh. Let me give you some context. I have been working for almost a year now on this ASP .NET application :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;connected to an Oracle 10g database. &lt;/li&gt;    &lt;li&gt;uses the Microsoft ADO .NET provider for Oracle (preferred over &lt;a href="http://www.oracle.com/technology/tech/windows/odpnet/index.html" target="_blank"&gt;ODP .NET&lt;/a&gt; 10g for its Visual Studio 2005 integration and its ability to work above Oracle &lt;a href="http://www.oracle.com/technology/tech/oci/instantclient/index.html" target="_blank"&gt;Instant Client&lt;/a&gt;). &lt;/li&gt;    &lt;li&gt;bundled Oracle Instant Client 10.2 (more on that later...). &lt;/li&gt;    &lt;li&gt;uses impersonation. &lt;/li&gt;    &lt;li&gt;tested on numerous development environments and a couple of servers without a glitch. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This error occurred on a new and freshly installed Windows Server 2003 server. Without a clue, I looked for help on the Internet, basing my search on the error message. An I found &lt;a href="http://www.google.com/notebook/public/01335025009615452606/BDRwbSwoQnIbT6rQh" target="_blank"&gt;a good one&lt;/a&gt;, or so I thought. Let me get this straight : if you get the error above, it is very likely that you have to tweak your security rights on your Oracle client installation as suggested on the previous link. But not in my case, because of the way I had bundled Oracle Instant Client in my application :&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;the DLLs are deployed in the application bin directory. &lt;/li&gt;    &lt;li&gt;the application bin directory is added in front of the %PATH% environment variable at application startup. This is how it is done : &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;In the Global.asax file :&lt;/p&gt; &lt;textarea name="code" class="csharp" rows="13" cols="80"&gt;&lt;br /&gt;protected void Application_Start(object sender, EventArgs e) &lt;br /&gt;{&lt;br /&gt;    // Code that runs on application startup&lt;br /&gt;    SetEnvironmentVariable(&lt;br /&gt;        "PATH",&lt;br /&gt;        string.Format(&lt;br /&gt;            CultureInfo.InvariantCulture,&lt;br /&gt;            "{0};{1}",&lt;br /&gt;            Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "bin"),&lt;br /&gt;            Environment.GetEnvironmentVariable("PATH")&lt;br /&gt;        )&lt;br /&gt;    );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DllImport("kernel32.dll", EntryPoint="SetEnvironmentVariableW", CharSet=CharSet.Unicode)]&lt;br /&gt;public static extern bool SetEnvironmentVariable(string name, string val);&lt;br /&gt;&lt;/textarea&gt; &lt;p&gt;So in my case, the Oracle client installation was my application bin directory, which had the proper rights. This did not prevent me from trying to give everyone full access, just to make sure. But, very predictively, it failed to solve my problem.&lt;/p&gt; &lt;p&gt;I began to sweat a little. Did I really need to install a full Oracle client on the server ? No : I proved otherwise. I thought...&lt;/p&gt; &lt;p&gt;At last resort, I decided to use the indispensable &lt;a href="http://www.aisto.com/roeder/dotnet/" target="_blank"&gt;Reflector for .NET&lt;/a&gt; to check the piece of code responsible for throwing the exception. Nothing very fancy there, but I noticed after a while a peculiar trace mechanism. I tried to analyze it to find a way to enable it. And after a long while, I found out that Microsoft ADO .NET providers could be plugged into the &lt;a href="http://msdn.microsoft.com/en-us/library/aa964124.aspx" target="_blank"&gt;Event Tracing for Windows&lt;/a&gt; for debugging. Not very straightforward, but I managed to get it work. And here is the interesting piece of trace I got :&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&amp;lt;oc|ERR|THROW&amp;gt; 'System.DllNotFoundException: Impossible de charger la DLL 'oci.dll': Le module sp&amp;#233;cifi&amp;#233; est introuvable. (Exception de HRESULT : 0x8007007E) ,&amp;#160;&amp;#160; &amp;#224; System.Data.Common.UnsafeNativeMethods.OCILobCopy2(IntPtr svchp&amp;#160; IntPtr errhp&amp;#160; IntPtr dst_locp&amp;#160; IntPtr src_locp&amp;#160; UInt64 amount&amp;#160; UInt64 dst_offset&amp;#160; UInt64 src_offset) ,&amp;#160;&amp;#160; &amp;#224; System.Data.OracleClient.OCI.DetermineClientVersion()'&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;Please pardon my french ;-) &amp;quot;Come on&amp;quot;, I said to myself, &amp;quot;how can you not find this DLL when it is clearly in your %PATH% ?&amp;quot; Or is it not ? To be sure, I checked with &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx" target="_blank"&gt;Process Explorer&lt;/a&gt;. Indeed, it is.&lt;/p&gt; &lt;p&gt;The truth is out there : what if it could find the said DLL, but could not load it for any reason ? Indeed, a search focusing more on DllImport than on Oracle &lt;a href="http://forums.asp.net/t/1267713.aspx" target="_blank"&gt;confirmed this&lt;/a&gt; : a missing dependency could trigger this exception. So I decided to check dependencies with the &lt;a href="http://www.dependencywalker.com/" target="_blank"&gt;Dependency Walker&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="340" alt="image" src="http://lh6.ggpht.com/mcartoixa/SEfMhKqWOYI/AAAAAAAAABg/PDHH84XiSNc/image%5B12%5D.png?imgmax=800" width="565" border="0" /&gt; &lt;/p&gt; &lt;p&gt;So the Oracle Instant Client relies on MSVCR71.DLL, which is just not there. Isn't that DLL supposed to be by default in the C:\WINDOWS\system32 directory ? Well, it used to, but &lt;a href="http://support.microsoft.com/kb/326922" target="_blank"&gt;not any more&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;This is it. This dependency is so common that it had been somehow installed on all previous environments but not this one. I just added it to the application installation packages, alongside OCI.DLL, and that was it.&lt;/p&gt; &lt;p&gt;Note : Oracle Instant Client 11.1 is delivered with all its dependencies, including MSVCR71.DLL...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-2531404632674466303?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/2531404632674466303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=2531404632674466303' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/2531404632674466303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/2531404632674466303'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2008/06/missing.html' title='Missing'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/mcartoixa/SEfMhKqWOYI/AAAAAAAAABg/PDHH84XiSNc/s72-c/image%5B12%5D.png?imgmax=800' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-3254616177723125704</id><published>2008-02-20T13:51:00.004+01:00</published><updated>2008-02-20T17:33:35.267+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ETL'/><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><category scheme='http://www.blogger.com/atom/ns#' term='Software Factories'/><title type='text'>About Visual Studio, SSIS and DSLs</title><content type='html'>&lt;p&gt;I have had the opportunity to discover &lt;a href="http://www.microsoft.com/sql/technologies/integration/default.mspx" target="_blank"&gt;Sql Server 2005 Integration Services&lt;/a&gt; (SSIS) lately. That was a double blow. At first, I found it highly usable, though rough on the edges&amp;nbsp;: still only a very promising tool. And then I found it was the perfect example of a software factory created with the &lt;a href="http://msdn2.microsoft.com/en-us/vs2005/aa718368.aspx" target="_blank"&gt;Visual Studio Domain-Specific Language Tools&lt;/a&gt;. It is great to see Microsoft eating its own dog food, and create a great tool with it.&lt;/p&gt; &lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_dR4_IBKyRV0/R7xGXcJ1PeI/AAAAAAAAAAM/EGqRU6rVFDQ/s1600-h/ETL.png"&gt;&lt;img style="float:right;" src="http://bp0.blogger.com/_dR4_IBKyRV0/R7xGXcJ1PeI/AAAAAAAAAAM/EGqRU6rVFDQ/s320/ETL.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5169083840822853090" /&gt;&lt;/a&gt;I kept &lt;strike&gt;playing&lt;/strike&gt; working with it for a while and then I slightly became more and more frustrated by this experience. For instance, the process of modifying a data flow is tedious and laborious if a data source structure has been changed. And as happened with the Windows Forms designer, I soon felt the urge to bypass the designer to quickly mess with the code. My deep feeling is that designers are great to get started, editors are great to get finished. But in the case of SSIS, there is no such thing as code. All you can have is a XML file containing your flow design, messed up with presentation concerns, useless metadata, magical numbers... Great for machines, useless for humans.&lt;/p&gt; &lt;p&gt;The problem here, is that you have no &lt;a href="http://martinfowler.com/bliki/DomainSpecificLanguage.html" target="_blank"&gt;Domain-Specific Language&lt;/a&gt; (DSL) per se. Or, better, that the DSL has been generated by a machine. Some people have identified this flaw and &lt;a href="http://www.ayende.com/Blog/archive/2007/07/19/Idea-The-Boo-ETL-DSL.aspx" traget="_blank"&gt;felt the need for proper code&lt;/a&gt;, even for ETLs. I have even found a  &lt;a href="http://activewarehouse.rubyforge.org/etl/" target="_blank"&gt;code only&lt;/a&gt; ETL being developed. This, in my opinion, is the right thing to do, and I shall remember it when I design my own Software Factories&amp;nbsp;: a DSL is mandatory, the designer is here for comfort.&lt;/p&gt; &lt;p&gt;SSIS is a great tool. It just lacks a DSL.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-3254616177723125704?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/3254616177723125704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=3254616177723125704' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/3254616177723125704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/3254616177723125704'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2008/02/about-visual-studio-ssis-and-dsls.html' title='About Visual Studio, SSIS and DSLs'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_dR4_IBKyRV0/R7xGXcJ1PeI/AAAAAAAAAAM/EGqRU6rVFDQ/s72-c/ETL.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-2099162483924305930</id><published>2008-02-12T13:48:00.005+01:00</published><updated>2008-10-30T10:17:42.576+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='versioning'/><category scheme='http://www.blogger.com/atom/ns#' term='database'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>HowTo : Log DDL events in your Oracle database</title><content type='html'>&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Update&lt;/span&gt; (30/10/2008) : trigger code updated, due to a bug pointed out by Michel in the comments.&lt;/p&gt;  &lt;p&gt;Databases &lt;a href="http://www.codinghorror.com/blog/archives/001050.html" target="_blank"&gt;should be under version control&lt;/a&gt;. Not only that, but I believe that SQL scripts should be treated as regular code&amp;nbsp;: &lt;a href="http://www.joelonsoftware.com/articles/fog0000000043.html" target="_blank"&gt;can your database be built in one step&lt;/a&gt;&amp;nbsp;?&lt;/p&gt; &lt;p&gt;But if you do that, you will want to &lt;a href="http://odetocode.com/Blogs/scott/archive/2008/02/02/11721.aspx" target="_blank"&gt;scripts database changes&lt;/a&gt; too. This seems quite easy to do if you manage the whole application, but far less so if your it falls under the responsibility of, say, your customer DBA. But in any case, I think it is a good idea to track all the changes made on the structure of your database. So here is some simple scripts that I use on a daily basis to achieve this.&lt;/p&gt; &lt;p&gt;First of all, create a table&amp;nbsp;&lt;/p&gt; &lt;pre name="code" class="sql"&gt;CREATE TABLE log$ddlevents&lt;br /&gt;(&lt;br /&gt;    EventDate DATE DEFAULT SYSDATE NOT NULL,&lt;br /&gt;    Owner VARCHAR2(30),&lt;br /&gt;    EventType VARCHAR2(30) NOT NULL,&lt;br /&gt;    ObjectType VARCHAR2(18) NOT NULL,&lt;br /&gt;    ObjectName VARCHAR2(128),&lt;br /&gt;    DatabaseUser VARCHAR2(30) NOT NULL,&lt;br /&gt;    OsUser VARCHAR2(30),&lt;br /&gt;    MachineName VARCHAR2(64),&lt;br /&gt;    ProgramName VARCHAR2(64),&lt;br /&gt;    SqlText VARCHAR2(4000)&lt;br /&gt;);&lt;/pre&gt; &lt;p&gt;This table can be automatically filled thanks to the appropriate trigger&amp;nbsp;:&lt;/p&gt; &lt;pre name="code" class="sql"&gt;CREATE OR REPLACE TRIGGER trg_ad_logddlevent&lt;br /&gt;    AFTER ALTER OR CREATE OR DROP OR RENAME ON SCHEMA&lt;br /&gt;DECLARE&lt;br /&gt;    sqlTextPart ora_name_list_t;&lt;br /&gt;    sqlText VARCHAR2(4000);&lt;br /&gt;    i PLS_INTEGER;&lt;br /&gt;BEGIN&lt;br /&gt;    FOR i IN 1 .. ora_sql_txt(sqlTextPart)&lt;br /&gt;    LOOP&lt;br /&gt;        -- Make sure that we only retrieve the first 4000 characters&lt;br /&gt;        DECLARE&lt;br /&gt;            l PLS_INTEGER; -- Length of the current string&lt;br /&gt;            l1 PLS_INTEGER; -- Length of the concatenated string (can be &gt;=4000)&lt;br /&gt;            lp PLS_INTEGER; -- Length to be concatenated&lt;br /&gt;        BEGIN&lt;br /&gt;            SELECT NVL2(sqlText, LENGTH(sqlText), 0)&lt;br /&gt;                INTO l&lt;br /&gt;                FROM DUAL;&lt;br /&gt;            SELECT l+NVL2(sqlTextPart(i), LENGTH(sqlTextPart(i)), 0)&lt;br /&gt;                INTO l1&lt;br /&gt;                FROM DUAL;&lt;br /&gt;            SELECT DECODE(SIGN(l1-4000), -1, l1, 4000-l)&lt;br /&gt;                INTO lp&lt;br /&gt;                FROM DUAL;&lt;br /&gt;            sqlText:=CONCAT(sqlText, SUBSTR(sqlTextPart(i), 1, lp));&lt;br /&gt;&lt;br /&gt;            IF (l1&gt;=4000)&lt;br /&gt;            THEN&lt;br /&gt;                EXIT;&lt;br /&gt;            END IF;&lt;br /&gt;        END;&lt;br /&gt;    END LOOP;&lt;br /&gt;&lt;br /&gt;    INSERT INTO log$ddlevents (&lt;br /&gt;        Owner,&lt;br /&gt;        EventType,&lt;br /&gt;        ObjectType,&lt;br /&gt;        ObjectName,&lt;br /&gt;        DatabaseUser,&lt;br /&gt;        OsUser,&lt;br /&gt;        MachineName,&lt;br /&gt;        ProgramName,&lt;br /&gt;        SqlText&lt;br /&gt;    ) VALUES (&lt;br /&gt;        ora_dict_obj_owner,&lt;br /&gt;        ora_sysevent,&lt;br /&gt;        ora_dict_obj_type,&lt;br /&gt;        ora_dict_obj_name,&lt;br /&gt;        ora_login_user,&lt;br /&gt;        SYS_CONTEXT('USERENV', 'OS_USER'),&lt;br /&gt;        SYS_CONTEXT('USERENV', 'HOST'),&lt;br /&gt;        SYS_CONTEXT('USERENV', 'MODULE'),&lt;br /&gt;        sqlText&lt;br /&gt;    );&lt;br /&gt;END;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-2099162483924305930?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/2099162483924305930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=2099162483924305930' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/2099162483924305930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/2099162483924305930'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2008/02/howto-log-ddl-events-in-your-oracle.html' title='HowTo : Log DDL events in your Oracle database'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-803576484412992338</id><published>2007-11-30T18:22:00.001+01:00</published><updated>2007-11-30T18:35:52.285+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements'/><title type='text'>Getting Better</title><content type='html'>&lt;p&gt;I have had to spend the last few months of my life without ... a life ! Not that I had much of one before that, but this is not the point. We had this client we had signed a contract with in June for what we all believed to be a small project, due to be released in September. And we only managed to deliver our release last week : a web application (ASP .NET, C# 2.0, Oracle 10g) targeting IIS 6.0 on &lt;a href="http://www.microsoft.com/windowsserver2003/default.mspx" target="_blank"&gt;Windows Server 2003&lt;/a&gt; and a desktop application (Forms, C# 2.0, Oracle 10g) on &lt;a href="http://www.microsoft.com/windowsxp/tabletpc/default.mspx" target="_blank"&gt;Windows XP Tablet PC Edition 2005&lt;/a&gt;. The whole thing amounts to about 185,000 lines of code (according to &lt;a href="http://cloc.sourceforge.net/" target="_blank"&gt;CLOC&lt;/a&gt;), if that should ever mean something to you (please share your experience if it does ;-).&lt;/p&gt;  &lt;p&gt;The point is that we had to spend about twice as much resources on this project than was planned : we were 2 months late (on a 3 months project) and had to get additional developers involved at some point. So, what happened ? The answer is simple : a special blend of about all of the &lt;a href="http://blogs.construx.com/blogs/stevemcc/archive/2007/06/15/Classic-Mistakes-Updated.aspx" target="_blank"&gt;36 Classic Mistakes&lt;/a&gt; (except, notably, the Technology-Related Mistakes). The project at some point seemed so doomed, with blurry ever-changing requirements and about no visibility on our project, that we consider our achievement as a big success (and also as a proof that we are on the right tracks with our growing &lt;a href="http://www.softwarefactories.com/" target="_blank"&gt;Software Factory&lt;/a&gt;). But that does not mean we would accept to get through this again, and I know I, for one, would not.&lt;/p&gt;  &lt;div style="float: left"&gt;&lt;a href="http://www.amazon.fr/gp/product/0735605351?ie=UTF8&amp;amp;tag=mac09-21&amp;amp;linkCode=as2&amp;amp;camp=1642&amp;amp;creative=6746&amp;amp;creativeASIN=0735605351"&gt;&lt;img src="http://ecx.images-amazon.com/images/I/21HB3P03XDL._AA_SL160_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="margin: 0px; border-top-style: none! important; border-right-style: none! important; border-left-style: none! important; border-bottom-style: none! important" height="1" alt="" src="http://www.assoc-amazon.fr/e/ir?t=mac09-21&amp;amp;l=as2&amp;amp;o=8&amp;amp;a=0735605351" width="1" border="0" /&gt;&lt;/div&gt;  &lt;p&gt;Everybody involved in this project can be blamed. Me, us and them. And for this never to happen again, we all will have to learn from our mistakes. Starting with me, obviously. But the thing is that I cannot know for sure that my coworkers will have the same attitude. And that if they do, they will do it in (what I, in my humble opinion, would call) a sensible way. And I know for a fact that our client will not. So where do I go from here ? As for me, I sense I have to become a more accurate estimator. There &lt;a href="http://www.joelonsoftware.com/items/2007/10/26.html" target="_blank"&gt;seems to be a lot of work&lt;/a&gt; incurred, such as better organization and a lot of (boring) track keeping activity, but I guess it is what it takes. I also have to give more visibility on my work to people who lack the most basic technical skills.&lt;/p&gt;  &lt;div style="float: right"&gt;&lt;a href="http://www.amazon.fr/gp/product/0735618798?ie=UTF8&amp;amp;tag=mac09-21&amp;amp;linkCode=as2&amp;amp;camp=1642&amp;amp;creative=6746&amp;amp;creativeASIN=0735618798"&gt;&lt;img src="http://ecx.images-amazon.com/images/I/21TQYZD41ML._AA_SL160_.jpg" border="0" /&gt;&lt;/a&gt;&lt;img style="margin: 0px; border-top-style: none! important; border-right-style: none! important; border-left-style: none! important; border-bottom-style: none! important" height="1" alt="" src="http://www.assoc-amazon.fr/e/ir?t=mac09-21&amp;amp;l=as2&amp;amp;o=8&amp;amp;a=0735618798" width="1" border="0" /&gt;&lt;/div&gt;  &lt;p&gt;And I committed myself to improve my skills in the fields that I sensed people I have had to work with lacked. Even if could have considered (probably erroneously) them as not directly related to my job. And if I can, at the same time, improve my communication skills (and there is much room for improvement here) so that I can share this knowledge with them, I think will have greatly reduced the risk of me having to live through this again. First things first, I will start with requirements gathering.&lt;/p&gt;  &lt;p&gt;It seems like a lot of work. And I think it is. But I guess it is what I like about this job. It's : getting better all the time.&lt;/p&gt;  &lt;div id="{D28D3F3A-12E7-42cb-94F1-134D7EE0B244}" align="center"&gt;&lt;a href="http://profile.imeem.com/IJqG7Zd/music/e0K9DoWA/the_beatles_getting_better/" target="_blank"&gt;Getting Better&lt;/a&gt;&lt;/div&gt; &lt;script type="text/javascript"&gt;var so=new SWFObject("http://media.imeem.com/m/swiFS59KKz/aus=false/", "vplayer-{D28D3F3A-12E7-42cb-94F1-134D7EE0B244}", "300", "80", "8", "#000000"); so.addParam("wmode", "transparent"); so.write("{D28D3F3A-12E7-42cb-94F1-134D7EE0B244}");&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-803576484412992338?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/803576484412992338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=803576484412992338' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/803576484412992338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/803576484412992338'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2007/11/getting-better.html' title='Getting Better'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-3287252522120860695</id><published>2007-11-20T19:51:00.001+01:00</published><updated>2007-11-21T17:06:15.846+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>Software that works</title><content type='html'>&lt;p&gt;I hate software that works. Deeply. From the bottom of my heart and soul. Let me try to explain why.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.archives.gov/research/american-cities/" target="_blank"&gt;&lt;img height="240" src="http://www.archives.gov/research/american-cities/images/american-cities-048.jpg" width="188" align="right" /&gt;&lt;/a&gt;I have worked a lot with databases, and I have long been amazed at the ability &lt;a href="http://www.oracle.com/" target="_blank"&gt;Oracle&lt;/a&gt; has had to consistently ship software that works. Sure, they have &lt;a href="http://www.argeniss.com/woodb.html" target="_blank"&gt;their share of bugs&lt;/a&gt;, but who hasn't ? When you use their software, you can expect it to work. And nothing more. You can never expect consistency, nor OS integration, nor anything that could ease the pain of actually making it work. On the field of consistency for instance, I, for one, think that the procedures &lt;code&gt;&lt;a href="http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_lob.htm#i998484" target="_blank"&gt;GETLENGTH&lt;/a&gt;&lt;/code&gt;&amp;#160; and &lt;code&gt;&lt;a href="http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_lob.htm#sthref3586" target="_blank"&gt;GET_STORAGE_LIMIT&lt;/a&gt;&lt;/code&gt; (in the &lt;code&gt;&lt;a href="http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_lob.htm" target="_blank"&gt;DBMS_LOB&lt;/a&gt;&lt;/code&gt; package) are inconsistently named. But it works. &lt;a href="http://en.wikipedia.org/wiki/RTFM" target="_blank"&gt;RTFM&lt;/a&gt;. Have you ever tried to change the name of a computer with Oracle installed (&lt;a href="http://www.oracle.com/technology/products/database/xe/index.html" target="_blank"&gt;Express Edition&lt;/a&gt; on Windows XP for instance) ? Well, good luck if you want to see your database again.&lt;/p&gt;  &lt;p&gt;In the world of software that works, there is no such incongruity as &lt;a href="http://www.refactoring.com/" target="_blank"&gt;refactoring&lt;/a&gt;. Think of it as the activity of changing code that works into code that does the same thing, but in a different way. In other words, it is one of the most stupid things to do, the mother of all evils. One software I have had the opportunity to work on had at one time been ported from DOS (16 bit) to Windows NT (32 bit) (the source code was in C). Compiling it the first time resulted in hundreds of warnings (&lt;code&gt;int&lt;/code&gt;s would not fit in &lt;code&gt;short&lt;/code&gt;s). My coworkers confirmed it was normal behavior, and that nothing could be done while the software worked. And certainly not refactoring. As a result, the compiler &lt;a href="http://www.artima.com/cppsource/codestandards.html" target="_blank"&gt;ceased to be my friend&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;After a few years in the field, I have learn to develop a strong allergy to &amp;quot;software that works&amp;quot;.&lt;/p&gt;  &lt;p&gt;First of all, I regard the expression itself as pure nonsense. Yes, of course, software should work. And boats should float too. How would you call &lt;a href="http://en.wikipedia.org/wiki/Vasa_%28ship%29" target="_blank"&gt;a boat that does not float&lt;/a&gt; ? Software that does not work is no software. Call it an attempt, a bunch of source code, junk, whatever. Software works.&lt;/p&gt;  &lt;p&gt;But what does it do exactly ? Simple as this : software should do what it is supposed to do. This may sound a lot like &amp;quot;software should work&amp;quot;, except that this expression subtly introduces the concepts of &lt;a href="http://en.wikipedia.org/wiki/Software_Requirements_Specification" target="_blank"&gt;software requirements&lt;/a&gt; and of &lt;a href="http://www.softwarearchitectures.com/go/Discipline/DesigningArchitecture/QualityAttributes/tabid/64/Default.aspx" target="_blank"&gt;quality attributes&lt;/a&gt;.&amp;#160; What is your software supposed to do ? How efficient, usable or available is it supposed to be ? I realize now that almost none of the projects I have worked on in the past had a central repository (like a simple document) to gather answers to these simple questions. To be honest, nobody realized that these questions existed and could be asked. Unfortunately, and as far as I can tell, this is still the state of the art for the software industry.&lt;/p&gt;  &lt;p&gt;When you have requirements and attributes, you know what you can do with your code. If your software is a prototype, then it may not be worth refactoring it. If you design APIs, you might want to be consistent while naming them. The &lt;a href="http://msdn2.microsoft.com/en-us/library/system.text.asciiencoding.aspx" target="_blank"&gt;ASCIIEncoding&lt;/a&gt; class in the .NET framework does not follow the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms229043.aspx" target="_blank"&gt;capitalization conventions&lt;/a&gt; set by Microsoft itself. The difference with Oracle here is that there is a rule, and that exceptions are few (and can be seen as mistakes). Try to guess in which environment developers get more productive, more quickly ?&lt;/p&gt;  &lt;p&gt;When you don't have requirements or attributes, your only sensible goal is to build software that works. Which means you don't really have a goal.&lt;/p&gt;  &lt;p&gt;I love software development. It is a world where I can express a lot of creativity in trying to imagine solutions that fit into a set of requirements. Sometimes, I can even come dangerously close to the quixotic dreams of perfection I made as a teenager. I guess I have to be thankful that &amp;quot;software that works&amp;quot; regularly kicks in to bring me back to reality.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-3287252522120860695?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/3287252522120860695/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=3287252522120860695' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/3287252522120860695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/3287252522120860695'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2007/11/software-that-works.html' title='Software that works'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4143403277186065643.post-5232410983599478927</id><published>2007-11-15T10:55:00.001+01:00</published><updated>2007-11-15T10:55:15.388+01:00</updated><title type='text'>Brief introduction</title><content type='html'>&lt;p&gt;Hi all.&amp;#160; My name is Mac. Well, not really, but that is how my friends call me. I am 32 (still), I am a software developer, here in Paris, and have been so for the past 6 years. I have worked as a consultant in &lt;a href="http://www.quaternove.fr/" target="_blank"&gt;Quaternove&lt;/a&gt; for 5 years, developing software for a handful of diverse companies such as &lt;a href="http://www.wincor-nixdorf.com/" target="_blank"&gt;Wincor-Nixdorf&lt;/a&gt; (an ATM manufacturer), &lt;a href="http://www.servier.com/" target="_blank"&gt;SERVIER&lt;/a&gt; (a pharmaceutical laboratory) or &lt;a href="http://www.sagem.com/mobiles/" target="_blank"&gt;SAGEM&lt;/a&gt; (a mobile phone manufacturer), and developing skills (which I badly lacked ;-) in diverse technologies such as relational databases, C++, XML, Java or .NET.&lt;/p&gt;  &lt;p&gt;This experience taught me that ordinary developers have a lot to learn in many fields, ranging from the technologies they use to the communication skills that are needed to build better software. It taught me as well that in this respect (at least), I was a very ordinary developer. So I am reading a lot, from virtual blogs to real books, to try to become a better professional.&lt;/p&gt;  &lt;p&gt;After the discrepancies between how I was made things done and how I read (and came to believe) they could be done, I got myself a new job in a small company (we are 6 people), which I will keep unnamed (for now at least) as this blog is a personal initiative. I am considered a .NET expert, which I guess I can accept if it is taken as a relative notion. I am deeply involved in the realization of our vision of building our own &lt;a href="http://www.softwarefactories.com/" target="_blank" rel="tag"&gt;Software Factory&lt;/a&gt; to be able to develop better and cheaper software for our customers.&lt;/p&gt;  &lt;p&gt;This blog is destined as a means to keep track of my problems, my solutions and my various thoughts about software development. And maybe share some of them.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4143403277186065643-5232410983599478927?l=macinsoft.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://macinsoft.blogspot.com/feeds/5232410983599478927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4143403277186065643&amp;postID=5232410983599478927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/5232410983599478927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4143403277186065643/posts/default/5232410983599478927'/><link rel='alternate' type='text/html' href='http://macinsoft.blogspot.com/2007/11/brief-introduction.html' title='Brief introduction'/><author><name>Mac</name><uri>http://www.blogger.com/profile/12422354229331017688</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='25' src='http://blog.mathieucartoixa.fr/pix/Mac.jpg'/></author><thr:total>0</thr:total></entry></feed>
