Archives

Archives / 2006
  • New Stuff, New Stuff, Go Download Already

    First of all you got the VS 2005 Service Pack 1 for Team Suite, and it's said to contain some 2200 fixes?!?! It's available for download here. Note that it's a 430 MB download and it's also said to take some time to install.

    Second good thing, and also a must to download and check out, is the RC1 of ASP.NET AJAX. You can read about it on Scott's blog. As usual, Scott gives you the info you need. I'm pretty sure that this package will used ALOT in the next couple of years, until something else pops up or becomes "cooler". Perhaps WPF(e) will beat it eventually, Another thing - the ASP.NET hompage news also says:

    The Microsoft AJAX Library is also available in an easy-to-install, standalone package for development on non-Windows systems. 

    Sounds interesting, don't you think? You can download and read more about ASP.NET AJAX on their webby,

  • [.NET 2.0] Playing Around with BuildProvider and CodeDom

    This is old news for some of you, but I've never looked at the ASP.NET buildprovider functionality in more detail until tonight, and it is pretty cool. The buildprovider can generate/build code from certain file types you drop into an ASP.NET project and I'm sure you're familiar with .xsd files and how VS.NET generates classes from those. The cool thing is that you can write your own buildprovider and generate code yourself.

    If you think this sounds like fun, here's a few links for you to get you started:

    What you need to know though, is that if you need to do something more elaborate, the CodeDom stuff isn't a walk in the park. Also, the buildprovider only works for ASP.NET projects, which is sad news, but Scott Guthrie explained it in an old blog post of his:

    In the beginning of the Whidbey project there was a plan to enable broad declarative support for file-types as compiler inputs (for example: XAML could have been processed this way).  Unfortunately due to time/resources the compiler teams had to scale back their support for this -- and only web projects still contain them.  I'm hoping we'll see broader support for them in all project types with future releases.

    Buildproviders should also work in Web Application Projects, but I couldn't get it to run... Have to look at that again some other day. I saw Scott Guthrie mention this in some blog post, but I cannot find it now. UPDATE: I got a mail from Scott about this:

    Unfortunately build providers don’t work directly with web application projects (they still work for the running app – but the assemblies they create aren’t linked to by the web application project assembly, so you can’t reference the types directly.

    You can, however, use the VS feature called “single file generators” that enable you to generate .vb/.cs files from declarative types, and then include this within your project assembly.

    Pity... guess I have to look at single file generators then if I want to follow up on this one. Or just run an external code generator manually. No time for this now anyway, too much work to do...

  • How to Use Msbuild.exe with CruiseControl.NET

    I just updated my primer/tutorial/walkthrough on CruiseControl.NET with some information about how to use msbuild.exe instead of devenv.exe in your minimal cc.net configuration. One good reason to go with msbuild is that you don't need to install VS.NET on a dedicated build server, and you can also target unit tests, performance tests, code analysis etc. that you may have added using the Team Edition versions of VS.NET.

    Please check it out and comment on it if you please.

  • System Restore...

    I'm not sure what has happened with the WinXP Automatic Updates lately, but a while ago I noticed (for the first time) I had an option to Shut down and install updates at the same time. I tried it the second time I saw it and naturally it hung my whole system.

    The machine wasn't working properly after that of course, but I managed to get in and install the updates more or less manually.

    Today I got new problems with the updates. It started with a crash in the svchost.exe process and I tried to debug and see what it was. Windows popped up a webpage telling me there was a fix for this specific "Generic Host bla bla bla" problem. I installed it, it told me it won't fully work until I restart my machine. Alright, I kept running for a while, got the svchost.exe crash again and decided to restart.

    After the restart, WinXP wanted to start install some Updates it appearently had in queue! At login? Weird. It didn't ask and I couldn't stop it. Of course the installation failed as it hung my whole box. I let it sit there for a long time before I decided to restart the machine.

    Anyway, what saved me today was to restart the machine, hit F8, select to start with a "configuration that worked" or whatever the menu option says. Now I'm in, I've configured Automatic Updates in a way so that I will decide myself when to download and install. All seems to work WAY better now.

    I wonder how far away SP3 is... I think I'm going for Vista as soon as I get my hands on the RTM version.

    UPDATE: LOL, I was too fast... after this "manual" Windows Update and the recommended reboot, I got a new crash after logging into Windows, now it was the AutoUpdate.exe crashing on my... yeah... LET ME WORK FOR LOVE'S SAKE!

  • [Podcasts] Podcast Aggregator - Doppler

    My buddy Jan-Erik has been listening to podcasts for a while now, and he pointed me to a program called Doppler which seems to be a decent podcast aggregator. I've only just started to use it, but it looks nice and seems to behave well. It got all the bells and whistles we're getting used to nowadays - async downloads, system tray, notifications and so on, and you can turn these features on and off as you please.

    Go check Doppler out at http://www.dopplerradio.net/

    Now I need to look for a seamless way to get these things over to my Sony Ericsson mobile without too many clicks.

  • [Podcasts] New Podcast - Without a Name

    Found a newly started podcast, one which haven't got a name yet even. So far called "developer podcast", but they would like to get some ideas for a name. "They" are Derek Hatchard and Mike Mullen and you find links to their own blogs from their podcast site. They have recorded 2 shows so far and the sound quality could be better, but they give some good tips about Vista which are useful and have some links to resources they talked about on their blog.

    You find these guys at http://netcasts.ardentdev.com/

  • FolderShare - The Best Utility of the Year?

    Oh yeah! Thanks to Scott Hanselman for podcasting and blogging about this tool, and thanks Microsoft for making this one a free Windows Live Service. Most of you know that Scott is testing most of the software tools that ever gets created and let me quote some of the things he's saying about FolderShare:

    Sure, there's other applications that have tried to solve problems like this before, but holy crap FolderShare nails it.

    There's so much you can do with it, like automatically mirror pictures, music and so on across your machines with a few clicks. They just have to be connected to the Internet. It's also secure. I now have my IE Favourites synced between my machines, and it was done with like 2-3 clicks.

    Even though it's free now, you got a few limitations to how many folders and files you can share right now. That will probably change in the future. If you look at https://www.foldershare.com/info/plans.php you see that there is a limit to 10 folders and 10.000 files at the moment, but hey, that will take you far. I've also seen a max filesize of 2GB being mentioned on the FolderShare web site so I'm not sure what's the deal here.

    It's beautiful anyway, go download already!

  • [Podcasts] .NET Podcasts

    I've soon listened to all shows that have been recorded by Scott Hanselman and Carl Franklin on Hanselminutes (http://www.hanselminutes.com/), and I've started to dig around for some more podcasts, preferably similar to the Hanselminutes stuff. I've been listening to .NET Rocks (http://www.dotnetrocks.com/) for some time as well, and I just ran upon the Polymorphic Podcast (http://polymorphicpodcast.com/) which seems to be just great. Polymorphic is about most things .NET related and it's hosted by Craig Shoemaker.

    Then there's the ASP.NET Podcasts, hosted by Wallace B. (Wally) McClure and Paul Glavich, which I haven't listened to (or looked at for that matter because they also have some viewable material) at http://aspnetpodcast.com or better yet http://aspnetpodcast.com/CS11/blogs/asp.net_podcast/default.aspx

    If you know of any other similar podcasts, please let me know and I'll add them to this page.

    I need to think of a way to automatically download the files and have them synced with my SonyE ricsson mobile phone... Or get a better "download deal" with my phone company and create a small program that I can run on the mobile phone to download these podcasts directly. It's too expensive for me to download these files over the mobile network as I have to pay for the bytes...

  • How to Hook Up a VS.NET 2005 Solution With CruiseControl.NET in a Few Minutes

    This is a short "primer" on how to get your CruiseControl.NET (CC.NET) Continuous Integration (CI) Server up and running with a very small configuration, and it will only take you about 5 minutes or so. I’m pretty new to CC.NET so I thought I would share some of the stuff I learned about it when setting it up. I've used it before, but that was some time ago and now I’m planning on using it for an upcoming project so I had to brush things off and see what had changed lately.

    I’m listing some NAnt resources as well here, even though I’m not covering NAnt now (but probably will in a future update). If you want to read about NAnt and CC.NET, Joe Field got a great article on it, and I'm sure there are other CC articles out there.

    Updates

    Nov 25, 2006 - Added information about how to use msbuild.exe and a small sample configuration. 

    Why CruiseControl.NET?

    So why would you like to use something like CruiseControl.NET? Say you have an ASP.NET Web application solution with a few class library projects and some NUnit tests, you keep track of it using VSS and you want to make the move to CI. Say you want it to check out, compile, test and report every time new code is checked in or by schedule every night (this is up to you and dead simple to change). If this is something you’d like to do, keep reading.

    Note that this has nothing to do with the Unit Testing features of (some of the) VS.NET Team System Editions, but CC.NET is so flexible it’s possible to use that feature too, via the <msbuild> <task> for example, but that’s for another time. I've updated this page (at the end) with a sample configuration for compiling using msbuild, but not for running unit tests with it (yet) 

    If you know the basics and just want to get to the configuration file, jump to the section near the end called “CC.NET Configuration” where you got the XML I came up with. Good luck.

    Tools and Products

    I'm using these tools and products:

    - Visual Studio.NET 2005 + Visual Source Safe

    - CruiseControl.NET version 1.1.2527, tool for doing Continuous Integration

    - NUnit version 2.3.6293 for .NET 2.0, tool and framework for unit testing your code

    - NAnt + NAntContrib version 0.85, tool and framework for performing complex build tasks, similar to msbuild.exe. The Contrib

    package contains extra stuff you want to use as a NAnt user (not used in this paper yet, but make sure it’s the same versions if you decide to install them now)

    Resources

    Some good reasources, where you can download the things I listed above:

    - CruiseControl.NET– http://ccnet.thoughtworks.com/

    - NUnit – http://www.nunit.org/

    - NAnt – http://nant.sourceforge.net/ (not used in this paper yet)

    - NAntContrib – http://nantcontrib.sourceforge.net/ (not used in this paper yet)

    - Great (longer) tutorial on CC.NET by Joe Field - http://joefield.mysite4now.com/blogs/blog/articles/146.aspx

    Ways of Building Your Code

    Just a few words about different ways to build/compile your code. There are various ways to do this of course, but a few typical ones:

    - Let CC.NET build it by using the devenv.exe program (this requires you to install VS.NET on the build server)

    - Let CC.NET hand over the build process to msbuild.exe.

    - Let CC.NET hand over the build process to NAnt, which in itself can use devenv.exe or msbuild.exe to build you code.

    Using devenv.exe is a simple way of doing it, CC.NET got a <task> for it, you just point at your solution file, and I’m sure it will be enough for most people who just wants to get going. But, it won’t give you the precise control you might want to have.

    This paper will cover the first one, using devenv.exe, and the second one using msbuild.exe, but it should be enough to get you started.

    Download

    This tutorial assumes that you already have VS.NET 2005 installed. So start off by downloading the other products listed above. There’s no need to install NAnt unless you want to use that as your build tool. The simplest configuration of CC.NET handles the build on its own, without even involving msbuild.exe, but I recommend that you look at, learn and consider using NAnt for more complex/complete build tasks. You find the links in the Resource section.

    Installing

    Installing these things is pretty straight forward and needs no help. A few words though... Most of these products are actually mimicking the beautiful way most Java tools are installed – unzip into a directory of your choice. But I recommend using the .msi installers, especially that of CC.NET as it installs a Windows Service as well and a few useful shortcuts to the CC.NET configuration file and the documentation.

    The CC.NET .msi installer also creates a website (CC.NET Dashboard) on your IIS if you got that installed. For some reason it doesn’t create any shortcuts to it from the Start menu. I’ll talk about that later.

    Speaking about documentation I have to say that the docs are great in most places. Thing is that the stuff you need to read are spread out in several places and I couldn’t find any decent CC.NET configuration that suited me. That’s why I’m writing this paper...

    My Test Solution

    So, we need something to test on, so I created this mini web app, which consists of 3 VS.NET projects:

    - A web app (I used the Web Application Project template for this)

    - A class library for a simple Database Access Layer project

    - A class library for a few unit tests (using NUnit)

    Make sure you install these things so that the solution file is sitting in a folder “above” these projects, like this:

    Solution (JohansTestSystem)

              Web Project - Johan.Web

              DAL Project - Johan.DAL

              Test Project - Johan.Test

    This will make everything sort of easier for all tools to handle the code and the projects. Start by creating an empty Solution and add new Projects to it as you go. VS.NET will make sure everything gets created where it should. It doesn’t matter where on your disk you are creating these projects, because we will check them out to and build them in another directory.

    Finally – add them to Visual Source Safe (or whatever source control system you are using). CC.NET got support for many source control systems.

    CC.NET Configuration

    Now, to the reason why you are reading this – let me show you an example of a pretty slim configuration to start with. You find the configuration file (ccnet.config) in the /server/ directory of where you installed CC.NET, or via the Start menu created by the CC.NET installation. My examples does not involve NAnt at all right now and will let CC.NET handle the build by calling the devenv.exe or msbuild.exe.

    Devenv.exe Configuration Sample 

    To understand why this first configuration file looks it does, I'll give you some info about where I have installed things and such:

    - VSS is installed in C:\Program Files\Microsoft Visual SourceSafe\

    - My VSS database is installed in C:\VSS\

    - I got a user called “Johan” in VSS

    - The solution file is checked into the VSS-project $/JohansTestSystem.root

    - I’m checking out and building the solution in the C:\CI\ directory, which means the solution will be checked out to C:\CI\JohansTestSystem\

    - I want CC.NET to look for newly checked in files every 60 seconds

    - I want CC.NET to use VS.NET devenv.exe to build my solution

    - I got NUnit installed in C:\NUNIT\

    - I want NUnit to test the application after the build

    This is a small, if not the minimum, example of a configuration file for this job:

     <cruisecontrol>

      <project name="Johans Test System">

        <sourcecontrol type="vss" autoGetSource="true" applyLabel="true">

          <executable>C:\Program Files\Microsoft Visual SourceSafe\ss.exe</executable>

          <project>$/JohansTestSystem.root</project>

          <username>Johan</username>

          <password></password>

          <ssdir>c:\vss\</ssdir>

          <workingDirectory>C:\CI\</workingDirectory>

          <cleanCopy>true</cleanCopy>

        </sourcecontrol>

       

        <triggers>

          <intervalTrigger seconds="60" />

        </triggers>

        <tasks>

          <devenv>

            <solutionfile>c:\CI\JohansTestSystem\JohansTestSystem.sln</solutionfile>

            <configuration>Debug</configuration>

            <buildtype>Build</buildtype>

            <executable>C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com</executable>

            <buildTimeoutSeconds>60</buildTimeoutSeconds>

          </devenv>

          <nunit path="C:\nunit\bin\nunit-console.exe">

            <assemblies>

              <assembly>C:\CI\JohansTestSystem\Johan.Test\bin\Debug\Johan.Test.dll</assembly>

            </assemblies>

          </nunit>

        </tasks>

       

        <publishers>

          <xmllogger />

        </publishers>

     

      </project>

    </cruisecontrol>

    You may want to consider not labeling the code after a build (applyLabel="false") and use another trigger instead of the <intervalTrigger>.

    Msbuild.exe Sample Configuration

    Now I'll show you how to change the configuration above to use msbuild.exe instead. One good reason do use this configuration is that VS.NET does not have to be installed on the build server. NOTE! If you're using the new Web Application Project template for a website project, you must copy the file Microsoft.WebApplication.targets to C:\Program Files\msbuild\microsoft\visualstudio\v8.0\webapplications\ directory, or the build will fail! The reasons for this is described in several places on the Net.

    The circumstanses described earlier are still valid, except that we're using msbuild.exe instead of devenv.exe. So, change the ccnet.config file to look like this:

    <cruisecontrol>

      <project name="Johans Test System">

        <sourcecontrol type="vss" autoGetSource="true" applyLabel="true">

          <executable>C:\Program Files\Microsoft Visual SourceSafe\ss.exe</executable>

          <project>$/JohansTestSystem.root</project>

          <username>Johan</username>

          <password></password>

          <ssdir>c:\vss\</ssdir>

          <workingDirectory>C:\CI\</workingDirectory>

          <cleanCopy>true</cleanCopy>

        </sourcecontrol>

       

        <triggers>

          <intervalTrigger seconds="60" />

        </triggers>

       

        <tasks>

          <msbuild>

            <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>

            <workingDirectory>c:\CI\JohansTestSystem</workingDirectory>

            <projectFile>JohansTestSystem.sln</projectFile>

            <buildArgs>/noconsolelogger /p:Configuration=Debug /v:diag</buildArgs>

            <targets>Build</targets>

            <timeout>15</timeout>

            <logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,ThoughtWorks.CruiseControl.MsBuild.dll</logger>

          </msbuild>

          <nunit path="C:\nunit\bin\nunit-console.exe">

            <assemblies>

              <assembly>C:\CI\JohansTestSystem\Johan.Test\bin\Debug\Johan.Test.dll</assembly>

            </assemblies>

          </nunit>

        </tasks>

       

        <publishers>

          <xmllogger />

        </publishers>

     

      </project>

    </cruisecontrol>

    The changes are in bold. The <msbuild> task and the values should be pretty straight forward and they are well described in the ccnet documentation for msbuild. Msbuild doesn't come with XML output so a few friendly people made an XML logger for it, which you need to download and put in project working directory (for me it's C:/CI/JohansTestSystem/) and also reference in the <msbuild> task section (as you can see above). Read about msbuild and the logger on this page.

    Finally, you need to do a few touches to the Dashboard configuration, which is the file called dashboard.config in c:/<ccnet>/webdashboard/ directory. First, add the compile-msbuild.xsl to the <xslFileNames> section, so that you get a somewhat nicer looking style to the msbuild output:

    <xslFileNames>

           <xslFile>xsl\header.xsl</xslFile>

           <xslFile>xsl\modifications.xsl</xslFile>

           <xslFile>xsl\compile.xsl</xslFile>

           <xslFile>xsl\unittests.xsl</xslFile>

           <xslFile>xsl\MsTestSummary.xsl</xslFile>

           <xslFile>xsl\compile-msbuild.xsl</xslFile>

           <xslFile>xsl\fxcop-summary.xsl</xslFile>

           <xslFile>xsl\NCoverSummary.xsl</xslFile>

           <xslFile>xsl\SimianSummary.xsl</xslFile>

           <xslFile>xsl\fitnesse.xsl</xslFile>

    </xslFileNames>

    You could remove the other files that you're not using, or just leave them there, it doesn't hurt. Then you would like to add the msbuild output to the dashboard menu. In the same configuration file, add a <xslReportBuildPlugin> section:

    <xslReportBuildPlugin description="MSBuild Output" actionName="MSBuildOutputBuildPlugin" xslFileName="xsl\msbuild.xsl" />

    Run

    Now, start CC.NET by clicking on the CruiseControl.NET shortcut on the desktop or find it via the Start menu, or look for ccnet.exe in the /server/ directory where you installed CC.NET.

    Even better might actually to be to open up a command prompt and run it from there, because you may get at few errors or warnings the first time and it’s easer to CTRL-C and look at them from there. Don’t bother starting the CC.NET Windows Service until you got a decent config that works well.

    If all is well, CC.NET should do its job and go back to sleep mode again, waiting for the next time to trigger. You should have gotten loads of output in the console window and something like this in the end:

    [Johans Test System:INFO] Integration complete: Success - 2006-11-11 18:45:23

    If not, go back and look at your config file where some path might be wrong. The errors output from CC.NET isn’t the best...

    The CC.NET Web Dashboard

    If you want to look at the results from the last build, or force a new build, you can use the CC.NET Dashboard. Note that ccnet.exe must be running.

    Open a browser and go to http://<your CI host>/ccnet/ and you should see the dashboard where the right hand side shows the projects described in your configuration file, in this case only one project. Click on your project name and then on the report for the latest build which will show you the files modified since last time (and by whom), and how the test run went.

    On the left hand side you can click on a number of links to get detailed reports if you like. The NUnit Details report is a good one, and as you can see, CC.NET got support for a number of other tools; NAnt, FxCop, NCover and so on.

    That’s it for now. This page will probably get updated with other sample configs where I use NAnt and other configurations with msbuild. As soon as I get a few minutes to write something...

  • Installing .NET 3.0 and Orcas... (or perhaps call it) An Ordinary Saturday in a Programmers' Life

    Note of warning - don't follow the steps I did. Better make sure you install things in the right order. Have a quick look down at the end where I have a "Lessons Learned" :p

    The Logbook

    It's Saturday morning and I'm about to install .NET 3.0 and Orcas and whateverelse I might need to get a proper 3.0 platform up and running on a WinXP VPC. It's 11am and I won't be sitting in front of the box all day to do this because I got loads of other stuff to do. The plan is to uninstall a few old things, then do something else, then download one part, install it and do something else and keep doing this until thing seem ok. Goal is to have a decent WinXP + .NET 3.0 + Orcas install to play around with by the end of the day :)

    11:00am - Need a new VPC machine to install things on, so I start by taking a copy of my (almost) vanilla WinXP SP2 VPC file I always keep handy.

    11:30am - Phew! That took a while to copy... I'm in there now, uninstalling a few old things I no longer need. I noticed I copied the wrong VPC file so I got a few old WinFX things I need to remove.

    11:55am - All done, downloading the SDK setup file... BTW, Nicholas Allen got a page where he lists things you need to install: http://blogs.msdn.com/drnick/archive/2006/11/07/v1-rtm-downloads.aspx

    12:10pm After reading up on some things, I started the install of "Microsoft® Windows® Software Development Kit for Windows Vista™ and .NET Framework 3.0 Runtime Components". It complains that I still got a few old things I should remove (FxCop etc.) and retry install. That's a good one Microsoft. Thanks. Uninstalling and retrying... this install is downloading during installation, so it might take a while. I'm off to do something else while that is running... BTW. The full install requires some 2.3 GB of disk space.

    12:18pm BANG! Installation bombed. It crashed during the FxCop installation it seems. I wanted to read about the error, but when the "report to ms" dialog was done, it closed the installation dialogs... I guess I should restart XP and restart the installation again... gah!

    12:25pm It says I must first install the old version... here goes. What old version? Taking a look at the installed programs and uninstalling whatever seems to be related to any SDKs...

    12:40pm Ngggh... still refusing to install. Uninstalling even more and trying again. Lessons learned - start out with a very, very fresh XP + VS.NET 2005 box. Kids, don't try this on your daddy's machine at home. I think I'm off to cut my hair and have something to eat.

    15:30pm Right, I'm back. I've unistalled everything I think is remotely related to the old WinFX stuff, and also let WinXP finish installing a few updates it had on queue... took a while it did. Starting a new install of .NET 3.0 SDK again. Next, next, next, next... BANG! My whole VPC now crashed as the installer was about to start doing its real work. Jeeeez... what is this?

    15:35pm Starting VPC again and we'll see if the install works better this time. Wow... it's actually looking good now.

    16:20pm Still installing...

    16:25pm Done! Now on to the next install, Visual Studio 2005 extensions for .NET Framework 3.0 (WCF & WPF), November 2006 CTP, starting now...

    16:55pm I'm back. Had something to eat. Right, installing the Orcas stuff didn't work, because it needs the .NET 3.0 runtime stuff on the machine... Weird, because one would think it got installed with the SDK... whatever, installing the runtime now. Seems that I didn't read right stuff :D

    17:55pm This is your host this evening, back from driving my daughter to a street dance show she's in. The runtime is installed and I'm back in track again - time to install the WCF/WPF extensions... why does the task "merging of the help collections" give me the chills? Because "merging of the help collections might take some time"...

    18:15pm Everything looks fine, now installing the Workflow extensions... Why does all these installation look different? Seems like every team at Microsoft is using their own installer and tools for making these packages? One would think that there were some kind of guidelines that they should try and use the same templates. Anyway, as long as it works I'm happy.

    19:15pm Took a break. Workflow Foundation extensions seems to be installed OK, time to fire up VS.NET and see if it works :p

    (a few minutes later) It works!! Yay! I need a drink...

    Lessons learned:

    a) Make sure you got a few hours of spare time...  ;)

    b) Try to have an as clean as possible machine from start - WinXP SP2 and VS.NET 2005, that's all. Use a virtual machine if possible, don't mess up the box you're working on every day.

    c) Remove anything even remotely related to older .NET 3.0 / WinFX installations.

    d) Install things in this order:

       1. Microsoft .NET Framework 3.0 Redistributable Package 
       2. Microsoft® Windows® Software Development Kit for Windows Vista™ and .NET Framework 3.0 Runtime Components
       3. Visual Studio 2005 extensions for .NET Framework 3.0 (WCF & WPF), November 2006 CTP
       4. Visual Studio 2005 extensions for .NET Framework 3.0 (Windows Workflow Foundation)

    e) Voilá, you're (hopefully) done, start making your first WPF app or something already!

     

  • [.NET 2.0] On Battery or Not

    I'm thinking of writing a small utility to manage which of my apps gets started at startup of Windows, depending on if my laptop is running on batteries or not. Normally, when I boot it up on batteries, I don't want to start things such as my blog reader and a few other things.

    The thing is it's very simple to detect from .NET if you are running on batteries or not. The SystemInformation type gives you all that and more:

    using System;

    using System.Windows.Forms;

     

    namespace BatteryConsole

    {

        class Program

        {

            static void Main(string[] args)

            {

                PowerStatus ps = SystemInformation.PowerStatus;

     

                if(ps.PowerLineStatus == PowerLineStatus.Online)

                    Console.Write("Your power cable is connected, and ");

                else

                    Console.Write("You are running on batteries, and ");

                Console.WriteLine("your battery level is on {0}", (ps.BatteryLifePercent * 100) + "%");

     

            }

        }

    }

    I'll get back if I ever get that small program written.

  • [Podcasts] Hanselminutes is Cool

    I've started to listen to podcasts on my mobile phone while commuting to where I work at the moment, and it's pretty cool. I've listened to quite a few shows by Scott Hanselman and Carl Franklin available at http://www.hanselminutes.com and I am surprised (well not really) by the quality. It's relaxed, sit-back kind of shows and Carl asks very good questions. You also get some very good tips about tools and blogs.

    The shows I've enjoyed most so far I think is the one on Test Driven and the follow up on Mock Objects. The one on Infocards were pretty interesting as well, and... ;)

    Have to hunt for more podcasts... I spend lots of time on trains these days.

  • [.NET 2.0][Unit Testing] Good Tutorial on System.Transactions (and Unit Testing)

    On my random blog reading and Googling around System.Transactions and Unit Testing, I ran into a series of short but great articles by Stuart Celarier which actually covers both topics. Stuart teaches the reader about System.Transaction by using unit tests in a very educational (and entertaining) way. 

    He uses NUnit in his articles, but nothing will stop you from using the test mechanism built into VS.NET if you got that Team Edition version. Just use the [TestMethod] attribute instead of [Test] and all sample code in the articles will compile and test well (eventually :)

    Stuart also make use of anonymous methods for testing events that I recently blogged about.

    System.Transactions is good stuff, I wonder if it could be useful to manage "compensating transactions" when dealing with multiple web service calls within a transaction?

  • [.NET 2.0][Unit Testing] Using Anonymous Methods when Testing Events

    I've not used anonymous methods too much when coding, but I ran upon a (what I think is) great use of it when writing unit tests and specifically when you need to test events. Mark Seemann blogged about it some time ago (and got lots of comments), and I've seen it in other places when surfing around a few blogs. No need for me to list some sample code, just head over to the pleh blog and read.
  • [Team System] Getting Rid of Default Document Folders in the Quick Launch Bar

    I just recently blogged about how to display document folders in the Quick Launch area of the TFS Sharepoint portal. Here's a follow-up to that one on how to remove the default folders which are created when you set up a new Team System project. It's all about modifying the Sharepoint template. You should only try this if you are creating a custom Team System Process Template.

    1) Create a new test-project in Team System, don't bother to add any source control to it.

    2) In Team Explorer, remove the Document folders and files you're not interested in. This will be reflected on the project portal. As is explained in detail at the MSDN site, you must also edit the Process Template XML files to reflect these changes to the template content. While at it, you may also delete any reports you don't want (or add for that matter), but again - modify the template XML files to reflect this. I'm pretty sure it will still work well, but you never know, things will probably be messed up if you don't. If you change the portal content, change the XML files (repeat as a mantra).

    3) On the project portal, go to "Site Settings", "Go to Site Administration" and click "Save site as template". This will create an .stp file on the portal that you can download and put anywhere on your Team Foundation Server for now. Write down the name of the Sharepoint template because you need it in the following steps.

    4) The rest about how to add the template to the server and so on is well described on the TFS site on MSDN. In short - Go to the server, add the template to the TFS by using the stsadm.exe tool and pointing at your .stp file. Then get back you your lovely Process Template files and refer to it (by name) in the <site> section of the WssTasks.xml file.

    5) Now, upload the new Process Template to TFS, create a new project and see if it looks alright.

    As I wrote earlier, to change the overall look and feel of the Sharepoint portal, you still need to use Frontpage, but that is something I will go into later.

  • [Team System] Displaying Document Folders in the Quick Launch Bar

    Some people who are editing their Team System process templates and are new to Sharepoint wonder how to publish their own document folders in the menu of the portal home page. There are at least 2 ways - either use Frontpage (which I haven't tested yet), or in Sharepoint go to "Documents and Lists", click the folder in question, click "Modify settings and columns" in the left hand menu and then "Change general settings" and tell it to "Display this document library on the Quick Launch bar".

    To modify the Quick Launch bar when it comes to reports and such, I think Frontpage is the tool. I'll try that as soon as I get Frontpage installed... not even sure which version of Frontpage to use actually.

    Last thing to do is to modify the Sharepoint portal template in a way that suits the new process template, then create a new template out of it, make sure it's installed on the Team System server and then point at it from the WssTasks.xml file:

    <site template="Your_Sharepoint_template" language="1033" />

    Who said creating your own process template for TFS was easy? :) I'll get back to this process in a later post.

  • [Team System] Great Tool for Modifying Process Template

    I found a great tool for those of you who wants to modify the process template - Process Template Editor from imagiNET, and it's free. It won't see to all your needs, but it's a great help and the best tool I've seen so far to get you started. You still need to do some manual XML editing if your goal is to create a completely new template, and I still need to find a good way to modify the document folders and the content within there. So far I've been editing the WssTasks.xml file by hand, and it *beeps*... :)

     

  • Get Padded Aspect Ratio Thumbnail Image

    I needed a GetThumbnail method which kept the aspect ratio of the original and also scaled the image with decent quality. There are several ways you can do this, I got a few examples here.

    First, there is the Image.GetThumbnailImage() method which is pretty good if you just want to scale down the original image to a specific size, say 64 x 64:

        thumbnail = img.GetThumbnailImage(64, 64, Nothing, IntPtr.Zero)

    But the problem with this method is the image get scewed and most people I think want to keep the aspect ratio. So if I want to scale down the original image by, say by 50%, and still keep the aspect ratio:

        Private Function GetAspectRatioThumbnail(ByVal img As Image, ByVal percent As Integer) As Image

            Dim ratio As Double = percent / 100

            Return img.GetThumbnailImage(img.Width * ratio, img.Height * ratio, Nothing, IntPtr.Zero)

        End Function

    Very simple, yes, but if you've not been doing image manipulation before this could get you going I guess.

    Now, I needed to fit a big image with unknown size into a fixed size area in a report, and this image area in the report streches the image to fit the bounds by itself. Not good. So I needed to both scale down the image, and "pad" it so it filled out the image area in the report. This little method helped me out here:

        Private Function GetPaddedAspectRatioThumbnail(ByVal img As Image, ByVal newSize As Size) As Image

            Dim thumb As New Bitmap(newSize.Width, newSize.Height)

            Dim ratio As Double

     

            If img.Width > img.Height Then

                ratio = newSize.Width / img.Width

            Else

                ratio = newSize.Height / img.Height

            End If

     

            Using g As Graphics = Graphics.FromImage(thumb)

                'if you want to tweak the quality of the drawing...

                g.InterpolationMode = InterpolationMode.HighQualityBicubic

                g.SmoothingMode = SmoothingMode.HighQuality

                g.PixelOffsetMode = PixelOffsetMode.HighQuality

                g.CompositingQuality = CompositingQuality.HighQuality

     

                g.DrawImage(img, 0, 0, CInt(img.Width * ratio), CInt(img.Height * ratio))

            End Using

     

            Return thumb

        End Function

    You can tweek the quality of the image drawing as you see fit, it all depends on the size of the image, how much you need to scale it down and so on. I'm sure there are many other ways to do this, but it works for me.

     

  • [Books] Essential ASP.NET 2.0 - off to the presses!

    More than a week old news, but this is a book I'll be getting when it comes out. Fritz Onion writes on his blog:
    My production editor at Addison Wesley just informed me that Essential ASP.NET 2.0 just went to press last week! I should have copies in my hand before Halloween, just in time to bring with me to TechEd Developers in Barcelona (where they should also be available at the conference bookstore, assuming everything is shipped successfully). If you won't be in Barcelona, you can also pre-order it from Amazon, Barnes and Noble, or Bookpool.com of course ;)
    I'll see if I can pre-order it where I usually buy books like this...
  • [Ajax] Top 10 Web 2.0 Attack Vectors

    Shreeraj Shah on Top 10 Web 2.0 Attack Vectors:
    This technological transformation is bringing in new security concerns and attack vectors into existence. Yamanner, Samy and Spaceflash type worms are exploiting “client-side” AJAX frameworks, providing new avenues of attack and compromising some of the confidential information.
    Worth reading I say. Especially #6, Client side validation in AJAX routines:

    WEB 2.0 based applications use AJAX routines to do a lot of work on the client-side, such as client-side validations for data type, content-checking, date fields, etc. Normally, these client-side checks must be backed up by server-side checks as well. Most developers fail to do so; their reasoning being the assumption that validation is taken care of in AJAX routines. It is possible to bypass AJAX-based validations and to make POST or GET requests directly to the application – a major source for input validation based attacks such as SQL injection, LDAP injection, etc. that can compromise a Web application’s key resources.

    This is just not a common mistake in Ajax code, it relates to all web pages and forms where you leave input validation to be handled by JavaScript on the client side. If you're concerned with what data you get fed by people, always check it on the server side. And not just data from form fields, also check data you get via web services, POX over HTTP or even the product catalog you import from trusted parts.

     
  • Missing the App Pools Folder in Windows 2003?

    Well, that happened to me today, and even though I've been working with Win 2k3 for quite some time now, not seeing the application pools where they were supposed to be quite baffled me :)

    Of course the simple answer is that IIS was running in IIS 5.0 Isolation Mode (also called IIS 5.0 compatibility mode). Not sure why though, but I guess there may have been some issues with old COM components or something and therefore the default IIS settings were changed.

    If you want to change back to "Worker Process Isolation Mode"? Just (quoted from TechNet):

    1.  In IIS Manager, expand the local computer, right-click Web Sites, and then click Properties.
    2.  Click the Service tab, clear the Run WWW service in IIS 5.0 isolation mode check box, and then click OK.
    3.  To start the WWW service, click Yes when asked if you want to restart IIS now.

    If the switch to worker process isolation mode is successful, a folder named Application Pools appears in the IIS Manager listing for your local computer. You can quickly determine which isolation mode IIS is running because the Application Pools folder is present in worker process isolation mode and absent in IIS 5.0 isolation mode.

  • Save Image to Byte Array

    Saving an Image object to disk is straight forward, just call the Image.Save(filname) method and it's done. But what if you need to save that Image to a Byte() array (or Byte[] in c# speak ;) because you need to store it in a database or stream it somewhere? It turned out to be quite simple if you use the MemoryStream class of .NET and the Image.Save(stream, imagetype) method overload:
     
    Dim img As Image = LoadImageSomehow()
    Dim rawData() AsByte
    Using ms AsNew MemoryStream()
       img.Save(ms, Imaging.ImageFormat.Png)
       rawData = ms.GetBuffer()
    EndUsing
    'do something with the rawData buffer here...
     
    Works for me.
     
  • [Team System] Migrating Code From VSS to VS2005 and Team Foundation Server

    UPDATE: I really, really recommend that you check out this GUI for VSSConverter at http://www.epocalipse.com/blog/2006/04/06/vssconverter-gui/ It was created by Eyal Post and it works like a charm! 

    We recently tried to migrate old VS2003 code from VSS to VS2005 and Team Foundation Server using the vssconverter utility that ships with Team System, and it worked pretty well... after a while.

    It's pretty straight forward if you follow the guideance on this page, http://msdn.microsoft.com/en-us/library/ms253060.aspx, but I really recommend you make sure the old code and VSS database is backed up first and that you try the migration to a test-project first.

    We set up a local VSS database on a client machine and moved (via archiving) the code to that local database first. Then we ran the analyze, test migration, tweaked the user mapping file and then finally kicked off the migration to the production TFS project. It worked without any major problems except that we had to be logged in as a user on the domain and with proper right to the team project. But it's all in the TFS documentation on MSDN... somewhere :D

    What may be somewhat itchy is the work you may get into after that, when you open up old solution and project files. It may be that VS2005 fails to load the old project files, but try to do a "get latest" and check out the .vbproj and .csproj files, then try to reload the projects. Good luck! 

    UPDATE: It looks as if the best way to open up a migrated solution is to locate the solution file in the Source Control Explorer window and double-click it. I will probably ask you to re-bind the projects, so do that and they should "connect" automatically. Make sure you have "Visual Studio Team Foundation Source Control" selected as your Source Control Plug-in in Tools->Options. It happens that the plug-in selection reverts back to VSS sometimes when the solution is opened.

  • Colibri Type Ahead

    Jan-Erik says:
    I can't imagine how I managed before I installed Colibri. It's so super easy to start programs now. Just press CTRL+SPACE and write the program name. I rarely ever goes to the Start-menu anymore... It's really super.
    I just installed it myself and it's... cute!
  • [Team System] How to Delete a TFS Team Project

    There are several ways to delete a TFS team project, but not via the Team Explorer. Steven Smith writes:

    If you need to delete a Team System Project you need to do it through a command line utility that is installed with Team Explorer.  In my case, I created a test project but wanted to also test project deletion.  There is no way to delete a project from Team System except through the command line tool, TFSDeleteProject.exe.  This utility is in the c:\program files\Microsoft Visual Studio 8\Common7\IDE\ folder by default.  To delete a project, use the following syntax:

    TFSDeleteProject /server:ServerName ProjectName

    Julien Lavigne got a utility which does the same thing via a web service.

  • [Team System] How to Delete a TFS Build Type

    Something I read on MSDN about deleting Build Types (because there's no obvious way to do it in the Team Explorer:

    To delete a build type
    1. On the View menu, click Other Windows and then click Source Control Explorer.
    2. In the Folder pane of the Source Control Explorer, locate the build type that you want to delete in the ${Team Project}\Team Build Types\{Build Type Name}\TeamBuild.proj tree. The build type is represented by the TeamBuild.proj file, but you need to delete the folder as well.
    3. With the desired build type folder selected, choose Delete from the shortcut menu. You will also need to check in the changes that were made to the directory. The build type entry is deleted and the action removes all underlying XML files.

    Good shortcut for how to manage Build Types in TFS -> Working with Build Types in Team Build 

    I also found good info about deleting build types on the Vertigo's Team System blog -> http://blogs.vertigosoftware.com/teamsystem/archive/2006/05/03/Deleting_Team_Build_Types_and_Team_Builds.aspx

     

  • [SQL] Using a Variable TOP Clause

    This is a simple one, but still worth mentioning. Say you want to select a variable number of rows in a SELECT statement and don't want to use "dynamic SQL" to do that but rather use a SQL Parameter - no problems. In SQL Server 2005 you can type a query like this:

    SELECT TOP (@number) Title,Body,Author,Created,LastModified FROM Pages ORDER BY LastModified DESC

    Note that the parenthesis around @number is important, or you'll end up getting this error:

    Incorrect syntax near '@number'.

    If you're stuck with an older version of SQL Server, there are several ways to work around that problem. You could for example set the ROWCOUNT, as ROWCOUNT supports a variable:

    SET ROWCOUNT @number; SELECT Title,Body,Author,Created,LastModified FROM Pages ORDER BY LastModified DESC; SET ROWCOUNT 0

    A good place to look for SQL syntax information is here and here.
  • [Team System] Looking at Team Foundation Server

    I've not been blogging that much lately - and for good reasons. I switched work a week ago, and many of you know how that is. Full speed ahead, lot of new info to dig into and new things to learn. It's been an inspiring week and it feels really good.

    Anyway, I've started to look more in detail at Team System and especially the Foundation Server parts. We plan to introduce it at work and really start using it to it's full extent with custom project templates and work items. I've been looking at most of the videos at TeamStudioRocks, and even though they are from the beta versions, that site is worth a visit or two. Other good websites for Team System and TFS related info is the Rob Caron blog and of course the Visual Studio Team System User Education (phew) blog.

  • My Cat Sponsored by Google?

    Amazing... I was installing the trial version of Winzip 10 to zip up a bunch of files for a big backup and I was just about to uncheck the "install Google..." options because I already got the Windows Live stuff installed and it works pretty well. As I was reaching for that checkbox my cat jumps up on the table and hits Enter and starts to install everything. Now I got search deskbars and toolbars like everywhere... how useful... not.

    After I've uninstalled certain components I'm gonna have a talk with that cat.

  • Kid's Programming Language - KPL

    If you like coding and simple games and perhaps want to teach your kids (or yourself for that matter) how to code games - check out Kid's Programming Language. It's free, it's based on .NET 1.1, it comes with a decent color-coded editor and a bunch of sample game code, sounds and sprites. Including a fully functional Missile Command game in around 1500 lines of code. An Asteroids looking game can be downloaded.

    As you understand, the main focus of KPL seems to be to learn how to code by maknig games. Not a bad idea. I spent a few hours playing around with it and it's seriously fun. Anyone who knows just a little coding can make their own little game and version 2 of KLP will have full support for 3D.

  • Ultimate List of Free Windows Software from Microsoft

    Found this blog post on "The Road to Know Where" - a huge list of free and sometimes very useful tools and apps from Microsoft:

    Ultimate List of Free Windows Software from Microsoft
    Microsoft has over 150 FREE Windows Programs available for download -- but finding them all is extremely difficult. Until now, thanks to the Road to Know Where!

    A few favorites on that list are Open Command Window Here and Alt-Tab Replacement.

  • [.NET 2.0] Detecting Idle Time with Mouse and Keyboard Hooks

    I thought I could share some piece of code I wrote a couple of years ago to detect if a user is idle or not. I used it on a chat client I developed because we were not allowed to use Messenger at the site. So the way to do it is to set up a coupld of low-level Windows hooks to detect mouse and keyboard activity. Obviously this involves a couple of DLL Import statements and you have to be careful to UnHook everything when the application exits as we're dealing with unmanaged code here. That's why I implemented the IDispose pattern for it.

    This code is actually a piece of cake to implement if you use the ClientIdleHandler class (code below). First a look at the sample Windows Form which is made up of a lable indicating if the user is idle or active, and a timer set to 1 second. Each time the timer fires, it checks the bActive value in the ClientIdleHandler to see if the user has been active since the last check. I also added a progress bar on it (0 to 10) to give a visual indication on the idle seconds count.

    Note: This code has not been tested in production systems and if you decide to use it, do that at your own risk. This code has been running pretty fine for the last 2 years, but on .NET 1.1. I don't know how well it behaves on .NET 2.0 even though it seems to work well. Also note that this code is not optimized in anyway and you may want to implement the static bActive variable different, perhaps raise events from the ClientIdleHandler class instead of using a timer like I do. Anyway, you have been warned :)

    Form1.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;

    namespace MouseAndKbdHookSample
    {
        
    public partial class Form1 : Form
        {
            
    private ClientIdleHandler clientIdleHandler = null;
            
    private int iIdleCount = 0; //keeps track of how many seconds the user has been idle
            private const int IDLE_THRESHOLD = 10; //how many seconds should pass before the app goes into idle mode

            public Form1()
            {
                InitializeComponent();

                
    //start client idle hook
                clientIdleHandler = new ClientIdleHandler();
                clientIdleHandler.Start();
            }

            
    private void timer1_Tick(object sender, EventArgs e)
            {
                
    if (ClientIdleHandler.bActive)    //indicates user is active
                {
                    
    //zero the idle counters
                    ClientIdleHandler.bActive = false;
                    iIdleCount = 0;

                    
    //change user status
                    if (IdleLabel.Text == "IDLE")
                        IdleLabel.Text =
    "ACTIVE";

                }
                
    else    //user was idle the last second
                {
                    
    //check if threshold was reached
                    if (iIdleCount >= IDLE_THRESHOLD)
                    {
                        
    //change to IDLE and stop counting seconds
                        if (IdleLabel.Text == "ACTIVE")
                            IdleLabel.Text =
    "IDLE";
                    }
                    
    else //increase secs counter
                        iIdleCount++;
                }

                
    //some visual goo added
                progressBar1.Value = iIdleCount;
            }
        }
    }

    I added some code into the Dispose() method of the form, to help close the hooks, like this:

              //Dispose of our client idle handler
              if (clientIdleHandler != null)
                  clientIdleHandler.Close();

    Then there is this ClientIdleHandler class which does it all. I added enough comments in there I hope to explain what it does. If you want to read more on these hooks and how to use them from .NET there is always Google out there and a few KB articles on MSDN which helped me out. Like this one for example. Some people may recognize parts of the code in this class from a bunch of code sample that can be found on the Internet, still this kind of functionality is still asked for by people in forums.

    ClientIdleHandler.cs

    using System;
    using System.Runtime.InteropServices;

    namespace MouseAndKbdHookSample
    {
        
    /// <summary>
        /// Write something here sometime...
        /// </summary>
        public class ClientIdleHandler : IDisposable
        {
            
    //idle counter
            public static bool bActive = false;
            
    // hook active or not
            static int hHookKbd = 0;
            
    static int hHookMouse = 0;

            
    // the Hook delegate
            public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
            
    //Declare MouseHookProcedure as HookProc type.
            public event HookProc MouseHookProcedure;
            
    //Declare KbdHookProcedure as HookProc type.
            public event HookProc KbdHookProcedure;

            
    //Import for SetWindowsHookEx function.
            //Use this function to install thread-specific hook.
            [DllImport("user32.dll", CharSet = CharSet.Auto,
                 CallingConvention =
    CallingConvention.StdCall)]
            
    public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
                
    IntPtr hInstance, int threadId);

            
    //Import for UnhookWindowsHookEx.
            //Call this function to uninstall the hook.
            [DllImport("user32.dll", CharSet = CharSet.Auto,
                 CallingConvention =
    CallingConvention.StdCall)]
            
    public static extern bool UnhookWindowsHookEx(int idHook);

            
    //Import for CallNextHookEx
            //Use this function to pass the hook information to next hook procedure in chain.
            [DllImport("user32.dll", CharSet = CharSet.Auto,
                 CallingConvention =
    CallingConvention.StdCall)]
            
    public static extern int CallNextHookEx(int idHook, int nCode,
                
    IntPtr wParam, IntPtr lParam);

            //Added all the hook types here just for reference
            
    public enum HookType : int
            {
                WH_JOURNALRECORD = 0,
                WH_JOURNALPLAYBACK = 1,
                WH_KEYBOARD = 2,
                WH_GETMESSAGE = 3,
                WH_CALLWNDPROC = 4,
                WH_CBT = 5,
                WH_SYSMSGFILTER = 6,
                WH_MOUSE = 7,
                WH_HARDWARE = 8,
                WH_DEBUG = 9,
                WH_SHELL = 10,
                WH_FOREGROUNDIDLE = 11,
                WH_CALLWNDPROCRET = 12,
                WH_KEYBOARD_LL = 13,
                WH_MOUSE_LL = 14
            }

            
    static public int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
            {
                
    //user is active, at least with the mouse
                bActive = true;
                
                
    //just return the next hook
                return CallNextHookEx(hHookMouse, nCode, wParam, lParam);
            }


            
    static public int KbdHookProc(int nCode, IntPtr wParam, IntPtr lParam)
            {
                
    //user is active, at least with the mouse
                bActive = true;

                
    //just return the next hook
                return CallNextHookEx(hHookKbd, nCode, wParam, lParam);
            }

            
    public void Start()
            {
                
    if (hHookMouse == 0)
                {
                    
    // Create an instance of HookProc.
                    MouseHookProcedure = new HookProc(MouseHookProc);
                    
    // Create an instance of HookProc.
                    KbdHookProcedure = new HookProc(KbdHookProc);

                    
    //register a global hook
                    hHookMouse = SetWindowsHookEx((int)HookType.WH_MOUSE_LL,
                        MouseHookProcedure,
                        (System.
    IntPtr)Marshal.GetHINSTANCE(
                        System.Reflection.
    Assembly.GetExecutingAssembly().GetModules()[0]),
                        0);
                    
    //If SetWindowsHookEx fails.
                    if (hHookMouse == 0)
                    {
                        Close();
                        
    throw new ApplicationException("SetWindowsHookEx() failed");
                    }
                }

                
    if (hHookKbd == 0)
                {
                    
    //register a global hook
                    hHookKbd = SetWindowsHookEx((int)HookType.WH_KEYBOARD_LL,
                        KbdHookProcedure,
                        (System.
    IntPtr)Marshal.GetHINSTANCE(
                        System.Reflection.
    Assembly.GetExecutingAssembly().GetModules()[0]),
                        0);
                    
    //If SetWindowsHookEx fails.
                    if (hHookKbd == 0)
                    {
                        Close();
                        
    throw new ApplicationException("SetWindowsHookEx() failed");
                    }
                }
            }

            
    public void Close()
            {
                
    if (hHookMouse != 0)
                {
                    
    bool ret = UnhookWindowsHookEx(hHookMouse);
                    
    //If UnhookWindowsHookEx fails.
                    if (ret == false)
                    {
                        
    throw new ApplicationException("UnhookWindowsHookEx() failed");
                    }
                    hHookMouse = 0;
                }

                
    if (hHookKbd != 0)
                {
                    
    bool ret = UnhookWindowsHookEx(hHookKbd);
                    
    //If UnhookWindowsHookEx fails.
                    if (ret == false)
                    {
                        
    throw new ApplicationException("UnhookWindowsHookEx() failed");
                    }
                    hHookKbd = 0;
                }
            }

            
    public ClientIdleHandler()
            {
                
    //
                // TODO: Add constructor logic here
                //
            }
            #region IDisposable Members

            
    public void Dispose()
            {
                
    if (hHookMouse != 0 || hHookKbd != 0)
                    Close();
            }

            #endregion
        }
    }

    That's it folks! I hope it helps someone.

  • [Refactoring] Tools for Refactoring VB.NET

    I've not been coding any VB.NET for a while now, but when looking into a pretty good sample of how to develop an Outlook style smart client (which is in VB.NET), the walkthrough recommended to use Refactor! for Visual Basic 2005. It's a free plugin from Developer Express inc, in partnership with Microsoft and it supports a bunch of the most common refactorings you need.

    The last 2 years I've used c# all of the time for my .NET projects, but VB.NET is pretty neat actually. I don't mind using VB for coding up presentation layer stuff, and keep using C# for the rest. VB can be somewhat faster to use, as you don't need to think of cases, semi colons and stuff, and you got these new namespaces which gives you fast track access to common functionality which is almost like cheating ;)

    If the link to the sample app is not working for you, try searching on MSDN for "RSS Reader Outlook look and feel" and you should find it. Also available on the VB Developer Center.

  • WinFX Renamed to .NET Framework 3.0

    Picked this up from Soma's blog:

    ...we have decided to rename WinFX to the .NET Framework 3.0.  .NET Framework 3.0 aptly identifies the technology for exactly what it is – the next version of our developer framework.

    What a pack of good stuff developers will get in that release indeed. The CLR will still be version 2.0 though. Jazon Sander posted some details around questions that followed directly after that announcement, like these:

    1.  What version of the compilers are being used?  .NET FX 3.0 is built on .NET FX 2.0 including the CLR and BCL.  This means you will be using the 2.0 C# and VB compilers from the redist when using .NET FX 3.0. 

    2.  Will .NET FX 3.0 contain LINQ support?  No.  LINQ support is in the Orcas product which is shipping after .NET FX 3.0 (which ships in Vista).

    I think I'll have to figure out a new tag taxonomy for my blog posts :)

  • [Vista] Getting Daemon Tools to Work in Vista Beta 2

    Try this at own risk (see below)

    If you like me use Daemon tools alot and want to get it to work in Vista Beta 2 - Try downloading an older version 3.02 from the D-tools archives. It worked for me.

    You may have to disable UAP to install the drivers though, which is done via the System Configuration tools (the Tools tab).

    One strange thing which happened just now though is that Vista tried to re-active again it seems, and it failed. I looked at "Welcome Center" and yep - my Vista is no longer activated and when I try to activate it fails with error code 0x8007000D Not sure if it was disabling of UAP or installing D-tools that made this thing happen...

  • [Vista] ATI Drivers for Vista Beta 2

    Found this news article (and downloading as I write):

    ATI today released a major update to its first beta generation Windows Vista graphics driver. The Catalyst Beta package fully supports the Vista Display Driver Model (VDDM) and should deliver greater stability than the previous version and allow a better look at Microsoft's AeroGlass user interface.

    The driver published is available in 32-bit and 64-bit versions and supports DirectX9-compatible graphics processors, including the desktop Radeon processors 9500 and higher, the Mobility Radeon 9550 and higher series, the chipsets Crossfire 3200 and Xpress 200 and 200m as well as the workstation cards FireGL V3100 and higher and FireMV 2200 PCIE and higher.

    EDIT: For some reason that I don't know, I cannot get any higher resolution than 1280 x 1024 on my 19' flat screen, which is no improvement over the drivers which were installed from start.

  • [Vista] Some Things Work - Others Don't

    I decided to be brave and installed Vista Beta 2 on my home computer. Because you have to format the C-drive, I made a huge, fresh backup of most of my files and went ahead with the install. Vista installed fine and started up OK with a few issues:

    My ATI Radeon X850 XT gets a maximum of 1280 x 1024 - I will look for new drivers and see if that helps.

    My Sound Blaster Audigy 2 zs refuse works...almost. I can use the front panel in- and output, but the output from the card on the back of the computer doesn't work at all. I'm currently running my sound via earphones from the front output... I have to investigate this further.

    None of the Daemon Tools versions I've tried so far seems to work properly, which is a disaster because I got most software and backups saved as Images. IsoBuster got me going, but it's not as good as Daemon Tools (which I just luuuuuv).

    I had some problems getting DNS lookups to work for some reasons. I could get to almost all webbsites except a few really important ones (like ms.com, google etc), which were pretty weird. I'm connected to the Internet via a router/firewall and have automatic IP configuration set up. I thought maybe it had something to do with IP6 or something so I just added my ISP DNS servers straight into the network settings and I've had no problems since then.

    When the computer goes into Sleep mode and I want to start from it, it seems to hang in startup and I have to power off  fully and press the power button again. When it starts up, it revovers from the hibernate mode, which seems to work well. Not sure why it cannot get going from Sleep mode but I'll have to investigate.

    Other than that - performance is great, file copying seems to be faster than in XP (!), but maybe that was because I used a really crappy AV software. Someone blogged about some AV which worked with Vista... Ah here it is, blogged by Kristan Kenney on DigitalFile.

    (All of a sudden the Media Player 11 stopped playing in a middle of a song... maybe it doesn't like David Bowie :o) I like the way Media Player 11 minimize to the system tray... I think. It takes up quite some space down there actually...

    What else is there to say... it will take some getting used to the new File Explorer though, but I think it will work out pretty well. The Windows Sidebar is something I will explore some more - I'm thinking of developing a couple of (hopefully) useful Gadgets just for fun if nothing else. The CPU/Mem meter is just beautiful, and the RSS feed viewer is pretty cool.

    Oh, and all these security allowance elevation dialog thingys which keeps poping up all the time you want to start/remove/change stuff will have to go. If you've decided to be local admin on your box you don't want to keep saying yes, Yes, YES, YAHHH DARNIT! all the time. Once should be enough :)

  • [Vista] What does Vista do when it Sleeps?

    I have to say the new "power button" which puts Vista into the new "Sleep" mode seems nice. My 2 Ghz laptop (which doesn't have much on it yet I must admit) goes to sleep in 1 second and starts up in pretty much the same time. Superfast - I like it.

    As I understand it, by default a laptop is put into sleep mode when the power button is pressed, then goes into hibernate (saves memory to disk) after a few hours or so, to save power. When resuming from hibernate it takes a bit longer for the box to get going, but that's understandable. It's possible to configure what happens when you press the power button or close the lid, also depending on if you're on battery or plugged in.

    You can read more of what Vista does when it's in sleep mode on the Microsoft Vista Performance pages.

  • [Ajax] GWT - Google Web Toolkit

    Related to what I wrote in my previous post about Script#, there is already GWT - Google Web Toolkit, which does something similar but with Java. You write your front end in the Java language, and the GWT compiler converts the code into JavaScript and HTML.
  • [Ajax] Check Out the Script# Prototype

    This should interest all of you who are into AJAX, Atlas and that kind of stuff no the ASP.NET platform - Nikhil (who is an architect on the Web Platform and Tools team at Microsoft) releases a prototype of a C# to Javascript/Ajax compiler and looks for feedback:

    Script# brings the C# developer experience (programming and tooling) to Javascript/Ajax world. This post shares a prototype project for enabling script authoring via C#...

    Check it out - Nikhil also got a video to explain how it works.

  • Stylish Quotes in Blog Posts

    I found a few CSS tips and tricks to format (in my view) prettier quotes in your blog posts. For example:

    This is a quote.


    For the above, I added this CSS:

    blockquote {
      background: transparent url(quoleft.png) left top no-repeat;
    }

    If you want to add a closing quote to it as well, add this:

    blockquote p {
      padding: 0 48px;
      background: transparent url(quoright.png) right bottom no-repeat;
    }

    If you use <P> inside the quote, you may get additional quote signs, so use a couple of <BR /> instead.

  • [Vista] Is Sami the Default Swedish Language?

    I had heard about this before, but someone had also said it was going to be fixed for beta 2. Looks like it wasn't because when I selected Sweden as my region, it defaulted to Sami, Lule (Sweden) as language :)

    There were actually 3 different Sami dialects available; Lule, Northern and Southern, which is amazing in itself. I had no idea we had all these different versions of the Sami language... I can't remember seeing Finnish in that list though, but it should be.

    Overall, the installation went really smooth, but I'm installing on the bare metal here, and not in VPC or Virtual Server. Graphic is stunning...

  • [Vista] Beta 2 Available on MSDN Subscription

    Guess I'm not the first to notice, but beta 2 of Vista is available for download to MSDN subscription owners. 3200 MB ISO :)

    EDIT: There still (day after release) seems to be a problem with generating license keys for any other Vista version than the premium home edition. I guess we'll have to check back on the MSDN Subscription page every now and then and see if it gets fixed.

  • Copy Code and Paste as HTML From VisualStudio 2005

    There are 100's of macros and add-ins and plug-ins doing this, but I got this one from "CodingHorror" installed and configured an ALT-C shortcut to copy the code as HTML. It's a manual installation process, but it's good enough for me.

    Now why VS 2005 doesn't ship with a proper copy/paste functionality is something I don't really understand. But it gives a whole lot of happy late-nighters a chance to whip up something useful on their own :)

  • [.NET 2.0] Testing Generics, Collections and Yield Return

    I've not looked too much at the yield return statement in c# 2.0 yet, but if you learn how to use it I'm sure it will become something you use "every day" when programming. Whenever you need to do some conditional iterations on a collection, array or list, yield may be a nice solution to go for. A few, silly and not perfect, snippets which helped me understand how to use yield return:

    using System;
    using System.Collections;
    using System.Collections.Generic;

    public class Program
    {

        
    static void Main()
        {
            // Build up a few arrays and a list to work with
            
    string[] names = { "Johan", "Per", "Thomas", "Lina", "Juan", "Jan-Erik", "Mats" };
            
    int[] values = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
            
    List<int> list = new List<int>();
            list.Add(1);
            list.Add(2);
            list.Add(3);
            list.Add(4);

            
    Console.WriteLine("Get the names which contains an 'a':");

            
    // Iterate on all names which contains letter 'a'
            foreach (string name in EnumerableUtils<string>.GetNamesContainingLetter(names, 'a'))
            {
                
    Console.Write("{0} ", name);
            }
            
    Console.WriteLine();
            
    Console.WriteLine();

            
    //iterate through first half of this collection
            Console.WriteLine("First half of the name-array:");
            
    foreach (string name in EnumerableUtils<string>.GetFirstHalfFromList(names))
            {
                
    Console.Write("{0} ", name);
            }
            
    Console.WriteLine();
            
    Console.WriteLine();

            
    //iterate through first half of another collection
            Console.WriteLine("First half of the value-array:");
            
    foreach (int value in EnumerableUtils<int>.GetFirstHalfFromList(values))
            {
                
    Console.Write("{0} ", value);
            }

            
    Console.WriteLine();
            
    Console.WriteLine();

            
    //iterate through first half of a List
            Console.WriteLine("First half of the value-list:");
            
    foreach (int value in EnumerableUtils<int>.GetFirstHalfFromList(list))
            {
                
    Console.Write("{0} ", value);
            }
            
            
    Console.WriteLine();
        }
    }

    public class EnumerableUtils<T>
    {
        
    public static IEnumerable GetNamesContainingLetter(string[] names, char letter)
        {
            
    foreach (string name in names)
            {
                
    if (name.ToLower().Contains(letter.ToString().ToLower()))
                    
    yield return name;
            }
        }

        
    public static IEnumerable<T> GetFirstHalfFromList(List<T> arr)
        {
            
    for (int i = 0; i < arr.Count / 2; i++)
                
    yield return arr[i];
        }

        
    public static IEnumerable<T> GetFirstHalfFromList(T[] arr)
        {
            
    for (int i = 0; i < arr.Length / 2; i++)
                
    yield return arr[i];
        }
    }

  • Martin Fowler on Ruby

    Martin Fowler just blogged a pretty long post on his view on Ruby. I don't want to ruin the reading for you but it ends with:

    But overall I'm increasingly positive about using Ruby for serious work where speed, responsiveness, and productivity are important.

    :)

    Personally I've managed to install Rails and went through some tutorials. Not enough for me to give it a verdict.

  • [.NET 2.0] Quick Way of Closing VisualStudio Files

    If you end up having a zillion files opened in the VisualStudio 2005 IDE and want to close a few of them, just click with the MIDDLE mouse button on their tabs where you see the filename. Quick and easy.

  • [.NET 2.0] Visual Studio 2005 Web Application Project V1.0 Released

    From the Visual Studio 2005 Web Application Project webby:

    Today we released the V1.0 release of the VS 2005 Web Application Project option. You can learn about it here, and download it here.

    You should then check out the tutorials on this site to learn more about it and how to use it. You might also want to keep an eye on my blog -- where I'll be posting updates about it regularly.

    This forum is the best place to ask questions or get get answers about the VS 2005 Web Application Project option.

  • [Ajax] Check Out the "Atlas" Control Toolkit

    You may want to look at the "Atlas" Control Toolkit site where they have a list of cool samples of what you can do with it, and it's dead simple. You can probably live without some of the controls, but some of them are quite useful and you would have to spend quite some time to achieve the effects you get for free. My favos on that list are the CollapsiblePanel and the TextBoxWatermark.

    Some may argue that these controls have nothing to do with Ajax, but Ajax has become synonymous with a rich UI, and this is what "Atlas" gives you for sure.

  • How to Play Go

    I'm learning how to play Go, the old boardgame. Easy to learn, but hard to master. This is a pretty good web site with introduction to the game, and some interactive training -> http://playgo.to/interactive/
  • Windows Defender

    If you don't have it installed yet you should consider it. I have been running the Anti Spyware beta from Microsoft for quite some time now, and today it automatically updated itself to Windows Defender Beta 2. This program has been quite helpful with protecting my kids' computers. The young ones doesn't always know what is harmful to their boxes or not. I've told them "if you see a big pupup with a spyware warning in the right corner - let me know at once" :)

    About Windows Defender:

    Windows Defender (Beta 2) is a free program that helps protect your computer against pop-ups, slow performance, and security threats caused by spyware and other unwanted software. It features Real-Time Protection, a monitoring system that recommends actions against spyware when it's detected, and a new streamlined interface that minimizes interruptions and helps you stay productive.

  • [.NET 2.0] Visual Studio 2005 Web Application Project - Old Skool

    My thanks to ScottGu who commented on my earlier blog post about checking out the Visual Studio 2005 Web Application Project, which gives you Old Skool style of working with ASP.NET applications. I'm sure lots of people (like me) prefer the way it used to work. Whole thing with teaching old dogs... Snip from the site:

    The Visual Studio 2005 Web Application Project Model is a new web project option for Visual Studio 2005 that provides the same conceptual web project approach as VS 2003 (a project file based structure where all code in the project is compiled into a single assembly) but with all the new features of VS 2005 (refactoring, class diagrams, test development, generics, etc) and ASP.NET 2.0 (master pages, data controls, membership/login, role management, Web Parts, personalization, site navigation, themes, etc).

  • [.NET 2.0] Using Web Deployment Projects with Visual Studio 2005

    Got a tip from a friend to have a look at this page on the MSDN webby about different web deployment options with VS.NET 2005. Snippet from that page:

    Visual Studio 2005 provides deployment support though its Copy Web Site and Publish Web Site features. While these are ideal for many scenarios, there are other, more advanced scenarios where developers need the following capabilities:

      • More control over assembly naming and output.
      • Custom pre-processing and post-processing for the build.
      • The ability to exclude, add, and transform files and directories during builds.
      • The ability to modify the Web.config file to change database connection strings, application settings, or the URLs for Web references, depending on the build configuration. (For example, it might be necessary to use different values for development, test, staging, and release settings).
    This white paper describes a solution to these advanced scenarios and introduces a new feature called Web Deployment Projects for Visual Studio 2005.

    There is a VS.NET plugin available on that page with the following features for building ASP.NET 2.0 web sites:

    • ASP.NET 2.0 precompilation as part of the build process.
    • More flexible options for generating compiled assemblies from a Web project, including these alternatives:
      • A single assembly for the entire Web site.
      • One assembly per content folder.
      • A single assembly for all UI components.
      • An assembly for each compiled file in the Web site.
    • Assembly signing options.
    • The ability to define custom pre-build and post-build actions.
    • The ability to exclude folders from the build.
    • The ability to modify settings in the Web.config file, such as the <connectionString> element, based on the Visual Studio build configuration.
    • Support for creating .msi files with setup projects.

    The extensibility of Web Deployment projects enables you to tailor the build and deploy process to suit your needs. This is done without sacrificing the optimized workflow improvements achieved with Visual Studio 2005 Web site projects.

    I still have to read the whole page myself and try out the add-in. Looks interesting and useful though.
  • [.NET 2.0] Writing Your Own Provider

    Being intrigued by the provider system, I though I would spend some time on the excellent Provider Toolkit page on MSDN to see if I could understand how to write your own provider. From scratch that is, not based on the membership stuff.

    I found this great page, which describes how to write an SqlImageProvider from ground up. The sample code on the page got some errors in it, but I got it working eventually, and it's just amazing. I'll write another really simple provider and post the code here soon.

    I'm thinking what I could use the provider system for... perhaps if you wanted to construct a system where you know you would start using Access or even XML files, then at a later state move to SQL or Oracle. You could write the whole interface to your DAL as a provider... perhaps a bit too much code to be funny, but it could work. Each method would have to be written at least three times - once for the base, once for the service and of course once for the concrete provider where you would probably use whatever helper classes you got to actually manage the data. Oh well...

  • [.NET 2.0] Taking a Web App Offline

    This is a neat feature of ASP.NET 2.0 I just found out about. Loads of people have already written about it, but it's so useful that I decided to put it on my blog as well. By placing a file called 'app_offline.htm' in the root directory of your web app, no ASP.NET dynamic pages are no longer served. The web server returns the content of that file instead. This is what ScottGu wrote about this feature on his blog:

    Basically, if you place a file with this name in the root of a web application directory, ASP.NET 2.0 will shut-down the application, unload the application domain from the server, and stop processing any new incoming requests for that application.  ASP.NET will also then respond to all requests for dynamic pages in the application by sending back the content of the app_offline.htm file (for example: you might want to have a “site under construction” or “down for maintenance” message).

    This provides a convenient way to take down your application while you are making big changes or copying in lots of new page functionality (and you want to avoid the annoying problem of people hitting and activating your site in the middle of a content update).  It can also be a useful way to immediately unlock and unload a SQL Express or Access database whose .mdf or .mdb data files are residing in the /app_data directory.

    Once you remove the app_offline.htm file, the next request into the application will cause ASP.NET to load the application and app-domain again, and life will continue along as normal.

    You may want to read all the comments to this blog entry, some interesting conversation there.

    I just happened to stumble upon this feature when I was publishing my web app directly from within VisualStudio (Build->Publish...), because VS automatically places that file in the web app during upload of the new files. Neat. What is not so neat is that VS didn't remove the app_offline.htm file once it was done publishing :) Maybe it was because I was publishing to an FTP site... not sure. Will try again some other time.

  • [Books] Professional ASP.NET 2.0? Naaaah...

    Every now and then I like to read literature related to coding, design, refactoring and various development methodologies, especially when I know there's something new out there that I haven't been able to work with or look at yet.

    This time I thought I'll get myself a really fat and heavy book on ASP.NET 2.0 which digs into the changes between 1.1 and 2.0 and some tips on how to best use the goodies like new controls, membership, web parts and so on. Without doing too much investigation, I used the Internet book-shop I usually use and did a search on "ASP.NET 2.0". I got a number of hits and selected "Professional ASP.NET 2.0" from Wrox. The book is supposed to help "experienced developers make the transition to ASP.NET 2.0".

    I should have read some reviews I guess... it was kind of a bad buy it seems. 1258 pages (!) and the book doesn't even bring up how to hide menu items based on a web.sitemap file by editing the sitemap provider section in web.config. Something this great video on the MS ASP.NET Developer Center shows. One reason the book is so thick is probably because each code sample is in both VB.NET and C# and you also get page after page with class properties. I dunno, but Wrox got a separate ASP.NET 2.0 book on security, roles and stuff, maybe they brought it up there. I may have had bad luck with the sitemap provider thing I was looking for, but there were other things I needed that were missing as well. I can't say I've looked at ALL thousand or more pages, but...

    EDIT: Gah... Page 86 in the book describes how you can use precompile.axd to precompile the website. Well, that function was removed after beta 1 as far as I know. Not very impressive...

    The book do have some samples around client-side callbacks which were good, but overall I wouldn't recommend it.

  • [.NET 2.0] How to get Selected-events from an ASP.NET 2.0 TreeView Control using a Web.SiteMap File

    The new ASP.NET 2.0 TreeView control looks neat, and it's very simple to use in conjunction with a web.sitemap file. I spent some time on it yesterday but there were a few things the TreeView control and I never could agree on. For example, when using a TreeView Control in conjunction with a .sitemap file (via the SiteMapDataSource), you cannot get any selection events to fire at all because the treeview is in navigation mode.

    Good news is that it is not impossible to work around it, but it took me a while to figure out, and not without some serious help from Google... The trick is to get the TreeView in selection mode instead of navigation mode. For that to happen, the NavigateUrl property for the node has to be an empty string (""). So, what you have to do is to manually edit the TreeNode DataBindings of the TreeView control and add som code to control the redirection to the right page or else you will stay on the same page forever :)

    From start:

    1. Create your web.sitemap file
    2. Optionally - create your master-page where you want your treeview and breadcrumb controls to sit
    3. Drag/drop a TreeView Control onto the page
    4. Set the ExpandDepth to whatever depth you like 
    5. Choose a new datasource and select a Site Map (the control should now display your nodes from the web.sitemap file)
    6. Select to Edit TreeNode DataBindings
    7. Mark the SiteMapNode from the list of available data bidings and Add it as a selected data binding
    8. Uncheck the Auto-generate data bindings checkbox, we don't need it
    9. Edit the SiteMapNode properties:
      1. Set the TextField to 'Title'
      2. Set the ValueField to 'Url'
      3. Optionally - set any default parameters you like
    10. Finally, add the SelectedNodeChanged event for the TreeView Control and some code in that event to redirect to the right page:

    protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)

    {

        Response.Redirect(TreeView1.SelectedNode.Value, "false");

    }

    This is a sample of how the TreeView code in the ASPX page could look like:

    <asp:TreeView ID="TreeView1" runat="server" AutoGenerateDataBindings="False" DataSourceID="SiteMapDataSource1"

        PopulateNodesFromClient="False" ImageSet="WindowsHelp" OnSelectedNodeChanged="TreeView1_SelectedNodeChanged">

        <DataBindings>

            <asp:TreeNodeBinding DataMember="SiteMapNode" TextField="Title" ValueField="Url" />

        </DataBindings>

        <ParentNodeStyle Font-Bold="False" />

        <HoverNodeStyle Font-Underline="True" ForeColor="#6666AA" />

        <SelectedNodeStyle BackColor="#B5B5B5" Font-Underline="False" HorizontalPadding="0px"

            VerticalPadding="0px" />

        <NodeStyle Font-Names="Tahoma" Font-Size="8pt" ForeColor="Black" HorizontalPadding="5px"

            NodeSpacing="0px" VerticalPadding="1px" />

    </asp:TreeView>

     

    Now if you try out your web site, the SelectedModeChanged event should fire. One big drawback with this piece of code is that now the treeview fires a PostBack event and you have to add the extra Response.Redirect() to get to the right page. Without the redirect the treeview won't be able to automatically detect which page you're on and render the treeview accordingly.

    If you want to add a breadcrumb (SiteMapPath) to the page, just drag/drop it in there. It works out of the box.

  • [.NET 2.0] Membership and Personalization Provider for Access Database

    Not sure why vs2005 didn't ship with providers for Access databases, but Access is quite useful if you want to develop small and simple websites and do not have access to SQL Server or similar. I run a small website hosted by an ISP and even though they support ASP.NET 2.0, I don't have access to SQL Server.

    A sample Access provider is available for download on the MSDN ASP.NET Developer Center section with Provider Toolkit information. I've tried it, and it seems to work good enough for my needs. I'm having some troubles writing to the database under IIS on Windows 2000, even if I set all the security and permission stuff as it should be. Well, as long as it works under Cassini and on my website I don't care :)

    EDIT: Stupid me, even though I had set access rights and permissions on all folders down to APP_DATA, the MDB-files still had the old permissions set on them. I explicitly gave the ASPNET user write access to the file and now it works like a charm :)

  • Virtual Server 2005 R2 Enterprise Edition for Free

    If you by chance missed it - look here for details.Snip from the download page:

    The full software for 32-bit and 64-bit versions is available as a free download. Register to pre-order a CD (available May 2006) or to download the full software.

    Go get it already :)

  • WS-Transfer - Are We Talking HTTP Over XML Over HTTP?

    I may be daft, but after reading the comments on WS-Transfer submission to the W3C, I get the feeling that WS-Transfer feels... I dunno, wrong? I know SOAP is transport independant, but a vast majority of the SOAP calls are made over HTTP, so are we talking HTTP over XML/SOAP over HTTP?

    WS-Transfer is about doing resource manipulation, using HTTP-like verbs such as GET, PUT, DELETE and such. Feels like a more complex REST style of managing resources to me.

  • Building Web Services the REST Way

    There is much talk at the moment about REST, what is it and not is, Lo-REST, Hi-REST and whatnot. For those of you who don't really know what REST is and don't have time (or like me, not the brain) to delve into Fielding's full REST description, Roger L. Costollo wrote a short piece called Building Web Services the REST Way, which I think is pretty good. Some of you will recognize the REST style from XML on HTTP solutions you did 5-6 years ago, before the dawn of the SOAP and ROPE...

    It seems to me that some people think Microsoft is not supporting HTTP/XML/REST the way it should. If you want to get updated on the matter, go to Don's blog and Jonnay's blog (Sacrificial Rabbit) and start to read. 

  • Factory Factory Factory...

    From last year, but so true and very funny - BenjiSmith wrote a story around why he hates frameworks.

    I'm currently in the planning stages of building a hosted Java web application (yes, it has to be Java, for a variety of reasons that I don't feel like going into right now). In the process, I'm evaluating a bunch of J2EE portlet-enabled JSR-compliant MVC role-based CMS web service application container frameworks.

    And after spending dozens of hours reading through feature lists and documentation, I'm ready to gouge out my eyes.

    I know exactly what he means :D

     

  • RSS Toolkit Update

    MSDN blogger Dmitryr made a minor update to his excellent RSS toolkit:

    I am posting a minor update to the ASP.NET RSS Toolkit (version 1.0.0.1).  It contains changes made in response to the feedback I received -- I'd like to thank everyone for their comments and suggestions!

    Check it out.

  • [Vista] Vista VPC File Size

    If someone's interested - the size of the virtual hard drive after installing Vista + VMAdditions is around 8 GIG. I could try to shrink the file size, but I guess it wouldn't help much. Seems pretty hard to copy it to a 4.7 GB DVD then...
  • [Vista] Testing Vista Feb CTP on VirtualPC

    Today I installed the Feb CTP of Vista on my box at home, under VPC. The install was noticably faster than before, but even so took about an hour I think. I went out for a while, enjoying the spring sun, so I'm not sure exactly how long the install took.

    After reading some advice on the Net, I installed the VMAdditions from the Virtual Server R2 program instead of the additions included in VPC. I don't know much of the difference, but performance in Vista is good enough to give it a real go. Just missing the Glass effects and sound is not working, but these are known issues.

    The only thorn in my side right now is that I cannot get networking to work. I've seen some problems related to NAT and such, but I have to read up on it to see if it is related to my problems.

  • [Vista] Virtual Vista Bloggers

    An excellent way to test out a new operating system like Vista is to run it in a virtual machine, but some people run into problems installing and getting good performance out of it. The last days I've been reading posts from these two guys on the topic - Mikekol runs a blog called "Virtual Vista" which has several good posts about Vista on VPC and Virtual PC Guy blogs about... yes you guessed it!

  • [Java] Testing SOAP Headers with a Simple Axis Handler

    This is not a tutorial, but just some sharing of my brief learnings when testing a simple Axis Handler (somewhat similar to ASP.NET Soap Extensions). I wrote 2 programs - one simple web service client as a Java console program and one web service. The client calls a web service method called test() but adds a simple SOAP header containing a username and a password. The web service has a BasicHandler, defined in the deployment descriptor as a request handler, which checks each request and makes sure it contains the correct SOAP header with the correct username and password. The handler also sets the validated username in a ThreadLocal variable, which is then picked up by the web service method. If the request does not contain the correct SOAP header, username and password, a fault is thrown.

    There are several ways for the handler class to set data which can be picked up by the web service method, and I know there is a debate going on around the use of ThreadLocals, but I thought it could be useful in this particular case.

    I don't think it matters much which version of Axis you use, but I went for Axis version 1.3. Note that this is test-code, not tested for production. If you find something smelly in the code, I would love to hear about it. Another note is the way I build up the SOAP header and my somewhat sloppy usage of XML namespace. I know it can be done much better, but the intention was to test the handler code :)

    Note that the web service client code is auto-generated from the WSDL and I've not bothered to show the code for it here.

    First, the client code:

    package test;

    import org.apache.axis.message.*;

    public class MyClient {

     public static void main(String[] args) {
     
      System.out.println("Hello, this is the client!");
     
      MyServiceServiceLocator wsloc = new MyServiceServiceLocator();
     
      SOAPHeaderElement oHeaderElement;
      javax.xml.soap.SOAPElement oElement;
      MyServiceSoapBindingStub ws;
     
       try {
        ws = (MyServiceSoapBindingStub)wsloc.getMyService();

        oHeaderElement = new SOAPHeaderElement("http://test",
         "securityHeader");
        oHeaderElement.setPrefix("sec");
        oHeaderElement.setMustUnderstand(false);
        oElement = oHeaderElement.addChildElement("username");
        oElement.addTextNode("johan");
        oElement = oHeaderElement.addChildElement("password");
        oElement.addTextNode("secret");
         
        ws.setHeader(oHeaderElement);
        System.out.println(ws.test());
       } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
     
     }

    }


    Then, the web service code (most comments and javadoc removed):

    package test.service;

    import test.service.handler.MyHandler;

    public class MyService
    {
     public String test()
     {
      String username = MyHandler.getUsername();
      MyHandler.setUsername(null); //clean up
     
      return "Hello from Service! User is = " + username;
     }
    }

    Finally, the Handler code looks something like this:

    package test.service.handler;

    import org.apache.axis.AxisFault;
    import org.apache.axis.Message;
    import org.apache.axis.MessageContext;
    import org.apache.axis.handlers.BasicHandler;

    import java.util.Iterator;

    import javax.xml.soap.SOAPException;
    import javax.xml.soap.SOAPHeader;
    import javax.xml.soap.SOAPHeaderElement;

    import org.apache.axis.message.SOAPEnvelope;

    /**
     * Simple Axis handler which looks for a SOAP header
     * containing two elements - username and password. Invoke() method
     * checks these...
     *
     * @author Johan Danforth
     */
    public class MyHandler extends BasicHandler {

     private static final long serialVersionUID = 1L;
     private static ThreadLocal _username = new ThreadLocal();

        public static String getUsername() {
            return ((String) (_username.get())).toString();
        }
       
        public static void setUsername(String value) {
            _username.set(value);
        }
     
     /**
      * Method called by Axis handler, checks SOAP header with
      * username and password.
      *
      * @throws AxisFault if header is missing or invalid or wrong username or password
      */
     public void invoke(MessageContext msgContext) throws AxisFault {

      boolean processedHeader = false;
     
      try {
       Message msg = msgContext.getRequestMessage();
       SOAPEnvelope envelope = msg.getSOAPEnvelope();
       SOAPHeader header = envelope.getHeader();
       Iterator it = header.examineAllHeaderElements();
       SOAPHeaderElement hel;
      
       while (it.hasNext()) {
        hel = (SOAPHeaderElement) it.next();
        String headerName = hel.getNodeName();
        if(headerName.equals("sec:securityHeader"))
        {
         checkUsername(hel);
         processedHeader = true;
        }
       }
      } catch (SOAPException e) {
       //capture and wrap any exception.
       throw new AxisFault("Failed to retrieve the SOAP Header or it's details properly.", e);
      }

      if(!processedHeader)
       throw new AxisFault("Failed to retrieve the SOAP Header");
     
     }

     private void checkUsername(SOAPHeaderElement hel) throws AxisFault {
      String username = getUsername(hel);
      String password = getPassword(hel);
     
      if(!(username.equals("johan") && password.equals("secret")))
      {
       throw new AxisFault("Access Denied");
      }
      else
      {
       //set username as threadlocal variable
       _username.set(username);
      }
     }

     private String getPassword(SOAPHeaderElement hel) throws AxisFault {
      org.w3c.dom.Node passwordNode = hel.getLastChild();
      String nodename = passwordNode.getNodeName();
      if(!nodename.equals("sec:password"))
       throw new AxisFault("Missing password element in SOAP header.");
      String password = passwordNode.getFirstChild().getNodeValue();
      System.out.println("password = " + password);
      return password;
     }

     private String getUsername(SOAPHeaderElement hel) throws AxisFault {
      org.w3c.dom.Node usernameNode = hel.getFirstChild();
      String nodename = usernameNode.getNodeName();
      if(!nodename.equals("sec:username"))
       throw new AxisFault("Missing username element in SOAP header.");
      String username = usernameNode.getFirstChild().getNodeValue();
      System.out.println("username = " + username);
      return username;
     }
    }


    I need to share with you the deployment descriptors and the web.xml as well. I run the Axis Servlets in the same web app as my web service code. It's up to you how you prefer to do it really. I thought it was easier this way when I used the latest version of Eclipse. That's why the web.xml is full of Axis stuff and I'm using a separate server-config.wsdd instead of registering the service through the Axis admin tool pointing at a separate deploy.wsdd file. I'm attaching a sample deploy.wsdd file as well, just in case someone is unfamiliar with the server-config file.

    My web.xml looks like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_ID" version="2.4" xmlns="
    http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
     <display-name>
     HelloWorld2</display-name>
     <servlet>
      <display-name>
      Apache-Axis Servlet</display-name>
      <servlet-name>AxisServlet</servlet-name>
      <servlet-class>
      org.apache.axis.transport.http.AxisServlet</servlet-class>
     </servlet>
     <servlet>
      <display-name>
      Axis Admin Servlet</display-name>
      <servlet-name>AdminServlet</servlet-name>
      <servlet-class>
      org.apache.axis.transport.http.AdminServlet</servlet-class>
      <load-on-startup>100</load-on-startup>
     </servlet>
     <servlet-mapping>
      <servlet-name>AxisServlet</servlet-name>
      <url-pattern>/servlet/AxisServlet</url-pattern>
     </servlet-mapping>
     <servlet-mapping>
      <servlet-name>AxisServlet</servlet-name>
      <url-pattern>*.jws</url-pattern>
     </servlet-mapping>
     <servlet-mapping>
      <servlet-name>AxisServlet</servlet-name>
      <url-pattern>/services/*</url-pattern>
     </servlet-mapping>
     <servlet-mapping>
      <servlet-name>AdminServlet</servlet-name>
      <url-pattern>/servlet/AdminServlet</url-pattern>
     </servlet-mapping>
     <welcome-file-list>
      <welcome-file>index.html</welcome-file>
      <welcome-file>index.htm</welcome-file>
      <welcome-file>index.jsp</welcome-file>
      <welcome-file>default.html</welcome-file>
      <welcome-file>default.htm</welcome-file>
      <welcome-file>default.jsp</welcome-file>
     </welcome-file-list>
    </web-app>


    My server-config.wsdd looks like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <deployment xmlns="
    http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
     <globalConfiguration>
      <parameter name="sendMultiRefs" value="true"/>
      <parameter name="disablePrettyXML" value="true"/>
      <parameter name="adminPassword" value="admin"/>
      <parameter name="attachments.Directory" value="C:\Java\eclipse\workspace\HelloWorld2\.deployables\HelloWorld2\WEB-INF\attachments"/>
      <parameter name="dotNetSoapEncFix" value="true"/>
      <parameter name="enableNamespacePrefixOptimization" value="true"/>
      <parameter name="sendXMLDeclaration" value="true"/>
      <parameter name="sendXsiTypes" value="true"/>
      <parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
      <requestFlow>
       <handler type="java:org.apache.axis.handlers.JWSHandler">
        <parameter name="scope" value="session"/>
       </handler>
       <handler type="java:org.apache.axis.handlers.JWSHandler">
        <parameter name="scope" value="request"/>
        <parameter name="extension" value=".jwr"/>
       </handler>
      </requestFlow>
     </globalConfiguration>
     <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
     <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
     <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
     <service name="AdminService" provider="java:MSG">
      <parameter name="allowedMethods" value="AdminService"/>
      <parameter name="enableRemoteAdmin" value="true"/>
      <parameter name="className" value="org.apache.axis.utils.Admin"/>
      <namespace>http://xml.apache.org/axis/wsdd/</namespace>
     </service>
     <service name="Version" provider="java:RPC">
      <parameter name="allowedMethods" value="getVersion"/>
      <parameter name="className" value="org.apache.axis.Version"/>
     </service>
     <service name="MyService" provider="java:RPC" style="wrapped" use="literal">
      <operation name="test" qname="ns3:test" returnQName="ns3:testReturn" returnType="xsd:string" soapAction="" xmlns:ns3="
    http://test" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>
      <parameter name="allowedMethods" value="test"/>
      <requestFlow>
       <handler type="java:test.service.handler.MyHandler">
        </handler>
      </requestFlow>
      <parameter name="typeMappingVersion" value="1.2"/>
      <parameter name="wsdlPortType" value="MyService"/>
      <parameter name="className" value="test.service.MyService"/>
      <parameter name="wsdlServicePort" value="MyService"/>
      <parameter name="schemaQualified" value="
    http://test"/>
      <parameter name="wsdlTargetNamespace" value="
    http://test"/>
      <parameter name="wsdlServiceElement" value="MyServiceService"/>
     </service>
     <transport name="http">
      <requestFlow>
       <handler type="URLMapper"/>
       <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
      </requestFlow>
      <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
      <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
      <parameter name="qs.list" value="org.apache.axis.transport.http.QSListHandler"/>
      <parameter name="qs.method" value="org.apache.axis.transport.http.QSMethodHandler"/>
      <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
      <parameter name="qs.wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
     </transport>
     <transport name="local">
      <responseFlow>
       <handler type="LocalResponder"/>
      </responseFlow>
     </transport>
    </deployment>


    A sample deploy.wsdd could look like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Use this file to deploy some handlers/chains and services      -->
    <!-- Two ways to do this:                                           -->
    <!--   java org.apache.axis.client.AdminClient deploy.wsdd          -->
    <!--      after the axis server is running                          -->
    <!-- or                                                             -->
    <!--   java org.apache.axis.utils.Admin client|server deploy.wsdd   -->
    <!--      from the same directory that the Axis engine runs         -->
    <deployment xmlns="
    http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

      <service name="MyService" provider="java:RPC" style="wrapped" use="literal">
          <parameter name="wsdlTargetNamespace" value="
    http://test"/>
          <parameter name="wsdlServiceElement" value="MyServiceService"/>
          <parameter name="schemaQualified" value="
    http://test"/>
          <parameter name="wsdlServicePort" value="MyService"/>
          <parameter name="className" value="test.service.MyService"/>
          <parameter name="wsdlPortType" value="MyService"/>
          <parameter name="typeMappingVersion" value="1.2"/>
          <operation xmlns:operNS="
    http://test" xmlns:retNS="http://test" xmlns:rtns="http://www.w3.org/2001/XMLSchema" name="test" qname="operNS:test" returnQName="retNS:testReturn" returnType="rtns:string" soapAction="">
          </operation>
          <parameter name="allowedMethods" value="test"/>
      <requestFlow>
       <handler type="java:test.service.handler.MyHandler">
        </handler>
      </requestFlow>
      </service>
    </deployment>

     

  • Help needed - Trying to use w.Bloggar with .Text

    Looking for a blog-tool that supports the metablogapi interface I turned to w.Bloggar. I'm pretty sure I set it up properly with host names, URL to the api, proxy and all the stuff, but when I click the "Finish" button it hangs for a while and returns a "timeout" error message. Could be our proxy server here, but I've not had problems with that before. The metablogapi URL is correct, and I've activated it in my config and everything, so it should work...

    Anyone else having this problem? Or can you recommend some other offline blog tool, preferably integrated with IE?

    Thanks!

    UPDATE: I tried the same thing back home on my WinXP box, and it works perfect there of course... I guess my problems at work has to do with either the Win2k platform or the proxy server. I'll have to look up some other offline blog tool then I guess.

  • File-sharing with Microsoft Max

    If you haven't seen the Max demo or the video on Channel 9 yet, do it. The Max stuff is available for download on http://www.microsoft.com/max as well. As I understand it, you can only share photos so far with Max, but the technology sure lets you share all kinds of data - music, video... I love how Microsoft is making it easier for people to start sharing large data without the need for large ftp accounts :)

    What is Max? This is what the Max-webby says:

    "Microsoft® Codename Max is not like any other product. That's because it's not a product—it's your opportunity to try an exciting new user experience from Microsoft. Max is built on the next-generation WinFX Runtime Components technology that will drive the development of Windows Vista® applications. Today Max lets you make lists of your photos and turn them into beautiful slide shows to share with your family and friends. Tomorrow...who knows?"

    UPDATE: Note that Max is not supported on any of the public Vista builds, so you have to run it om WinXP SP2 it seems. Also, some useful information about Max compatibility with older and newer versions of .NET and WinFX, taken from the Max web:

    At this time, Max supports only the September CTP of the WinFX Runtime Components, which includes a Beta 2 version of the Microsoft .NET Framework.

    What if I have an older version?
    You must uninstall all previous versions of the WinFX Runtime Components and the Microsoft .NET Framework 2.0 Beta before you install Max.

    Note: If you have WinFX Runtime Components Beta 1 installed, you must also remove "Avalon" and "Indigo" via Add and Remove Programs. You should also follow these instructions to remove Windows Workflow Components Beta 1.

    What if I have a newer version?
    At this time Max does not support newer versions of the WinFX Runtime Components or the Microsoft .NET Framework 2.0. Stay tuned for a Max update that will support these versions.

  • Some limitations in Outlook add-ins with VSTO

    I had to code something, so a couple of nights ago I installed "the real" VS2005 and the VSTO toolkit and had a go at it. I've been trying out some Office-coding earlier but it has never been easier than what it is now with the integration with VS.

    The first thing I noticed was the limitations you have for Outlook add-ins, especially if you want to add add or modify the left hand "navigation pane", you know the one with the big buttons on it saying Mail, Calendar, Contacts, Tasks and Notes and so on. As far as I understand it, you can't do it with the VSTO tools alone. Also, it seems pretty impossible to stick your own Windows Form into the big "information pane" where you list and read mails and such, you know where you do all the work. What you *can* do though is bring up a web page and put some HTML in there. Very limited...

    I guess we'll have to wait until someone comes up with a neat trick or wait for Office Outlook 12.

    There are loads of good code samples on the MSDN webby, and I'm currently playing with the My.Blogs DLL and the Outlook add-in for it. Very useful DLL and neat code to look at. Note that the Outlook sample does not include the DLL itself, you need to download that first and copy the DLL into the Outlook add-in solution. Also, if you're surfing through a web proxy, you will have to add this piece of proxy code to all Feed-classes where it says

    client.UseDefaultCredentials = True

    Just add this somewhere next to that statement:

    Dim host As String = "your.proxy.host"

    Dim port As Integer = 8080 'your proxy port

    Dim proxy As WebProxy = New WebProxy(host, port)

    proxy.Credentials = CredentialCache.DefaultCredentials

    proxy.BypassProxyOnLocal = True

    client.Proxy = proxy

    Good luck!