Expert Texture

Thoughts on software, products, companies, technologies, people, places, and things

  Home  |   Contact  |   Syndication    |   Login
  38 Posts | 4 Stories | 0 Comments | 36 Trackbacks

News

Note: as of 11/3/05, this blog is no longer active. Click here for my active blog.
Subscribe in NewsGator Online

Archives

Post Categories

About

Links

Thursday, November 03, 2005 #

After careful consideration, I have decided to begin blogging on my own privately hosted site: et.cairene.net.  If you have subscribed to my feedburner feed (i.e., http://feeds.feedburner.com/MindFromRWandering), then your subscription will follow.

For me, it came down to this: I want more control than a community-hosted service can supply (free or otherwise).  The quite reasonable changes here at GeeksWithBlogs resulted in pushing me to this conclusion, but I would have gotten there anyway.

Thanks to Jeff Julian for GeeksWithBlogs and for his suggestions too.

I will continue “lurking here”.  I often read through the GeeksWithBlogs homepage and have started checking out the Podcast Studio.


Tuesday, October 25, 2005 #

You can find this post, and more, on my new blog here.


Last night, Dan and I went to the geek dinner Dave Winer hosted for Robert Scoble. While I've been to many parties and dinners full of geeks, this was my first "geek dinner."

There was an interesting mix of people: entrepreneurs from Web 2.0 startups, various software developers, many bloggers, and other assorted geeks.

The highlight of the evening for me was the discussion that started just before the restaurant closed. We adjourned to the parking lot to continue until it became too cold and too late (although, apparently Robert and Steve Gillmor kept it going for another hour and a half, see Geek dinner Gillmortastic).  It was a little challenging to get Steve Gillmor's entire point , although I guess Robert finally got it after we all left.

The conversation was, I think, a typical one: why Microsoft doesn't get Web 2.0 (i.e., how Google will beat Microsoft).  Steve Gillmor has some pretty strong views about the mind share that Google has regarding applications.  Yet he believes that Office will lose (or has lost) the battle.  It appears that he wants to see AJAX-enabled interfaces to everything.  All browser-based, all thin-client.

I think the major point of disagreement between Gillmor and many others in the crowd had to do with the utility of browser-based software models.  For example:

  • Gillmor wants to do all of his RSS reading on the Web.  I don't.  I prefer a model with the advantages of a smart client (rich UI and disconnected operation) that also allows me a surely Web-based interface.  Newsgator is a perfect example of this.  Both Robert and I use NewsGator in Outlook and from the Web.  I also use it from my WM5 device.  Even better, they are all synchronized.
  • Gillmor wants to write all his articles in e-mail.  He said something to the effect of "e-mail will supplant the use of Word in the next six months".  This comment nearly resulted in a wager.  I believe he is talking about a very small group of technologically-savvy early-adopters.

If Gillmor prefers Web-only, then more power to him.  And he is right, there are many like him who feel the same way.  But there are also a huge number of people (and these are not just corporate users) that prefer the installed-software model.

Google has enjoyed a great deal of popularity as an answer to Microsoft's dominance. They have a stockpile of goodwill and trust from people simply because they are not Microsoft. This is not permanent. The bigger they get, the more profitable they are (if that's possible), the more people they piss with their own kind of over-reaching, the more this is going to wane.

And Microsoft is not standing still. Certainly, they're concerned about Google (and I hope more concerned about supporting different models of user interaction than just Google). Next year is going to be a big year for Microsoft. I am not ready to count them out of this "Web 2.0" market.


Friday, October 21, 2005 #

I have removed this solution in favor of a new, more robust, solution.  You can find it on my new blog, here: Renaming ASP.NET 2.0 Assemblies Redux.

Thursday, October 20, 2005 #

This post and more can be found on my active blog, here.

Apparently Microsoft will be releasing a tool called aspnet_merge that will help resolve some of the shortcomings in the deployment options when precompiling ASP.NET 2.0 projects. This is supposed to be available on November 7th, but I don't feel like I want to wait. Thanks to the DotNetNuke guys for working with Microsoft on this. I'm really surprised that it got to be so late in Microsoft's development cycle before they figured out this was a problem.

I thought I'd try ILMerge to do it. Searching to see if someone else had, I came across this post by K. Scott Allen: Using MSBuild and ILMerge to Package User Controls For Reuse. Similar problem, different goal.

I went ahead and did this with nant as that was the quickest way for me to get this into my release process. I admit this is all a kind of a hack. First, I search for all App_Web*.dll files. Then I replace all references in the aspx and ascx files with a reference to my new merged dll. Finally, I use ILMerge to merge to the new dll. Note that I'm not merging everything, just the assemblies that have seemingly random names.

The nant code follows. It is a bit clumsy, but it works.

  
  
  
  
    
    
      
        
          
        
      
      
        
        
          
            
            
          
          
            
          
        
        
          
            
          
        
      
    
    

Thursday, September 29, 2005 #

This post and more can be found on my active blog, here.


Update: the CLR team has confirmed that this break was unintentional and has been fixed.  The June CTP probably had it and the July CTP definitely had the fix.


The other night we were performing tests of the Digipede Network on .NET 2.0 Beta 2 and came across an unexpected failure. The failing code instantiated a FileInfo object with the fileName argument of a nonexistent file. Then the code read the Attributes property. This resulted in the following exception / stack trace:

Unhandled Exception: System.IO.FileNotFoundException: Could not find file 'xxxxx'.
  File name: 'xxxxx'
    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
    at System.IO.FileSystemInfo.get_Attributes()

The code was supposed to read Attributes only if Exists was true. This was clearly a logic error, but my first question was: "How does this ever work?" As I didn't have time to look into it further, I just went ahead and fixed the problem.

Today I tested this code again in .NET 1.1 and found that Attributes returns a default value (all bits on) even when the file cannot be found. I looked this up in the BreakingChanges.chm (that hasn't been updated since May) and found no reference to this change in behavior.

I decided to test it again on .NET 2.0 Beta 2 (v2.0.50215) and confirmed again that I get the above exception. This appears to be an unintentional breaking change to Beta 2.

Then I tried it with the .NET 2.0 RC (v2.0.50727, the one from the Visual Studio 2005 RC that was handed out at ). This time it worked just like it did in .NET 1.1.

So, the problem came and went.

I figure that the Beta 2 behavior was reasonable; however, the CLR team apparently (and, I think, correctly) prefers compatibility.

Here is the code sample I used to test this out:

using System;
using System.IO;

namespace FileInfoTest {
  /// 
  /// Summary description for Class1.
  /// 
    internal class FileInfoTest {
    /// 
    /// The main entry point for the application.
    /// 
    [STAThread]
    private static void Main(string[] args) {
      // check arg length
      if (args.Length != 1) {
        Console.WriteLine("Usage: FileInfoTest file");
        return;
      }
      // get FileInfo
      FileInfo fileInfo = new FileInfo(args[0]);

      Console.WriteLine("Exists:\t{0}", fileInfo.Exists);
      Console.WriteLine("Directory:\t{0}", fileInfo.DirectoryName);
      Console.WriteLine("Name:\t{0}", fileInfo.Name);
      Console.WriteLine("Attributes:\t{0}", fileInfo.Attributes);
      Console.WriteLine("LastAccessTime:\t{0}", fileInfo.LastAccessTime);
      Console.WriteLine("LastWriteTime:\t{0}", fileInfo.LastWriteTime);
    }
  }
}



Friday, September 23, 2005 #

This post and more can be found on my active blog, here.


When I was at , I was talking to Faisal Mohamood about some interesting applications for the Digipede Network.  I had a question about Intellisense in VS2005 and he said something like “Really?  That should just work”.

Finally I have gotten to sit down and spend a few focused minutes on this Intellisense issue.  Our XSD works great in VS2003, but not in VS2005.  Lots of warnings that look like this:

Type 'x' is not declared in namespace 'y'.

I made the assumption that the VS2003 schema was actually valid; but it turns out that it wasn't.  Strangely enough, it appears that VS2003 is much more forgiving about errors in XSD than VS2005 is.  I'm happy to say that the XML validation features of VS2005 told me what was wrong with the schema and it was easy to fix.

Note: our original schema had been created using xsd.exe from a class library.   I had to tweak some things in it by hand, but basically VS2003 accepted it as it was generated.  Oddly, it had several problems in it.  The most major one (and the cause of the problem above) is that there were many top-level element nodes that should have been complexType nodes.  It seemed kind of arbitrary whether types were defined or not.  So, don't trust xsd.exe for creating valid XSD.

 


Wednesday, November 02, 2005 #

I stopped posting over the last few days due to the service changes at GeeksWithBlogs.  They have decided to include advertisements on all of their hosted blogs and feeds.  I can understand their need:  the community is growing rapidly and it's costing more money to support. 

I would have preferred it if we (as a part of this community) had been given a chance to comment on this change and even been given the option of ponying up some money.  My guess is that many members here would pay in advance for the service or even just donate money to keep it running free of ads.  (Jeff Julian implies that there may be options for an ad-free premium service in the future once they get their new blogging system in place.)

Instead, we received an e-mail on Sunday morning.  By Monday morning, my blog had an advertisement on it.  BTW: I don't object to advertisements, I just object to having no control over the advertisements. 

This is kind of ironic for me as I have been trying to figure out how to get more control over my blog's CSS template only to find that I now have less. 

In Jakob Nielsen's article Weblog Usability: The Top Ten Design Mistakes, he says that you don't want to let someone else control your blog.  He even sites this very issue as a reason (see issue #10).

Yup.

Now what?  Well, I am evaluating other options.  And maybe I will move again.  If you are a subscriber, please make sure you have subscribed to http://feeds.feedburner.com/MindFromRWandering -- this will ensure that if I do make a move, you will come along.

Update:  One thing I forgot to say in this post:  I do appreciate the community that GeeksWithBlogs is building here.  I don't actually expect service for free (and of course, that is what I have gotten and continue to get from GeeksWithBlogs).  And I do fully appreciate Jeff's need to make this change.


Friday, October 28, 2005 #

Dan Ciruli and Nathan Trueblood will be running a webinar on the DN, showing how to speed up applications.  They do a great job of giving an overview of its power and functionality.  The focus of this webinar will be financial applications.

Sign up to find out how our product can help you do more.  Faster.

Go here for details on what will be covered and to sign up.  It is scheduled for 10AM Pacific and will be about 30 minutes.


Now that I am finished with the port to VS2005 / .NET 2.0, I wanted to point out a few final issues I came across. Note that we use the Preemptive Dotfuscator v3.0 here, but the obfuscation issues likely apply to other obfuscators as well:

New files in ASP.NET 2.0

As the compilation model for ASP.NET has changed a great deal, there are also some new files that you must deploy. Of course, this is not an issue if you use VS2005 to deploy directory to a web site, but if you are packaging up all of your files into an installer then make sure you include these new files:

  • *.resx
  • *.compiled
  • PrecompiledApp.config

In particular, I have found that if the *.compiled and PrecompiledApp.config file are not in place, your global events will not get raised.

Obfuscation Issue #1: Don't rename __ASP

Exclude the __ASP namespace from the renamed. This is a new namespace that is generated by the compiler, so you need to exclude this in your Dotfuscator project file:

  <renaming>
    <excludelist>
        . . .
        <namespace name="__ASP" regex="false" />
        . . .
    </excludelist>
  </renaming>

Note that there is also a new ASP namespace, but I did not have to exclude this one because I was already excluding class names that are automatically placed under this namespace.

Obfuscation Issue #2: Don't obfuscate multiple Web projects at once

Before ASP.NET 2.0, it was possible to obfuscate multiple Web projects at the same time (as long as all of the namespaces are unique across projects). The new namespaces that are generated by the compiler (i.e., ASP and __ASP) will cause a conflict during obfuscation. To solve this problem, you need to break up your obfuscations into multiple projects.

This last part is somewhat non-trivial (or at least a real hassle). I have written many nant scripts that take build output and assemble them into a directory for obfuscation, breaks up the Dotfuscator configuration file, runs multiple obfuscation runs, and finally reassembles the files into individual folders for release.

I am not going to blog on those specifics, but if you are interested in my solutions to these problems, feel free to contact me.


Thursday, October 27, 2005 #

I have posted a bit on merging ASP.NET 2.0 (without aspnet_merge) and also on renaming ASP.NET 2.0 auto-named assemblies. My first solution on renaming was incomplete in that it would only work when there were no dependencies between the renamed assemblies.
This solution is correct and produces assemblies that properly get through Dotfuscator 3.0 / and actually run!   All of the code below are either nant targets or nant tasks.  These should be generally applicable (with the right properties assigned).
  1. Disassemble the assemblies with ildasm.
  2. Get the generated assembly name for a particular folder from a representative file (either an aspx or ascx).
  3. Replace the assembly name for all files (pages, controls, and the il) with a fixed name (e.g., “App_Web_Root”).
  4. Reassemble and rename the assembly's DLL to the fixed name (using ilasm).

These targets assume the following properties are set:

ProjectPath
the path to your build project directory
ildasm
the full path to the ildasm executable
ilasm
the full path to the ilasm executable

The first part is disassembly (the most straight-forward part):

  <!-- disassembles all App_Web assemblies to il -->
  <target name="disassembleAspNet20Assemblies" >
    <foreach item="File" property="assembly">
      <in>
        <items basedir="${ProjectPath}\bin">
          <include name="App_Web*.dll" />
        </items>
      </in>
      <do>
        <exec program="${ildasm}" workingdir="${ProjectPath}" commandline="/out=${assembly}.il /nobar /raweh /utf8 /quoteallnames /linenumbers ${assembly}" />
      </do>
    </foreach>
  </target>
The second part is to change the files to point to the new name:
  <!-- Renames a generated-assembly for ASP.NET 2.0 -->
  <!-- 'page' property is a representative page or control in the folder -->
  <!-- 'fixedAssemblyName' property is the new desired name of the assembly -->
  <target name="renameAspNet20Assembly">
    <loadfile property="loadedPage" file="${ProjectPath}\${page}" />
    <!-- get the assembly name from the representative page -->
    <regex pattern="(?'assembly'App_Web.+\s*)\042" input="${loadedPage}" />
    <!-- store the assembly name to fixed name mapping -->
    <property name="${assembly}" value="${fixedAssemblyName}"/>
    <!-- copy all of the pages (and il), replacing this assembly name with the fixed name. -->
    <copy todir="${ProjectPath}/tmpBak" overwrite="true">
      <fileset basedir="${ProjectPath}">
        <include name="**\*.as?x" />
        <include name="**\*.dll.il" />
        <exclude name="tmpBak\**" />
      </fileset>
      <filterchain>
        <replacestring from="${assembly}" to="${fixedAssemblyName}" />
      </filterchain>
    </copy>
    <!-- copy them all back -->
    <copy todir="${ProjectPath}" overwrite="true">
      <fileset basedir="${ProjectPath}/tmpBak">
        <include name="**\*.as?x" />
        <include name="**\*.dll.il" />
      </fileset>
    </copy>
  </target>
Finally, the assemblies must be reassembled:
  <!--  Reassembles all the App_Web*il into a new fixedAssembly.  -->
  <!-- This requires that the il's assembly name exists as a property that maps to the new fixedAssembly name.-->
  <target name="reassembleAspNet20Assemblies" >
    <foreach item="File" property="assembly">
      <in>
        <items basedir="${ProjectPath}\bin">
          <include name="App_Web*.dll.il" />
        </items>
      </in>
      <do>
        <!-- get the old DLL name -->
        <property name="dllName" value="${path::get-file-name-without-extension(assembly)}"/>
        <!-- get the old assembly name -->
        <property name="assemblyOnly" value="${path::get-file-name-without-extension(dllName)}"/>
        <!-- get the new, fixed assembly name -->
        <property name="fixedAssemblyName" value="${property::get-value(assemblyOnly)}"/>
        <!-- reassemble -->
        <exec program="${ilasm}" workingdir="${ProjectPath}" 
                  commandline="/out=${ProjectPath}\bin\${fixedAssemblyName}.dll /dll /res=${ProjectPath}\bin\${dllName}.res ${assembly}" /> 
        </do>
    </foreach>
  </target>
Then, for each folder, I call the target like so:
    <!--Dissasemble the assemblies-->
    <call target="disassembleAspNet20Assemblies"/>
    <!-- use Administration.aspx as a proxy for the site's root directory -->
    <property name="page" value="Administration.aspx" />
    <property name="fixedAssemblyName" value="App_Web.ControlRoot" />
    <call target="renameAspNet20Assembly" />
    <!-- use Login.aspx as a proxy for the site's Secure directory -->
    <property name="page" value="Secure\Login.aspx" />
    <property name="fixedAssemblyName" value="App_Web.Secure" />
    <call target="renameAspNet20Assembly" />
    <!-- use Headers.ascx as a proxy for the site's Control directory -->
    <property name="page" value="Controls\Header.ascx" />
    <property name="fixedAssemblyName" value="App_Web.Controls" />
    <call target="renameAspNet20Assembly" />
    <!--reassemble the assemblies-->
    <call target="reassembleAspNet20Assemblies"/>
 

After much speculation by many (on whether or not it would be before the 7th), it is available.

This is good news for those of us exhibiting at the VS launch -- we will be able to show off the Digipede Network from the final Visual Studio.


Monday, October 24, 2005 #

I found an error in my ASP.NET 2.0 assembly-renaming script (see Renaming ASP.NET Assemblies).

The regular expression isn't matching all assembly names that might be generated by the compiler.  This expression does the trick:

(?'assembly'App_Web.+\s*)\042

Simply replacing the pattern in the nant regex task solves the problem.


Friday, October 21, 2005 #

Dan is off to Code Camp in Seattle this weekend.  He'll be talking on Sunday @ 3 about grid-object oriented programming (what he calls GOOP).  He'll be talking about that and showing the Digipede Network at the same time.

If you are going to be there drop by and see him.


Where, I don't know.  It isn't yet on MSDN.  Robert Scoble said that it (and SQL Server 2005 + BizTalk 2006) are done in Three VPs on Channel 9.  Tonight is the shipping party.

Congratulations to all of the teams at Microsoft that have been working on this!


Thursday, October 20, 2005 #

I probably have not been clear in my previous posts about the overall methodology I'm following in our port to VS2005.  I have split my porting process into several different steps to isolate the effort into manageable slices.  These include:

  • Porting the projects into VS2005 for ongoing development.  While doing this, I have insured that everything still builds with VS2003 while my team makes the transition to the new IDE.  I am avoiding the temptation to fix the thousands of warnings related to deprecated functions.  That we will start fixing these as soon as the rest of the team is using VS2005. 
  • Porting our release engineering process.  I view this as the next most critical item as I want to have our testers began working with the new versions as soon as possible.  Note that I'm leaving installs and install issues out of this altogether as this is not managed inside of my group.
  • Continuous integration with CCNET. 
  • Digipede Network product features regarding mixed .NET 1.1 / .NET 2.0 environment and continued support for VS2003.
  • Evaluation of WSE3 to determine its viability relating to our release schedule.
  • (future) Evaluate performance improvements that can be achieved with .NET 2.0.
  • (future) Evaluate Team System (regarding unit testing and source control) and its applicability in our environment.

Wrapping up the Development portion

In addition to issues I brought up in my previous post (2.0 Port Update: Mixed Progress), I have come across a few more:

  • With the loss of the ASP.NET project file, many of the build properties are stored in the solution file.  I think this is unfortunate.  The ability to mix and match projects across different solutions gives the developer more flexibility (and I'm not a proponent of managing solution files in source control for this reason); however, this no longer really works with ASP.NET projects.  If we continue to keep solution files out of source control then critical build information won't be versioned.  This is not a huge problem, but I would rather not have to deal with this work-process issue while porting.
  • A slight annoyance: the ASP.NET 2.0 Project Properties dialog includes text boxes for paths to files (e.g., an SNK file).  The UI for this translates the path into an absolute one.  This is misleading, because the paths are actually stored as relative.  It would be much more clear if the UI did no such translation.

On to Release builds

The release engineering process has gone fairly smoothly.  I have been able to remove the hanging reference problem that is a bug in Dotfuscator (I blogged on that in my old blog here).

I have come across a somewhat major problem regarding the new ASP.NET 2.0 compilation model (K. Scott Allen has a good article here on this subject).  I like the idea that multiple assemblies are now supported by the compiler; however, the way that the assemblies are named presents a problem for anyone who has automated the obfuscation (and possibly the building of installs).  My biggest issue right now is getting the three Web site projects that encompass our solution into a state where I can reliably send them through our obfuscator.  I will definitely blog on the solution I come up with.