Creating a Setup with Visual Studio 2010 for an application that needs the full .net 4.0 framework

Tags: , , , , ,
3 Comments »

When using Visual Studio 2010 or any other version to create msi setups you can define prerequisites that need to be installed before the application will install. For most .NET applications this will be at least the .NET Framework itself. But from version 3.5 on there are two editions of this framework: the Client Profile and the Full Framework.

I created a setup and changed the prerequisites from Client Profile to the Full Framework. When testing this on a virgin machine the setup told me that I need to install the .NET 4.0 framework (that’s right) but then it directs me to the download of the Client Profile only.

To fix this, you have to change the InstallUrl of the .NET Framework Launch Condition:

  • right-click on the setup project in solution explorer and choose View –> Launch Conditions
  • here you will find a Launch Condition for the .NET Framework
  • select this Launch Condition and open the Properties Window
  • there you will find the InstallUrl property

For the full .net 4.0 Framework change this URL to http://go.microsoft.com/fwlink/?LinkId=186913

For the Client Profile of the .net 4.0 Framework the URL can stay as it is: http://go.microsoft.com/fwlink/?LinkId=131000

Deploy TT include files with a VSIX in Visual Studio 2010

Tags: , , , ,
1 Comment »

What’s the problem?

First of all I have to explain to everybody what I’m talking about:

With Visual Studio 2010 Microsoft introduced a new way to deploy extensions to Visual Studio. Instead of creating a setup.exe that copies files, writes to the registry and calls devenv.exe with the /setup option one only needs such a VSIX file that does all that is necessary to install an extension.

When working with the T4 (Template Transformation Toolkit) system one creates tt files with some kind of script that is used to generate source code within a user’s Visual Studio project. The Microsoft DSL Tools do the same: every DSL project contains a number of tt files that will generate all the code. If you take a look at such a file, you will only see two lines:

<#@ Dsl processor="DslDirectiveProcessor" requires="fileName='..\DslDefinition.dsl'" #>
<#@ include file="Dsl\Diagram.tt" #>

The magic happens with the include command. The real template code sits in the included file and not within every single project. When installing the DSL Tools extension to Visual Studio all these include files get installed somewhere where they can be found by the tt engine.

For my own DSL Languages I would like do the same: the user projects should only contain such two line tt files and include the rest of the template from other files.

How to deploy tt template files?

The following steps will show you how to deploy additional files with you DSL extension.

I will start from a newly created Domain-Specific Language Designer project. Such a project contains a Dsl and a DslPackage project where the DslPackage project creates besides of the DslPackage.dll a vsix file to install the designer onto another machine.

Our goal will be to add some tt files to the vsix and make them includable on the installed machine.

  1. Add a folder to the DslPackage project and name it TextTemplates (or any other name)
  2. Add the tt files to this folder.
    • In the properties windows clear the “Custom Tool” property; otherwise Visual Studio will try to execute these templates within the DslPackage project.
    • set “Build Action” to “Content”
    • set “Include in VSIX” to “True”
  3. Add a file called Additional.pkgdef to the DslPackage project with the following content and
    • set “Build Action” to “Content”
    • set “Include in VSIX” to “True”
      [$RootKey$\TextTemplating\IncludeFolders]
      [$RootKey$\TextTemplating\IncludeFolders\.tt]
      "IncludeMyDsl"="$PackageFolder$\TextTemplates"

      Replace “IncludeMyDsl” by a unique name for your DSL but make sure it starts with the word “Include”.

  4. Edit the source.extension.tt in the DslPackage project and add the following line within the Content tag:

    <VsPackage>Additional.pkgdef</VsPackage>

With these changes the tt files from the TextTemplates folder get packaged into the vsix file and will be accessible using the <include> tag on the machine where this extension is installed.

Be careful when using GetCallingAssembly() and always use the release build for testing

Tags: , , ,
1 Comment »

This looks like such a innocent method but it lead to big trouble in one of my projects. But lets start with when someone would use this method that is declared as a static method in the Assembly class. In the MSDN you can read:

Returns the Assembly of the method that invoked the currently executing method.

In our project we had an assembly with a lot of helper methods. On of these gets resources from the calling assembly. In various places of our code we called this method to get icons or other resources. This method used exactly this GetCallingAssembly() method to figure out what assembly to look for resources.

That worked pretty good in debug mode but exceptions were thrown in release mode. We could not understand what is going on. It became even worse: when we build a release version and tried to debug that version (using Visual Studio Debugger) in worked again. It looked like a heisenbug.

It took us some time to figure out what is also written in MSDN:

If the method that calls the GetCallingAssembly method is expanded inline by the compiler (that is, if the compiler inserts the function body into the emitted Microsoft intermediate language (MSIL), rather than emitting a function call), then the assembly returned by the GetCallingAssembly method is the assembly containing the inline code. This might be different from the assembly that contains the original method. To ensure that a method that calls the GetCallingAssembly method is not inlined by the compiler, you can apply the MethodImplAttribute attribute with MethodImplOptions.NoInlining.

The JIT compiler moves code around to optimize for performance. Small methods (up to about 56 Byte IL-Code if I remember it right) can be inlined where the method call was before. But the compiler does this only in release, not in debug mode. Also when attaching the debugger to our release build the JIT compiler stopped inlining to enable debugging and our bug was gone.

After understanding this, the fix is easy. Just don’t allow the compiler to inline that particular method that calls Assembly.GetCallingAssembly(). Then the method stays in the assembly where the source code is written and everything will be fine.

[MethodImplAttribute(MethodImplOptions.NoInlining)]
public void SomeFunction(int i)
{
    // ...
    var a = Assembly.GetCallingAssembly();
    // ...
}

This attribute does the trick and I recommend to use it on all methods that call GetCallingAssembly() and can be called form another assembly and need the real calling assembly.

A Change event for Dependency Properties

Tags: , , ,
No Comments »

WPF comes with Dependency Properties and everybody using WPF will know about these new kind of properties. When you define your own Dependency Properties in your own class you can pretty easy add a property change event handler:

public int MyProperty
{
    get { return (int)GetValue(MyPropertyProperty); }
    set { SetValue(MyPropertyProperty, value); }
}
public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.Register("MyProperty",
                        typeof(int),
                        typeof(MainWindow),
                        new UIPropertyMetadata(0,
                            MyPropertyvalueChangeCallback));

private static void MyPropertyvalueChangeCallback
                        (DependencyObject d,
                         DependencyPropertyChangedEventArgs e)
{
}

But how to add such a event handler to an already existing Dependency Property or somewhere else then in the defining class? E.g. to an property of a WPF-Control that was not build by you. Take a standard WPF-TextBox; both the Text and the FontSize properties are Dependency Properties but the TextBox-class only provides a change event for the Text-property. Nevertheless you can get a change event for any Dependency Property:

DependencyPropertyDescriptor dpd =
    DependencyPropertyDescriptor.FromProperty
        (Control.FontSizeProperty, typeof (TextBox));
dpd.AddValueChanged(someTextBox, SomeTextBoxFontSizeChanged);

Every time the FontSizeProperty on the instance someTextBox changes the given method is called. It’s that easy and you can implement this code everywhere not only within the class that defines the property.

Foxit Reader vs. Acrobat Reader: the default program problem

Tags: , ,
No Comments »

I’m a big fan of the Foxit pdf Reader. It is just so damn fast in comparison to Acrobat Reader when opening pdf documents. Yesterday I had to go through a bunch of pdfs each containing only one or two pages to find a specific one. While waiting for Acrobat Reader to open a file I could open, check an close a few files with Foxit. If you are not using Foxit Reader give it a try…

But for some pdf features you will need the original Adobe Reader. E.g. some documents with fields to enter data, with scripts or DRM secured files won’t open in Foxit.

I always have both installed on my machine and Foxit is the default application for opening pdf documents. But this setting changed some time ago on my Windows 7 64 bit machine.

I reset the default program for pdf in windows control panel to Foxit and all icons of pdf documents changed to the Foxit one. I can double click a file and Foxit opens  – great. But in the very moment Foxit comes up the default program is set to Acrobat Reader again. This happens all the time.

I’m not sure what’s going on here and what is involved. I was blaming Acrobat and searched for a solution on the Acrobat side of the problem. Nothing.

In the end an update of Foxit to the current version fixes my problems.

Lenovo Integrated Camera again working on Windows 7

Tags: , , ,
24 Comments »

My Lenovo X200 notebook comes with an integrated webcam and I’m using it pretty often for Skype calls etc. But some time ago it stopped working. After reinstalling drivers, taking to the Lenovo support hotline, installing exactly the driver I was told to it was still broken. Yesterday a Lenovo technician cam to replace the camera (I’m so glad to have on-site support and do not need to send the notebook in), but in the end the new webcam behaves exactly as the first one – just not working.

So I started to debug the problem by myself and figured the following out. Maybe this is just an issue on my machine with my other software installed but maybe this is helpful for someone else.

The driver from the Lenovo webpage is build by the camera vendor Ricoh. That driver package just does not work on my Windows 7 64bit machine. The out-of-the-box Windows 7 driver works just fine!

Find the Camera device in Device Manager

device manager

On the properties sheet choose Update driver

Integrated Camera Properties

Then “Browse my computer for driver software” and  “Let me pick from a list of device drivers on my computer”

Update Driver Software I

Update Driver Software II

On my machine it only shows up one compatible “USB Video Device” – just use that driver:

Update Driver Software III

If Windows does not find this single one you can select it from the larger list by unchecking “Show compatible hardware” and choosing “Microsoft” / “USB Video Device”:

Update Driver Software VI

For some reason it does not always work the moment I installed the new driver and I had to reboot the machine. After installing the driver the device in device manager is called “USB Video Device” but after the reboot it is for some reason renamed to “Integrated Camera” but still using the Windows driver (that is the important part, you can check it in the properties sheet from within device manager). From now on it was working fine.

After some time Windows suddenly replaced this driver with the Ricoh one and the camera was broken again. To prevent Windows from doing so I uninstalled the driver package from “Programs and Features” in Control Panel.

Trackpoint Scrolling in iTunes, Thunderbird, etc.

Tags: , , ,
3 Comments »

I’m using a Lenovo laptop and I’m a big fan of the Trackpoint mouse replacement. That is this small red thing in the middle of the keyboard some notebooks are equipped with instead of a touchpad. In fact my notebook does not even has a touchpad.

You can use the Trackpoint for scrolling like a mouse wheel when pressing the middle button and moving the Trackpoint up or down. Everybody using it will know what I’m talking about, anybody else does not need to read to the end.

But in some applications the scrolling does not work at all what is very annoying. I had the most trouble with Thunderbird and iTunes – just no scrolling.

And here is a fix for that issue. There is a file (C:\Program Files\Lenovo\ TrackPoint\tp4table.dat) on your machine when you have installed the Trackpoint software from Lenovo. Just edit that file and add some additional rows for the application with broken scrolling.

; Apple ITunes
*,*,itunes.exe,*,*,*,WheelStd,0,9

; Mozilla Thunderbird
*,*,thunderbird.exe,*,*,*,WheelStd,0,9

 

Remember to open the file with an editor as Administrator otherwise it would not work. I had to reboot my machine after that change. I just tested this change on a Windows 7 64 bit machine but it should work on 32 bit or other versions of Windows as well. Maybe the same fix applies also to non-Lenovo notebooks but I cannot tell. If someone out there tested it, please comment.

More on this topic and templates for some more applications (Picasa, Safar, Windows Live Mail, Windows Live Writer) can be found at http://forums.lenovo.com/t5/X-Series-ThinkPad-Laptops/Fixing-Trackpoint-Scroll-for-ITunes-Picasa-Safari-Windows-Live/m-p/124378

How to get a IWin32Window from a WPF Window?

Tags: ,
3 Comments »

When building applications that mix WPF and Winforms windows (e.g. because you are using a Winforms dialog within a WPF application) you will sometimes need a System.Windows.Forms.IWin32Window interface from an WPF System.Windows.Window. This will be useful when using the WinForms OpenFileDialog and wanting to provide a parent window to the ShowDialog() method that only accepts IWin32Window as parent.

The IWin32Window interface declares only one read-only property named Handle that must be provided by the WPF Window.

Implementing the Interface

It is very simple to just add this interface to an existing WPF Window and implementing the single property:

public partial class Window1 : Window, IWin32Window
{
   public IntPtr Handle
   {
      get
      {
         var interopHelper = new WindowInteropHelper(this);
         return interopHelper.Handle;
      }
   }
}

 

Using a wrapper class

It does not look as a very good solution to add such an interface to each and every Window in you whole application only to be able to be the parent of a dialog. So instead of implementing the interface directly you could build a wrapper class that implements this interface and use this wrapper when opening a dialog:

public class Wpf32Window : IWin32Window
{
    public IntPtr Handle { get; private set; }

    public Wpf32Window(Window wpfWindow)
    {
        Handle = new WindowInteropHelper(wpfWindow).Handle;
    }
}

Opening the dialog will now look like:

d.ShowDialog( new Wpf32Window(this) );

The grand solution to this problem

I like the wrapper solution more than implementing an interface to each and every window but I do not like the changed ShowDialog() call. It just does not look natural any more. To solve this I created an extension Method to be used with the wrapper class:

public static class CommonDialogExtensions
{
    public static DialogResult ShowDialog
                               (this CommonDialog dialog, 
                                     Window parent)
    {
        return dialog.ShowDialog(new Wpf32Window(parent));
    }
}

Now the call to open a WinForms dialog with an WPF parent looks as it should look like:

d.ShowDialog(this);

Isn’t one OpenFileDialog enough?

Tags: ,
No Comments »

In fact one OpenFileDialog is enough but the .net framework provides two of them:

  1. System.Windows.Forms.OpenFileDialog in System.Windows.Forms.dll
  2. Microsoft.Win32.OpenFileDialog in PresentationFramework.dll (that is WPF)

With such a setup one would use the first for WinForms applications and the second for WPF apps. In fact if you create a WPF application and just type in OpenFileDialog you will get number 2.

But the 2nd one (even if it is part of the newer part of the framework) is an old dialog where the 1st will use the new and shiny Windows 7 dialog on Win7. Just look at the following screenshots.

a

b

Only the first class uses the Windows 7 dialog and comes with proper support for Libraries etc. Even if the second shows the Libraries in its left part it does not fully support this new Windows 7 feature.

I have no idea why the WPF class uses the old windows API but it does. For best compatibility with all Windows versions (including 7) you should always use the Winforms Dialog even when building WPF apps! It does not hurt to reference the System.Windows.Forms.dll (it is installed an every machine running the .net framework) and you can use that dialog from WPF without any trouble.

You should only know about one little disadvantage when using the WinForms dialog. It only accepts WinForms as a parent window no WPF windows. To overcome this limitation please read my other article about the IWin32Window interface and how to implement / provide it in WPF at http://www.ticklishtechs.net/2009/12/22/how-to-get-a-iwin32window-from-a-wpf-window/

Upgrading Windows 7 RC to RTM

Tags: ,
2 Comments »

Disclaimer: The following is no official advice or anything. I just did it and it worked ON MY MACHINE. Fell free to try but have a backup of your data.

The Windows 7 RTM bits will not allow an upgrade from an earlier version of Windows 7 (e.g. RC or beta). I belief that Microsoft did this to ensure that your new operating system works just fine and no beta and release bits get mixed up.

For the upgrade from the beta version to the release candidate quickly some patch occurred which allowed an upgrade. I used the same one and it works fine on my machine to upgrade Windows 7 RC to RTM.

What’s to do?

You need to change one file on the installation DVD. On way to do this is to copy all files to your computer, change the file and burn a new DVD. Since the upgrade will be run from within the already installed Windows 7 you do not need to boot from this DVD. I just copied all files to a USB drive and run the setup.exe from that drive. I belief you will be able to install Windows also from a directory on you local hard disk containing all the files from the DVD.

In the source folder you will find a text file named cversion.ini. The original file looks like:

[HostBuild]
MinClient=7233.0
MinServer=7100.0

Just change the MinClient number to the build version of you current Windows version. For the Windows 7 RC it will be 7100.

The upgrade should work fine now. But if your new Windows 7 starts acting strange don’t blame Microsoft or me. Always remember you installed it with an unsupported patch.

WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Log in