Infosys Microsoft Alliance and Solutions blog

« August 2008 | Main | October 2008 »

September 30, 2008

Part 1: Manage Page level states with VisualStateManager in Silverlight

Silverlight 2.0 Beta 2 introduced the concept of Visual State Manager (VSM). If you haven't checked it out still, here are some articles that will get you started.

VSM not only helps keep the looks and behavior of a control separate, it allows you to manage the various states the control can be in, along with the transitions, in a very clean and effective manner. Though most of the examples online today show this in context of a specific control and working with its control template, there is no reason why this can't be applied to the UserControl itself, i.e. at the Page level. You can very easily create custom states for your page and manage transitions between the states. In fact this can actually help reduce the total animations that you may have to write and also simplify the backend code.

In this two part blog post, I will explain this with a small sample. I am assuming basic understanding of Silverlight animations and VSM as well. In this first part I will explore how you would build an application without VSM and in part 2, create a similar experience but with using VSM. 

Let's start with taking a simplistic case where we will have 3 buttons on my Page which act like menu control.  On clicking a particular button, it will animate downwards, thus showing the active button. We will assume that the rest of the page has content filled up based on which button was clicked. To start with the here's the XAML with 3 buttons in a Grid.

    <Grid x:Name="LayoutRoot" Background="White">

        <Button HorizontalAlignment="Left" Margin="8,8,0,0" x:Name="btn1" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Content="Button 1" Click="btn1_Click">

            <Button.RenderTransform>

                <TransformGroup>

                    <ScaleTransform/>

                    <SkewTransform/>

                    <RotateTransform/>

                    <TranslateTransform/>

                </TransformGroup>

            </Button.RenderTransform>

        </Button>

        <Button HorizontalAlignment="Left" Margin="80,8,0,0" x:Name="btn2" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Content="Button 2" Click="btn2_Click">

            <Button.RenderTransform>

                <TransformGroup>

                    <ScaleTransform/>

                    <SkewTransform/>

                    <RotateTransform/>

                    <TranslateTransform/>

                </TransformGroup>

            </Button.RenderTransform>

        </Button>

        <Button HorizontalAlignment="Left" Margin="150,8,0,0" x:Name="btn3" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Content="Button 3" Click="btn3_Click">

            <Button.RenderTransform>

                <TransformGroup>

                    <ScaleTransform/>

                    <SkewTransform/>

                    <RotateTransform/>

                    <TranslateTransform/>

                </TransformGroup>

            </Button.RenderTransform>

        </Button>

    </Grid>

Next is to add the required animation so that a button can move to the new location. For this we can use Blend and add Button1Animation, which moves the button down. We use the TranslateTransform property and modify the Y value to 40. The animation storyboard is as below.

        <Storyboard x:Name="Button1Animation">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="40"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

While this animation moves the button down, we will need another animation to move the button back to its original position when another button is moved down. To do this, Blend offers an easy way by which we can create a duplicate animation and then reverse it from the Objects and Timeline panel. See the figure below.

duplicate.jpg

Using this approach, we get the Button1Animation_Copy animation.

        <Storyboard x:Name="Button1Animation_Copy">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="40"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

On similar lines we can create additional animations for the other two buttons to move them down and then back up. These are as below. 

        <Storyboard x:Name="Button2Animation">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="40"/>

            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="-72"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

        <Storyboard x:Name="Button2Animation_Copy">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="40"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>

            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="-72"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

        <Storyboard x:Name="Button3Animation">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn3" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="40"/>

            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn3" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="-142"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

        <Storyboard x:Name="Button3Animation_Copy">

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn3" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="40"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>

            </DoubleAnimationUsingKeyFrames>

            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="btn3" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="-142"/>

                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>

            </DoubleAnimationUsingKeyFrames>

        </Storyboard>

The next step is to stitch this together so that when we click a button, it moves down and the one already down moves back to its original position. For this the code will be something like below.

    public partial class Page : UserControl

    {

        enum MenuButton

        {

            None,

            One,

            Two,

            Three

        }

 

        MenuButton _current;

        public Page()

        {

            InitializeComponent();

            _current = MenuButton.None;

        }

 

        private void btn1_Click(object sender, RoutedEventArgs e)

        {

            //if the current button is different than the one clicked, animate it back and then animate this button in

            if (_current != MenuButton.One)

            {

                AnimateOut(_current);

                Button1Animation.Begin();

                _current = MenuButton.One;

            }

        }

 

        private void btn2_Click(object sender, RoutedEventArgs e)

        {

            //if the current button is different than the one clicked, animate it back and then animate this button in

            if (_current != MenuButton.Two)

            {

                AnimateOut(_current);

                Button2Animation.Begin();

                _current = MenuButton.Two;

            }

        }

 

        private void btn3_Click(object sender, RoutedEventArgs e)

        {

            //if the current button is different than the one clicked, animate it back and then animate this button in

            if (_current != MenuButton.Three)

            {

                AnimateOut(_current);

                Button3Animation.Begin();

                _current = MenuButton.Three;

            }

        }

 

        //animate the button back to its original location

        private void AnimateOut(MenuButton btn)

        {

            switch (btn)

            {

                case MenuButton.One:

                    Button1Animation_Copy.Begin();

                    break;

                case MenuButton.Two:

                    Button2Animation_Copy.Begin();

                    break;

                case MenuButton.Three:

                    Button3Animation_Copy.Begin();

                    break;

            }

        }

    }

If you run the application now and click any button, you will see it animate down and the previous button will animate and move back. This concludes part 1. In part 2 we will look at how using VSM, we can simplify this application and reduce the amount of code we have to write.

September 29, 2008

Silverlight 2.0 RC0 Installation

You would already be aware of the release of RC0 of Silverlight 2.0. If not check Scott's blog here. The details on the links for downloading these latest bits can be found in the same blog.

Note that unlike the previous Beta 2, this version doesn't comes with a go live license and if you visit the Silverlight installer page online, you will see that it still points to the earlier Beta 2 version (2.0.30523.8).  

Another aspect that Scott has explained, but may not be clearly understood by all is that this RC0 version will not work with the Blend 2.5 June Preview. It will work with Blend 2.0 SP1 only and if you try to install it with the June or any other beta/preview version you will get an error like below during installation. 

 SLRc0.jpg

Since I wanted to play around with this version, I uninstalled Blend 2.5 June preview and being an MVP, I have access to MSDN Subscriber downloads from where I downloaded and installed Expression Blend. Then I installed Blend SP1 preview (the link is given earlier in the blog) and finally ran the Silverlight RC0 setup (first uninstalled the previous Beta 2 bits).

The setup completed successfully, though initially it took a couple of min to show any update on the "Download Status". In fact for the first few min it didn't budge at all and I started suspecting if there was an issue with the installation package itself. But then it suddenly jumped to 100% and said "Download time remaining: 0:00:00". The installation after this took few more min and finally I was ready to try out SL RC0.

Quick test app creation and I had no issues in running it. The ASPX now shows the version as 2.0.30923. Interestingly if you visit the Silverlight installer page now, it says

"installed version 2.0.30523.9
requested version Silverlight 2 Beta 2 GDR 1 (2.0.30523.8)"

So it fails to recognize the new bits, which is as Scott mentioned in his blog. Let me get going with checking out this release and will share my experiences soon. Keep watching this space.

September 24, 2008

WPF - Displaying enums in ComboBox control

Displaying enums in ComboBox in WPF isn't really rocket science. The issue however comes when you want to display user friendly strings against the enum values. Enum unfortunately doesn't support this by a simple override to the ToString method.

The usual approach people take is the use the DescriptionAttribute. This attribute is assigned to each enum value and at runtime, using reflection, the value of the attribute is queried and is then displayed. The approach is definitely worth considering and I found an implementation of the same and a custom WPF ComboBox that will display such user friendly enum strings here.

However reflection does mean a bit of performance impact and depending on the size of the enum, this can vary. In the above implementation, the values are hence cached for any reuse and improve efficiency. However if the binding happens only once, this has no effect.

I was hence wondering on how to do this without having to use reflection. I then hit upon an idea of using a dictionary object with the enum as the key and the value as the user friendly string. It was then a matter of binding this with the ComboBox and set the DisplayMemberPath appropriately. In order to ensure that the enum and this dictionary collection go hand in hand, I decided to encapsulate them in a single class. There is definitely a maintenance overhead of ensuring that appropriate key value pair is added to the dictionary for each enum. See the code for this class below.

    internal class Utility

    {

        static Utility()

        {

            //initialize the collection with user friendly strings for each enum

            _monthCol = new Dictionary<Months, string>(){

                {Months.Jan, "January"},

                {Months.Feb, "February"},

                {Months.Mar, "March"},

                {Months.Apr, "April"},

                {Months.May, "May"},

                {Months.Jun, "June"},

                {Months.Jul, "July"},

                {Months.Aug, "August"},

                {Months.Sep, "September"},

                {Months.Oct, "October"},

                {Months.Nov, "November"},

                {Months.Dec, "December"}};

 

        }

 

        public enum Months

        {

            Jan,

            Feb,

            Mar,

            Apr,

            May,

            Jun,

            Jul,

            Aug,

            Sep,

            Oct,

            Nov,

            Dec

        }

 

        private static Dictionary<Months, string> _monthCol;

        public static Dictionary<Months, string> MonthCollection

        {

            get

            {

                return _monthCol;

            }

        }

    }

and in XAML, this Utility class can be instantiated as a resource and then referenced in the ComboBox creation.  

            <ComboBox ItemsSource="{Binding Source={StaticResource monthCollection}, Path=MonthCollection}" SelectedIndex="0" DisplayMemberPath="Value" SelectedValuePath="Key" />

Note that the SelectedValuePath property has also been set to point to the Key in the dictionary. with this, it is easy to handle the selection changed event and the combobox's SelectedValue property will then be the enum value and you can then easily use a switch/case block to handle it appropriately. If  you don't do it, you can still easily cast this to get to the enum value as below

            switch(((KeyValuePair<Utility.Months, string>)cmbBox.SelectedValue).Key)

            {

                //your case statements here

                default:

                    //custom logic

                break;

            }

 Comments welcome !

 

 

 

September 22, 2008

Hiding from Debugger

When writing trivial get/set type properties, I have seen many developers still struggle during debugging since if they do a step into (typically F11), they end up going into the getter and setter methods as well.

Debugger related attributes have been available since early times, but somehow people seem unaware. Typically one can use DebuggerHidden or DebuggerStepThrough attributes, as shown in the following code snippet.

        public int MyIntProperty

        {

            [DebuggerStepThrough]

            get { return myVar; }

            [DebuggerHidden]

            set { myVar = value; }

        }

This functionality has been further simplified in VS 2008 by virtue of a setting that by default is set to step over properties and operators. See the figure below (VS - Tools - Options).

PropertyDebug.jpg

The issue with this however is that it works globally so if for some properties one wishes to step into and for some one doesn't, this setting will not help and one needs to revert back to using the specific attributes.

An interesting benefit of using the automatic property feature, added with C# 3.5, is that the debugger automatically steps over such property declarations.

        public int MyIntProperty { get; set; }

So apart from making the code concise and one having to think of less variable names, one can also get this side benefit of debugger step through without having to assign any attributes or enabling the setting in VS tools options dialog.

September 18, 2008

Windows 7

Back in June I had mentioned about Windows 7 and that there is lack of information and a changed stance from Microsoft. If you haven't noticed, there is now a blog (about a month now) by the Windows 7 team called Engineering Windows 7. The likes of Jon DeVaan and Steven Sinofsky, along with other team members blog here.

If you want to know what goes behind creating something like a Windows operating system, this will give you a good perpective.

September 15, 2008

Unable to add reference to assemblies in GAC from VS

Recently someone asked me about an issue he was facing in being able to add reference to an assembly in GAC from Visual Studio. This is a question that somehow keeps coming back. If you search online you will surely get pointers on how to solve this. The typical way is to provide the path to where your specific assemblies are by adding a registry key pointing to it, or add it to the already known standard paths and you will start to see your assembly in the .NET tab of the Add Reference dialog. See more details here. VS picks up files found in this path also - C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies.

Now if you are satisfied by this, you have really only addressed the symptoms, but not the root cause. What is still unanswered is why VS didn't allow you add assemblies from GAC in the first place and went about it in a roundabout way?

In my opinion, there are really two aspects to this. The first is more about the fact that GAC isn't really organized the way it is seen as! Hmm, sounds a bit philosophical. In case you aren't aware .NET comes along with a Windows shell extension called Shfusion.dll. This DLL is found in your framework install path (on my machine the path is C:\Windows\Microsoft.NET\Framework\v2.0.50727).  The typical view that you see that lists the name, version, culture, public key token and processor architecture is a view managed by this shell extension. Incidentally if you didn't know which is GAC folder, it is c:\windows\assembly or you can just type assembly in start/run and view this folder.

I am surprised that people don't automatically realize this for the simple fact that in a window's folder, you can't have two files with the same name. We can store multiple assemblies in GAC which have same name, but different assembly version. This by itself should be sufficient to point out that the folder structure has to be different than what is seen.

So, if you remove the shell extension, you can see the true folder structure. There are registry values that you can tweak (set HKLM\Software\Microsoft\Fusion\DisableCacheViewer [DWORD] to 1), but I personally prefer the simpler option of unregistering the shfusion.dll. You can run regsvr32.exe with -u command line option to unregister shfusion.dll (something like regsvr32 -u  C:\Windows\Microsoft.NET\Framework\v2.0.50727\shfusion.dll). After this if you view the GAC in your windows explorer you will see the real structure which looks something like below.  

GAC.jpg

The framework assemblies and other assemblies in GAC actually reside inside of a sub directory called GAC_MSIL. Within this a folder is created by the name of the assembly and then another folder inside of that with the version number. So each version actually sits inside of a folder named by the version and hence you are able to copy as many files with the same names but different versions in GAC. BTW, if you want to view GAC, without even bothering to unregister the shfusion.dll, you can use the good old command prompt and navigate to C:\Windows\Assembly and view the directories, sub directories and the files in this folder.

When you want to add a reference to an assembly for VS to use, it needs to know the path so that it can access that and the compiler can also access the assembly during compilation. Since GAC's actual directory structure is hidden behind the shell extension, VS can't really show the actual folder structure. You may argue that one can write code to query the folders and sub folders and then display the assemblies, but this will be a significant overhead while showing the Add Reference dialog. An easier approach would be to just put the assemblies in some other known path and load from there and that's exactly what is done. Hence you will find two copies of all the framework assemblies. One set is in GAC and another is in C:\Windows\Microsoft.NET\Framework\v2.0.50727 (or C:\Program Files\Reference Assemblies\Microsoft\Framework for 3.0 and 3.5). Also as mentioned earlier, the registry settings allow you to configure your own path that VS uses to show the files.

The second aspect more deals with the purpose of GAC itself. You would surely be already aware that GAC is a place to put shared assemblies i.e. assemblies used by many applications are put here. We already saw how GAC allows you to place multiple versions of the assemblies as well. So what this mean? If you pay little attention to detail, you would realize that the idea of shared assemblies for applications really is to do with the run state of the application. What I am trying to say is that when an application is running, it may pick up assemblies from GAC along with those that are privately deployed. While this is dealing with runtime behavior, VS is really a developer tool and is more about design time and build process. Why should anyone be bothered about GAC at this time? All developers need is to be able to add reference to the appropriate assemblies and compile and build against them. The deployment will take care of ensuring that all required assemblies (private and shared) are appropriately deployed and it is at this time that the CLR will probe GAC if it can't find an assembly required by the application in the private probing path. Hence in my opinion, the question "I can't add reference to assemblies in GAC in VS" is really invalid, since you should not be doing it anyway.

Hope this helps. Any comments are most welcome.

September 8, 2008

How to write custom Main method for a WPF application?

If you have been working with WPF applications you know that the current default behavior for adding the entry point (Main) method is via codegen. You don't write it yourself. The method is generated when you compile your application. A typical WPF project contains App.xaml which is marked as ApplicationDefinition in the csproj file.

    <ApplicationDefinition Include="App.xaml">

      <Generator>MSBuild:Compile</Generator>

      <SubType>Designer</SubType>

    </ApplicationDefinition>

It is due to this tag, that MSBuild when compiling the project adds the Main method to App.g.cs that is created in the obj/debug (or obj/release) folder. The generated file looks something like below. See details here.

    public partial class App : System.Windows.Application {

 

        /// <summary>

        /// InitializeComponent

        /// </summary>

        [System.Diagnostics.DebuggerNonUserCodeAttribute()]

        public void InitializeComponent() {

 

            #line 4 "..\..\App.xaml"

            this.Exit += new System.Windows.ExitEventHandler(this.Application_Exit);

 

            #line default

            #line hidden

 

            #line 4 "..\..\App.xaml"

            this.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative);

 

            #line default

            #line hidden

        }

 

        /// <summary>

        /// Application Entry Point.

        /// </summary>

        [System.STAThreadAttribute()]

        [System.Diagnostics.DebuggerNonUserCodeAttribute()]

        public static void Main() {

            DummyApp.App app = new DummyApp.App();

            app.InitializeComponent();

            app.Run();

        }

    }

 

Hence, If you try to directly add code for Main method in App.xaml.cs, you will end up compiler error stating that there is already a definition of Main method. To add your own implementation, there are various approaches and you can pick that works best for you

Approach 1
You can delete the existing App.xaml and App.xaml.cs and add a new class file and maybe call it App.cs. In this you can define the App class and write your own Main method as below.

    public class App : System.Windows.Application

    {       

        [STAThread]

        public static void Main()

        {

            App app = new App();

            app.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative);

            app.Run();

        }

    }

 

Approach 2
You will run into issues with Approach 1 if you are adding resources and resource dictionaries to your App.xaml. Since the App.xaml is no longer present you will have to write code in your App.cs itself to manage the resources and the merged dictionaries. However this can be more easily handled by modifying the .csproj file and marking App.xaml as Page instead of ApplicationDefinition 

    <Page Include="App.xaml">

      <Generator>MSBuild:Compile</Generator>

      <SubType>Designer</SubType>
    </Page>

 

 

Due to this change, the default entry point is no longer generated and you can write your own which can be something like below. For detailed discussion on this check Dr. WPF's blog.

 

    public partial class App : System.Windows.Application

    {

        [STAThread()]

        static void Main()

        {

            App app = new App();

            app.InitializeComponent();

            app.Run();

        }

    }

 

Approach 3
If you have resources and hence want to have App.xaml, but don't like to tamper with .csproj file, then you can include another class in your project that defines the Main method as below.

 

    class Startup

    {

        [STAThread]

        static void Main()

        {

            App app = new App();

            app.MainWindow = new Window1();

            app.MainWindow.Show();

            app.Run();

        }

    }

 

However compilation will result in error stating that the EXE now has multiple entry points. You can then use the /main compiler option to identify the class whose main you want the application to use as entry point. This can be done via the project properties. In the Application tab, modify the Startup object properties from the drop down. See figure below.

 

startup.jpg

 

Each approach will result in the desired behavior of having a custom entry point defined instead of using the default code generated method. You can pick any approach that works for you.

September 5, 2008

IE 8 Beta 2 - Your last browsing session closed unexpectedly

IE8.jpg

Are you seeing something like this with IE 8 Beta 2? I have been getting this on and off and just realized when this occurs. If you are debugging a web based project (ASP.NET or Silverlight) from VS and then stop debugging from VS, the next time you open the browser, you will get this message. No harm done. You just select the "Go to your home page" option.

Interestingly, this doesn't occur if you are debugging, but instead of stopping debugging from VS, you directly close the browser window. 

Targeting .NET framework 3.5 SP1

If you working with VS 2008 you must be already aware about how to target your application to run on different .NET frameworks. With .NET framework 3.5 SP1 now available, I wanted to target my application for this version, but surprisingly VS 2008 doesn't shows this in the list of target .NET frameworks. Harish describes how to get this done. Check it out here.

It would have been much simpler to just provide this option in the existing drop down itself !

September 4, 2008

Debugging into .net source code

You may be aware of the availability of .net source code for debugging. Scott Guthrie had mentioned this along with release of VS 2008. Though Reflector still remains my personal favorite for quickly checking the .net source code during my regular work, it can't help much during debugging.

Recently the .net 3.5 SP1 code was also made available. In case you haven't checked this out, here are the instructions on how you can configure and use this feature from VS 2008. I tried this and it is awesome to be able to debug straight into .net source code and see what is really happening in there. Do note, however, as Shawn also mentions, the initial load time can be pretty high and i had to wait almost 30 min before I could start on with debugging. However since the symbols and the .cs files are cached locally, it is very fast thereafter. Go ahead and give it a try !

September 2, 2008

Interesting installation experience on 64 bit machine

The other day a team approached me stating that they had some issues in running and accessing a .net application on their newely configured Win2K3 64 bit dual core server. They were getting some sort of access denied when they moved their app from 32 bit to 64 bit. I told them that just by moving to 64 bit can't result in such issue and asked them to cross check and install .net 2.0 framework for 64 bit.

They had not installed it but soon reverted with another error while trying to do the installation - "Error creating process <C:\Docume~1\user\local settings\temp\1\IXP000.TMP\Install.exe>. Reason: C:\SYSROOT\system32\advpack.dll". I then refered them to this forum thread. 

The team came back with another interesting error that said - "The image file c:\netfx64\install.exe is valid, but is for a machine type other than current machine.". The message seemed to hint that this wasn't a 64 bit machine, but the team confirmed that indeed it was.

So I asked them to verify if they were using a 64 bit OS by pointing to this support article, and interestingly it turns out that they were actually working with a 64 bit machine but with a 32 bit OS setup on it. If you read the support article you will realize that there is a minor difference in the way the System details are shown. In a 32 bit system it reads Microsoft Windows Server 2003 Enterprise Edition, while in a 64 bit system it reads Microsoft Windows Server 2003 Enterprise x64 Edition.

I am waiting for the team to install teh 64 bit OS and then get back to me. In the meantime I thought to share this to highlight that be careful of what OS you are really running on your 64 bit system to avoid unpleasant surprises.

Subscribe to this blog's feed

Follow us on

Blogger Profiles

Infosys on Twitter