Archive for December 2010

A Visual Studio snippet for a class with #region sections

Here is a simple snippet to add to Visual Studio if you want:

Place it here for Visual Studio 2010: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC#\Snippets\1033\Visual C#

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>classr</Title>
			<Shortcut>classr</Shortcut>
			<Description>Code snippet for class with prepopulated regions.</Description>
			<Author>Microsoft Corporation</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
				<SnippetType>SurroundsWith</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>name</ID>
					<ToolTip>Class name</ToolTip>
					<Default>MyClass</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><!&#91;CDATA&#91;class $name$
	{
	#region Member Fields
	#endregion
	
	#region Constructor
	/// <summary>
	/// The default constructor
	/// </summary>
	public $name$()
	{
	}
	#endregion
	
	#region Properties
	#endregion
	
	#region Functions
	#endregion
	
	#region enums
	#endregion
		$selected$$end$
	}&#93;&#93;>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

A Progress Bar using WPF’s ProgressBar Control, BackgroundWorker, and MVVM

WPF provides a ProgressBar control.  But there isn’t really a manual for it, especially if you want to follow MVVM.

So I am going to make a little application that counts from zero to ten and tracks the progress.  You are going to see when it is OK to use the foreground and when it is not OK but better to use BackgroundWorker.

While much of this code may be production ready, you should be aware that this code intentionally implements a foreground process that is an example of what not to do.

Prerequisites

  • Visual Studio

Step 1 – Create a new WPF Application Project

  1. In Visual Studio, create a new Solution and choose WPF Application
  2. Give it a name.
  3. Hit OK.

Step 2 – Add two base MVVM files

There are two basic classes used for MVVM.

  • RelayCommand
  • ViewModelBase

These are found on different blogs and different posts all over the internet, so I would say they are public domain, or free and unlicensed.

  1. Download them zipped here. MVVM
  2. Extract the zip file.
  3. Add the MVVM folder and the two class under it to your project.

Step 3 – Create a ProgressBarViewModel class

  1. Create a new Class called ProgressBarViewModel.
  2. Adding a using MVVM statement at the top.
  3. Make the class inherit ViewModelBase.
    class ProgressBarViewModel : ViewModelBase
    {
    }
    

This will be populated as we create our View.

Step 4 – Design the GUI in MainWindow.xaml

Ok, so lets create the GUI.

  1. Add a local reference. (Line 4)
  2. Add a ProgressBarViewModel object as a resource. (Lines 6-8)
  3. Create a StackPanel in the default Grid to put everything in. (Line 10)
  4. Add a one character label in great big text to display our number. (Line 11)
  5. Add a ProgressBar element. (Line 12)
  6. Create buttons to manipulate the label. (Lines 13-16)
  7. Configure the DataContext of each element to be the the ProgressBarViewModel using the Key PBVM we gave it when we added it as a resource. (Lines 11-16)
  8. Think of and create Binding Paths for each element. Yes, we can basically just make these Path names up and add them to the ProgressBarViewModel later. (Lines 11-16)

Here is the XAML.

<Window x:Class=&quot;WPFProgressBarUsingBackgroundWorker.MainWindow&quot;
        xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
        xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
        xmlns:local=&quot;clr-namespace:WPFProgressBarUsingBackgroundWorker&quot;
        Title=&quot;MainWindow&quot; >
    <Window.Resources>
        <local:ProgressBarViewModel x:Key=&quot;PBVM&quot; />
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Label Content=&quot;{Binding Path=Value}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; HorizontalAlignment=&quot;Stretch&quot; HorizontalContentAlignment=&quot;Center&quot; Name=&quot;labelNumberCounter&quot; VerticalAlignment=&quot;Center&quot; FontSize=&quot;175&quot; />
            <ProgressBar Margin=&quot;0,3,0,3&quot; Height=&quot;20&quot; Name=&quot;progressBar&quot; Value=&quot;{Binding Path=Value}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; Minimum=&quot;{Binding Min}&quot; Maximum=&quot;{Binding Max}&quot;/>
            <Button Command=&quot;{Binding Path=IncrementBy1}&quot; Content=&quot;Manual Count&quot; DataContext=&quot;{StaticResource PBVM}&quot; Height=&quot;23&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Name=&quot;button1&quot; Width=&quot;Auto&quot; />
            <Button Margin=&quot;0,3,0,3&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Command=&quot;{Binding Path=IncrementAsForegroundProcess}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; Content=&quot;Count to 10 as a foreground process&quot; HorizontalAlignment=&quot;Stretch&quot; Height=&quot;23&quot; Name=&quot;buttonForeground&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;Auto&quot; />
            <Button Margin=&quot;0,3,0,3&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Command=&quot;{Binding Path=IncrementAsBackgroundProcess}&quot; DataContext=&quot;{StaticResource ResourceKey=PBVM}&quot; Content=&quot;Count to 10 as a background process&quot; HorizontalAlignment=&quot;Stretch&quot; Height=&quot;23&quot; Name=&quot;buttonBackground&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;Auto&quot; />
            <Button Command=&quot;{Binding Path=ResetCounter}&quot; Content=&quot;Reset&quot; DataContext=&quot;{StaticResource PBVM}&quot; Height=&quot;23&quot; IsEnabled=&quot;{Binding Path=IsNotInProgress}&quot; Name=&quot;buttonReset&quot; Width=&quot;Auto&quot; />
        </StackPanel>
    </Grid>
</Window>

Step 5 – Populate the ProgressBarViewModel

  1. Create the following member fields.
    • Double _Value;
    • bool _IsInProgress;
    • int _Min = 0;
    • int _Max = 10;
  2. Create a matching property for each member field. Make sure that in the set function of the property you call NotifyPropertyChanged(“PropertyName”).
  3. Create a function for each of the four buttons and populate these functions with the code. See the functions in the code below:
    • Increment()
    • IncrementProgressForeground()
    • IncrementProgressBackgroundWorker()
    • Reset()
  4. Create and populate the functions for the BackgroundWorker.
    • worker_DoWork
    • worker_RunWorkerCompleted()
  5. Create the following RelayCommand instances as member Fields.
    • RelayCommand _Increment;
    • RelayCommand _IncrementBy1;
    • RelayCommand _IncrementAsBackgroundProcess;
    • RelayCommand _ResetCounter;
  6. Create matching ICommand properties for each RelayCommand, instantiating the RelayCommand with the correct function.

Here is the code for the ProgressBarViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Text;
using System.Windows.Input;
using MVVM;

namespace WPFProgressBarUsingBackgroundWorker
{
    class ProgressBarViewModel : ViewModelBase
    {
        #region Member Fields
        Double _Value;
        bool _IsInProgress;
        int _Min = 0, _Max = 10;
        #endregion

        #region Member RelayCommands that implement ICommand
        RelayCommand _Increment;
        RelayCommand _IncrementBy1;
        RelayCommand _IncrementAsBackgroundProcess;
        RelayCommand _ResetCounter;
        #endregion

        #region Constructors
        /// <summary>
        /// The default constructor
        /// </summary>
        public ProgressBarViewModel()
        {
        }
        #endregion

        #region Properties
        /// <summary>
        /// Used to mark if the counter is in progress so the counter can't be started
        /// while it is already running.
        /// </summary>
        public bool IsInProgress
        {
            get { return _IsInProgress; }
            set
            {
                _IsInProgress = value;
                NotifyPropertyChanged(&quot;IsInProgress&quot;);
                NotifyPropertyChanged(&quot;IsNotInProgress&quot;);
            }
        }

        public bool IsNotInProgress
        {
            get { return !IsInProgress; }
        }

        public int Max
        {
            get { return _Max; }
            set { _Max = value; NotifyPropertyChanged(&quot;Max&quot;); }
        }

        public int Min
        {
            get { return _Min; }
            set { _Min = value; NotifyPropertyChanged(&quot;Min&quot;); }
        }

        /// <summary>
        /// This is the Value.  The Counter should display this.
        /// </summary>
        public Double Value
        {
            get { return _Value; }
            set
            {
                if (value <= _Max)
                {
                    if (value >= _Min) { _Value = value; }
                    else { _Value = _Min; }
                }
                else { _Value = _Max; }
                NotifyPropertyChanged(&quot;Value&quot;);
            }
        }

        #region ICommand Properties
        /// <summary>
        /// An ICommand representation of the Increment() function.
        /// </summary>
        public ICommand IncrementBy1
        {
            get
            {
                if (_IncrementBy1 == null)
                {
                    _IncrementBy1 = new RelayCommand(param => this.Increment());
                }
                return _IncrementBy1;
            }
        }

        /// <summary>
        /// An ICommand representation of the IncrementProgressForegroundWorker() function.
        /// </summary>
        public ICommand IncrementAsForegroundProcess
        {
            get
            {
                if (_Increment == null)
                {
                    _Increment = new RelayCommand(param => this.IncrementProgressForeground());
                }
                return _Increment;
            }
        }

        /// <summary>
        /// An ICommand representation of the IncrementProgressForeground() function.
        /// </summary>
        public ICommand IncrementAsBackgroundProcess
        {
            get
            {
                if (_IncrementAsBackgroundProcess == null)
                {
                    _IncrementAsBackgroundProcess = new RelayCommand(param => this.IncrementProgressBackgroundWorker());
                }
                return _IncrementAsBackgroundProcess;
            }
        }

        /// <summary>
        /// An ICommand representation of the Reset() function.
        /// </summary>
        public ICommand ResetCounter
        {
            get
            {
                if (_ResetCounter == null)
                {
                    _ResetCounter = new RelayCommand(param => this.Reset());
                }
                return _ResetCounter;
            }
        }
        #endregion ICommand Properties
        #endregion

        #region Functions
        /// <summary>
        /// This function manually increments the counter by 1 in the foreground.
        /// Because it only increments by one, the WPF control bound to Value will
        /// display the new value when this function completes.
        /// </summary>
        public void Increment()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;

            // If the value is already at 10, start the counting over.
            if (Value == 10)
                Reset();
            Value++;
        }

        /// <summary>
        /// This function starts the counter as a foreground process.
        /// This doesn't work.  It counts to 10 but the UI is not updated
        /// until the function completes.  This is especially problematic
        /// since the buttons are left enabled.
        /// </summary>
        public void IncrementProgressForeground()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;
            Reset();
            IsInProgress = true;
            Value = 0;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
            IsInProgress = false;
        }

        /// <summary>
        /// This starts the counter as a background process.
        /// </summary>
        public void IncrementProgressBackgroundWorker()
        {
            // If we are in progress already, don't do anything
            if (IsInProgress)
                return;

            Reset();
            IsInProgress = true;
            BackgroundWorker worker = new BackgroundWorker();
            // Configure the function that will run when started
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);

            /*The progress reporting is not needed with this implementation and is therefore
            commented out.  However, in your more complex application, you may have a use for
            for this.

            //Enable progress and configure the progress function
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);

            */

            // Configure the function to run when completed
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);

            // Launch the worker
            worker.RunWorkerAsync();
        }

        /// <summary>
        /// This is the function that is called when the worker is launched with the RunWorkerAsync() call.
        /// </summary>
        /// <param name=&quot;sender&quot;>The worker as Object, but it can be cast to a worker.</param>
        /// <param name=&quot;e&quot;>The DoWorkEventArgs object.</param>
        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = _Min; i < _Max; i++)
            {
                Value++;
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// This worker_ProgressChanged function is not in use for this project. Thanks to INotifyPropertyChanged, this is
        /// completely unnecessary.
        /// </summary>
        /// <param name=&quot;sender&quot;>The worker as Object, but it can be cast to a worker.</param>
        /// <param name=&quot;e&quot;>The ProgressChangedEventArgs object.</param>
        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Does nothing yet
            throw new NotImplementedException();
        }

        /// <summary>
        /// This worker_RunWorkerCompleted is called when the worker is finished.
        /// </summary>
        /// <param name=&quot;sender&quot;>The worker as Object, but it can be cast to a worker.</param>
        /// <param name=&quot;e&quot;>The RunWorkerCompletedEventArgs object.</param>
        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            IsInProgress = false;
        }

        /// <summary>
        /// This function resets the Value of the counter to 0.
        /// </summary>
        private void Reset()
        {
            Value = Min;
        }
        #endregion
    }
}

I’m sorry that this is not the most Newbie proof post. But I tried to comment like crazy the code so you can get through it.

Now if you find a discrepancy in my walk-through, please comment. Also, if it is easier for you to just download the project, here it is:
WPFProgressBarUsingBackgroundWorker.zip

Russian Government going Open Source…and the future

Well, I have seen governments claim they are going to open source before, but not from Russia, and not with such a realistic plan to migrate over a few years.

Here is a link to the article via Google translate:

Putin ordered the transfer of power on Linux

The now

Business drives software development.  Open Source communities help, but even today much of the ongoing development for Linux is driven by businesses such as Red Hat and Novell and others.  If you think your Linux code is being written by unpaid developers in their spare time, you are somewhat correct but only partially.  Most changes are made by developers who are paid.

While communities are nice, they can’t match the hours or output of experienced developers working forty to sixty hours a week.

Looking Ahead…the Apps…and C# (Mono)

The more open source is used in business, the more development power it will have.  But it is not the open source Operatings Systems that prevent people from moving to Linux or BSD.  Ubuntu, SUSE, Fedora, CentOS, PC-BSD, and numerous others are all very usable desktops that are user friendly.  It is the software that runs on them that everyone is waiting for.

The market is already there to make millions extra if you application runs cross platform, one Windows, MAC, Linux, and BSD.

But most the applications written for Windows, the business desktop of today, are using .NET Framework. So naturally those companies are going to want to make their code cross platform.  And they are going to find it is easier than they thought to move their applications between platforms using C#.  I have recently decided that C# is the future of applications on all platforms.

Some MAC and Linux users don’t like Microsoft and will fight off the idea of a Microsoft provided development platform such as C# (Mono) on their systems.  But when a corporation decides that you must run software X, and software X requires .NET, and you have to either give up your MAC or Linux box for a Windows box, or use C# (Mono), then users will come around.

If you are a company writing software for Windows only today and using C#, you need to take a look at Mono. Even if the return on investment of developing a C# (Mono) based version of your product is a slight loss to break even, it is an investment in the future.  Once written, maintenance costs will be less than the original development costs and that slight loss to break even margin will turn to a small profit.  And with the experience, you next app will migrate to C# (Mono) that much easier and soon, all you apps will run anywhere that C# (Mono) can run.

This is going to take off in a way Java hasn’t because developers for windows prefer and will continue to prefer .NET over Java.  And when it comes to business apps, Java just isn’t the language of choice.  Business applications are written in C#.

How to tranfer a TiVo recording and watch it on FreeBSD?

I broke my TiVo remote to my TiVo series II.

I wanted to watch a TiVo recording on my laptop…running FreeBSD. I had never done this, so I wasn’t sure if it was going to happen.

Gratefully, I succeeded. Here is what I had to do.

Step 1 – Find my media access key.

You can find this on your TiVo, but since I didn’t have a remote, I couldn’t look on my TiVo.  So I went to http://www.Tivo.com, logged in, and sure enough under My Account, there was a link to see my Media Access Key.

Step 2 – Download a video recording from your Tivo

  1. Connect to you Tivo using your favorite web browser using https.
    Note: I wasn’t sure of my Tivo’s IP Address so I had to connect to my Wireless router and look at its DHCP leases.
  2. Login using these credentials:
    User: tivo
    Password: [your media access key]Once in, you will see a list of recordings in a table and you can download them as you desire.
  3. Download your recording.  Your recordings are .tivo files.

Step 3 – Install tivodecode

When I tried to play the .TiVo file with mplayer, it failed. So I looked at how to convert it.

Turns out there is a port called tivodecode.  Install it as follows.

# cd /usr/ports/multimedia/tivodecode
# make install

Step 4 – Decode the .TiVo file

Run the following command to decode your .TiVo file.

tivodecode “Some Video.TiVo” -o “Some Video.mpg”

And now you can play decoded video in mplayer.

Windows Live Messenger update broke again: Error 8100030d

Hey a few months ago, Windows Live Messenger was update by Microsoft.

Afterwards, it would not let me log in. It gave me this error and took me to this page:
Error 8100030d: Cannot Sign-in to Windows Live Messenger

That page did not help at all.

This page worked the first time:
How to perform Clean Installation of Windows Live Messenger

However, it was still very annoying.  And I complained the first time it happened.

Well, Windows Live was updated by Windows Update again, and yes, you guessed it, this same issue happened again.

A second time is just unacceptable.

Especially since neither of the websites above fix this.  I expected the second one to fix this again, but alas, it does not!

Quote’s and brackets (” < >) in code snippets are a little messed up on my site

Hey all,

It has come to my attention that all the quote’s and brackets (” < >) in code snippets are a little messed up on my site.

I am fixing it.

For now, just use your favorite text editor and do a replace all:

< should be < > should be >
” should be ”

I will try to get this fixed.

Update:
I think I have this fixed. However, I think I am in a state where if I edit and update a document, it breaks the code. This is a problem for me that I need to find a solution for.

VMWare, RDP (MSTSC), WPF, and DisableHWAcceleration

I don’t know if you, like me, have a development box running Visual Studio 2010 and VMWare workstation. I develop in C# and WPF, and test the product in a VM. Then sometimes, when I work from home, I remote desktop into my development box.

When I am using RDP to remote control a VMWare Workstation host, and I run a WPF Application inside a VM, the WPF application doesn’t display. The window opens, and you see the frame of your windows, but the inside is just blank or a white/gray box. None of the WPF Controls are visible.

I have found two ways to fix this. One is permanent and one is temporary.

Option 1 – (Permanent) Set this registry key. Read more about this here on MSDN: Graphics Rendering Registry Settings

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Avalon.Graphics]
"DisableHWAcceleration"=dword:00000001

Option 2 – (Temporary) Or just reboot the VM while connected to the VMWare Workstation host via RDP. It seems that the VM boots and the OS detects the lack of support and disabled hardware acceleration. However, once you reboot when you are not RDP’ed into the VMWare Workstation host, you have hardware acceleration back.

I took me a long time to figure this out, because there was little to nothing in a Google search. I came across this solution while looking for something else a month or so ago, and needed to use it again when working from home last night. I thought I would post it so I never have to look for it again.

In Windows 7/2008, in Explorer, by default, Shift+Right-click in the white space gives you the “Open command window here” option

It is the simple things in life that makes one happy.

Did you know this:

In Windows 7/2008, in Explorer, by default, Shift+Right-click in the white space gives you the “Open command window here” option.

Using CSS to make an html numbered list have text before the number

I often use lists that look as follows:

  • Is in the format of Step #
  • Doesn’t indent.

It is a little more complex than it needs to be to do this in HTML but still doable.  The below list is an example.

  1. The first thing to do.
  2. The second thing to do.
  3. The third thing to do.

So how is it done? Well, it is done with CSS.

  1. Add your CSS
    ol.Steps {
    	counter-reset: section; // Make sure each new list starts at 1.
    	list-style-type: none;     // Removes the standard numbers.
    	padding: 0;                   // Removes padding so there is no indent.
    	margin-left: 0;               // Removes margin so there is no indent.
    }
    
    ol.Steps li:before {
         counter-increment: section;                  // Defines the counter increment to use.
         content: "Step " counter(section) " - ";  // Adds content before your content.
    }
    
  2. Add your html
    <ol class="Steps">
    	<li>The first thing to do.</li>
    	<li>The second thing to do.</li>
    	<li>The third thing to do.</li>
    </ol>
    

Easy enough.

This is also good when you need any word in front of the number such as: Chapter, Section, Item, etc…

Checking for html errors in your website or blog

So in doing a new web site or blog site, an error can be problematic.  One browser might ignore it, but another can completely be messed up.

You may open your website in Firefox and everything looks fine.  But then you check Chrome, IE, Opera, Safari, and in one or more of them your website looks completed messed up.

How to find html errors in your site

Well, this is where http://validator.w3.org comes in.  This web site will “browse” your website for you and parse the html in your website and report back errors.

  1. Go to http://validator.w3.org.
  2. Enter your URL in the Address text field.
  3. Click Check.

If you have errors they will be displayed, as well as the line number in your html source where the error occurs.

If you don’t have errors you will get a “Congratulations” and also be provided with some code to put on your site to say that your site is checked and “valid”.

Valid XHTML 1.0 Transitional

Being Thorough

For a static website, this is easy.  Check your pages once and since they rarely change, you are good for a long time.

For a blog, this is more complex. To be thorough you would have to check every post. Or only check a post if it is a problem.

Understanding Conditions in Custom Actions and InstallExecuteSequence

If you have ever had to deal with Custom Actions and their Conditions in InstallExecuteSequence, you can get frustrated really quickly. This is not intuitive, though not hard to learn. It definitely is one area that Microsoft could have designed much better, but it is what it is.

The first problem with the design is that it is hard to just read a little bit, and understand. So take a moment and read this all, so you can understand it all.

What is a Feature? What is a Component?

A Feature is a usually a group of Components. The Feature is a part of a product you want to install, at a high level. A Component is a list of install tasks to implement a feature.

Lets look at a use case using a Client/Server application.

Think of an application that has a Server piece, a GUI to manage the server, and a client piece.  When you install, the MSI gives you a check box with those three items and you can install any of the three, or all three on the same machine.  You have three Features.

Feature_1_Server
Feature_2_User_Interface
Feature_3_Client

A Component is a lower lever.  A feature is a list of Components.  So Feature_1_Server might install a list of files and a web service.

C:\Program Files\MyApp\Server\Server.exe
C:\Program Files\MyApp\Common\Common.dll
C:\inetpub\wwwroot\MyApp\Server\WebService.asmx

A Component can only add files to a single path. So because we have two directories above, there will be at least three Components. But we also need to create the web service, so this one Feature has four Components.

Component_1_Server_Files
Component_2_Common_Files
Component_3_WebService_Files
Component_4_WebService

Now if you install Feature_2_User_Interface, you get these files:

C:\Program Files\MyApp\UI\Server.exe
C:\Program Files\MyApp\Common\Common.dll

Notice that the same files in Common are included.  You don’t need to create a new Component for that.

Component_2_Common
Component_5_User_Interface

Install the Feature_3_Client and you see it is similar in the files it installs.

C:\Program Files\MyApp\Client\Client.exe
C:\Program Files\MyApp\Common\Common.dll

Notice that the same files in Common are included.  You don’t need to create a new Component for that.

Component_2_Common
Component_6_Client

Ok, so you have three features, and six components.

What are Conditions?

A Condition is a boolean expression added to a Custom Action to make sure it only runs if the expression returns true.

Imagine you are installing software that has a Server and a Client Feature.  You have a Custom Action that should run for the Server but not for the client.  It needs a condition that follows the logic in the following sentence.

If I am installing the Server Feature, run this action, otherwise, don’t run this action.

Unfortunately MSI doesn’t speak English so while the above sentence helps you understand what needs to be done, the Condition syntax is quite different.

Condition Expression Syntax

The expression is usually in this syntax:

[$|?|&|!][Component|Feature] [bool operator] [-1|1|2|3|4]

Example: If I am installing the Server Feature, run this action, otherwise, don’t run this action.

&Feature_1_Server = 3

Wow, I bet that unless you have some serious experience with MSI Conditions, you are looking at that syntax and shaking your head in confusion. I must admit that I would never have designed this the way it is and I consider it poor design, but again, it is what it is and if we are going to use MSIs, we need to learn this.

Lets break this out into four understandable parts.

  1. [Feature/Component Operator]
  2. [Feature/Component Id]
  3. [Boolean Operator]
  4. [Integer representation of a State]

Let’s cover the four different parts of this syntax.

What is the Feature/Component Operator?

There are only four Feature/Component Operators, all show in the table below.  There are a pair of operators for Features and a pair of operators for Component. So while there are four operators, only three things are determined.

  1. Is this is a Feature of a Component
  2. What is the current *State of the Component or Feature.
  3. What will be the new *State of the Component of Feature when the install completes.

* State is discussed later as it is the fourth item in the Condition syntax but very quickly, State can basically be understood as installed or not installed.

Operator Type State or Action Description Where this syntax is valid How is this commonly used?
$ Component Component – Gets the action that will occur. This is used in front of a Component to get the State change that will occur to the component. Returns a the new State. In the Condition table, and in the sequence tables, after the CostFinalize action. Use this to see if a Component will be installed or uninstalled.
? Component Component – Gets the current state. This is used in front of a Component to get the current state of that Component. Returns the current State. In the Condition table, and in the sequence tables, after the CostFinalize action. Use this to see if a Component is already installed or has not been installed (absent) or was uninstalled (absent).
& Feature Feature – Gets the action that will occur. This is used in front of a Feature to get the State change that will occur to the Feature. Returns a the new State. In the Condition table, and in the sequence tables, after the CostFinalize action. Use this to see if a Feature will be installed or uninstalled.
! Feature Feature – Gets the current state. This is used in front of a feature to get the current State of that feature. Returns the current State. In the Condition table, and in the sequence tables, after the CostFinalize action. Use this to see if a Feature is already installed or has not been installed (absent) or was uninstalled (absent).

$ and & are doing the same task, only for $ is for Components and & is for Features.  These operators are used before a Feature/Component Id to determine the new State, or more clearly, is this Feature/Component going to be installed or uninstalled.

? and ! also do the same task, again the difference is that ? is for Components and ! is for Features.  These operators are used before a Feature/Component Id to determine the current State, or more clearly, is this Feature/Component already installed or not installed.

What is the Feature/Component ID?

The Feature or Component Id is a unique string. In WIX, you create the Features and Components, so you should easily know the ID.  I like to use understandable Feature/Component names, such as Feature_1_Server and Feature_3_Client or Component_1_Server_Files and Component_6_Client_Files.

What is the Boolean Operator?

The boolean operator is any operator that when used in an expression leads to returning true or false. There are quite a few boolean operators that can be used.

  • Comparative Operators
  • Substring Operators
  • Bitwise Numeric Operators

Comparative Operators

There are the basic boolean operators that all languages have.  One difference is that in most languages, = is an assignment operator and == is comparison, but since there is no assignment like that when dealing with Features/Components and States, the = is the comparison operator and == is never used.

Operator Return Value
= Returns TRUE if values on both sides are equals.
<> Returns TRUE if the value on the left side is not equal to the value on the right side.
> Returns TRUE if the value on the left side is greater than the value on the right side.
>= Returns TRUE if the value on the left side is greater than or equal to the value on the right side value.
< Returns TRUE if the value on the left side is less than the value on the right side.
<= Returns TRUE if the value on the left side is less than or equal to the value on the right side.

Substring Operators

Operator Meaning
>< TRUE if left string contains the right string.
<< TRUE if left string starts with the right string.
>> TRUE if left string ends with the right string.

Bitwise Numeric Operators

Operator Meaning
>< Bitwise AND, TRUE if the left and right integers have any bits in common.
<< True if the high 16-bits of the left integer are equal to the right integer.
>> True if the low 16-bits of the left integer are equal to the right integer.

Any of the above operators can be used.

What is a State?

Basically you can think of State was an integer represented Installed or Not Installed.  There are actually five options but the often only two are used:

  • INSTALLSTATE_ABSENT (2) – Means it is Not Installed.
  • and INSTALLSTATE_LOCAL (3) – Means it is Installed.
States Value Meaning
INSTALLSTATE_UNKNOWN -1 No action to be taken on the feature or component.
INSTALLSTATE_ADVERTISED 1 Advertised feature. This state is not available for components.
INSTALLSTATE_ABSENT 2 Feature or component is not present. It either has never been installed, or if it was once installed it has been uninstalled.
INSTALLSTATE_LOCAL 3 Feature or component on the local computer. This feature or component is currently installed on the local computer.
INSTALLSTATE_SOURCE 4 Feature or component run from the source. This feature or component is installed, but files are not local, but on the source. So running this feature may require a mapped drive to the original installation source.

Examples

So now that we understand the parts, lets put it all together with these Examples.

Condition Definition How is this commonly used?
!MyFeature = 2 If MyFeature is not there (Absent) Use this to check if a Feature is not currently installed. It may have never been installed, or it may have been once installed but is now uninstalled. Both never installed and uninstalled result in the term Absent.
!MyFeature = 3 If MyFeature is currently installed Use this on uninstall or upgrade or repair to see if a Feature is already installed.
&MyFeature = 2 If MyFeature is to not be installed (remain absent) Use this to check if a Component is not currently installed. It may have never been installed, or it may have been once installed but is now uninstalled. Both never installed and uninstalled result in the term Absent.
&MyFeature = 3 If MyFeature is to be installed Use this on uninstall or upgrade or repair to see if a Component is already installed.

Component examples would be similar to these Feature examples.

Now that you are this far.  Guess what.  You can combine these two Conditions. Maybe I will post about combining conditions later.

Resources

http://msdn.microsoft.com/en-us/library/aa368012%28v=VS.85%29.aspx

My Blog has moved to a hosted solution with Gigabit Networks

Hey all,

This blog is currently a simple wordpress blog hosted on WordPress.com. It will shortly change to a new website hosted at Gigabit Networks.

One of my goals is to move to a completely BSD or similar licensed solution. I have chosen to have my final site use FreeBSD (OS), Apache (Web Server), Postgresql (DB), Silverstripe (CMS and blog). This will take me a long time.

Step 1 (Complete) – Move my current wordpress blog to a hosted solution that uses FreeBSD. With my blog moving to Gigabit Networks, this step is complete.

Step 2 (Just starting) – Migrate the blog to Silverstripe and postgresql is already in progress, but I expect it will take a year (as I do this in my spare time).

A couple of things to note:

  1. This will come with a new design for my website, so don’t be surprised when you see it. Hopefully it will be a better look.
  2. A couple changes are that my posts will no longer dumped to the home page, but to a Posts page.
  3. Subscribers will have to subscribe again as I will use email subscription “Delivered by FeedBurner.”
    Subscribe to Rhyous by Email

Hopefully this is a smooth transition. If you have any questions, please comment on this post.

C# (Mono) on FreeBSD

Well, if you have read my blog at all, you will realize that I have a developer job writing in C# on Windows, but it is my personal hobby to use FreeBSD.

I am very excited about Mono. I love the C# language. I also love FreeBSD.

I am going to go ahead and say something bold. Few people now realize this yet, but the ability to code in C# on open source platforms is going to be the single most important feature in the coming years. It will eventually be a standard library that will exist or be one of the first items installed on every system.

For more information:

http://www.mono-project.com/Mono:FreeBSD
Packaging for Mono and related applications on FreeBSD (http://www.freebsd.org) is handled by the BSD# Project. The purpose of this project is to maintain the existing Mono/C# ports in the FreeBSD ports tree, port new applications, and work on resolving FreeBSD specific issues with Mono. BSD# is entirely user supported and is not an official FreeBSD or Mono project.

For Licensing information:

http://www.mono-project.com/Licensing

Installing Mono

Mono is a port and as always a port is easy to install on FreeBSD.

Note: The version of mono in ports is not necessarily the latest and greated. I recommend that you install the latest version of mono. See this article.
Installing the latest version of Mono on FreeBSD or How to install and use portshaker?

#
#
cd /usr/ports/lang/mono
make BATCH=yes install

Compiling Hello World in Mono

The mono compiler is gmcs. It is simple to compile C# code.

  1. Create a new file called hw.cs. C# class files end in .cs.
  2. Add this text to the file:
    using System;
    
    namespace HelloWorld
    {
         class HelloWorld
        {
            static void Main(string[] args)
            {
                System.Console.WriteLine("Hello World");
            }
        }
    }
    
  3. Save the file.
  4. Compile the code to create an hw.exe program.
    # gmcs hw.cs

Running a Mono Program

Mono programs must be run using the “mono” command.

# mono hw.exe
Hello World

A Mono IDE: MonoDevelop

There is an IDE for Mono called MonoDevelop. MonoDevelop is a port and as always a port is easy to install on FreeBSD.

#
#
cd /usr/ports/devel/monodevelop
make BATCH=yes install

The Mono Develop port integrated with KDE to add itself to the KDE menu under Applications | Development | MonoDevelop. So you can run it from there.

This IDE allows you to create C# solutions. It is possible to run compile them on FreeBSD and run them on Windows, or compile them on Windows and run them on FreeBSD.

Is It Really Cross Platform

C# and Mono are supposed to be cross platform. So I can write it in Windows using Visual Studio or I can write in FreeBSD using Mono Develop and either way it should run on both Windows and FreeBSD and any other platform that supports mono.

So here are the results of my quick tests:

Test 1 – Does the Hello World app run in Windows.

Yes. I copied the file to a Windows 7 64 bit box and ran it. It worked.

Test 2 – Does a GTK# 2.0 Project run in Windows

No. I created a GTK# 2.0 project on FreeBSD in Mono Develop, and didn’t add anything to it, I just compiled it. I copied the file to windows and ran it. However, it crashed.

Supposedly you have to install the GTK# for .NET on the windows box, but it still didn’t work.

Test 3 – Does a Windows Form Application compiled in Visual Studio 2010 in Window 7 run on FreeBSD

Not at first. I created a basic Windows Form application, and didn’t add anything to it, I just compiled it. I copied it to FreeBSD and ran it. It crashed. However, by default .NET 4.0 is used.

Yes, if compiled with .NET 3.5 or earlier. I changed the project to use .NET 3.5 and tried again. It ran flawlessly.

Test 4 – Does a Windows Presentation Foundation project compiled in Visual Studio 2010 in Window 7 run on FreeBSD

No. There is PresentationFramework assembly so the application crashes immediately. I tried multiple .NET versions.

Note: I didn’t really test much more than the basics. I just created new projects, left them as is and tried them. It would be interesting to see a more fully developed application tested and working on both platform and to know what issues were encountered in doing this.

No WPF

Unfortunately there is no WPF and no plans for it. Of course, WPF stand for Windows Presentation Foundation, and so the who “Windows” part of that might need to be changed to something like XPF, Xorg Presentation foundation.

However since there is Moonlight, which is to Silverlight as Mono is to C# and .NET, and Silverlight is a subset of WPF, I have to assume that WPF will arrive in mono eventually, even if it is by way of Moonlight first.

Oracle Installer: Wow, can you say poor and unprofessional

So I am installing the Oracle client for the first time in my life (Yes, there are still some geek things I haven’t done yet) and wow was I surprised at the poor quality of the installer.

Here is the ugly:

1. I start the install and immediate a big black Command Prompt window comes up.
2. Once it comes up, it tries to install to a c:\app\jbarneck folder. Really? You haven’t figured out C:\Program Files\Oracle yet?
3. I installed only Instant Client. I needed Administrator as well. On reinstall it installed a new second instance of the Oracle Client. No it didn’t work and I have reverted my VM to try again.
4. When you have gone through their wizard and it is time to start the install, you click Finish. Yes, you heard correctly, you click Finish to start. When the install finishes, there is a small line of text letting me know it was successful and a close button.
5. Then I have to go get some text file called a .ORA file and copy it myself.

Anyway. If it was an Open Source project it wouldn’t be this poor. This is something I would have expected in the NT 4.0 days.

So if this is the lack of enterprise quality that I can expect from Oracle, which is a very rich “enterprise”, I will continue to stay away and recommend others do the same.

All I can say is: Wow, Oracle! Get your act together.

FreeBSD Wireless – Configuring a wireless interface on FreeBSD 8.1

FreeBSD Wireless

FreeBSD has strong support for wireless devices. Here is a quick overview of how to manage wireless interfaces on FreeBSD.

Prerequisites

For Wireless access requires the following:

  1. A wireless interface card
  2. wpa_supplicant
  3. An Access Point

Note: In later of versions of FreeBSD, since 2008, wpa_supplicant was included in base. If you are running an older version of FreeBSD, then wpa_supplicant was a port.  So if you are on FreeBSD 8, you have wpa_supplicant.

To complete this guide, we will also use:

  1. A FreeBSD desktop environment.
  2. wpa_gui

Note: wpa_gui is not included in the base system but is found in ports.

Step 1 – Determine what wireless interface card you have

Some wireless cards are built into the kernel, and may already be loaded.  If you know what card you have, skip this step.

  1. First, we need to find out what wireless card you have. Run ifconfig and look at the network cards you have.  Then to see which one is your wireless card, compare them to the wireless kernel module list here:
    http://www.freebsd.org/releases/8.1R/hardware.html#WLAN

    $ ifconfig
    em0: flags=8843 metric 0 mtu 1500
            options=219b
            ether 00:1e:37:d0:91:cb
            media: Ethernet autoselect
            status: no carrier
    lo0: flags=8049 metric 0 mtu 16384
            options=3
            inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
            inet6 ::1 prefixlen 128
            inet 127.0.0.1 netmask 0xff000000
            nd6 options=3

    Notice in the above configuration, no wireless card was discovered. Here is an example of one with a wireless card.

    em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
            options=219b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_MAGIC>
            ether 00:1e:37:d0:91:cb
            media: Ethernet autoselect
            status: no carrier
    iwn0: flags=8843 metric 0 mtu 2290
            ether 00:1e:37:d0:91:cb
            media: IEEE 802.11 Wireless Ethernet autoselect mode 11g
            status: associated
    lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
            options=3<RXCSUM,TXCSUM>
            inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3
            inet6 ::1 prefixlen 128
            inet 127.0.0.1 netmask 0xff000000
            nd6 options=3<PERFORMNUD,ACCEPT_RTADV>
  2. Most wireless cards are PCI devices.  Run pciconf to look for your wireless network card type. This outputs a lot of information, I have snipped my output to isolate only the information about the wireless PCI card.
    $pciconf -lv
    ...
    none1@pci0:3:0:0:       class=0x028000 card=0x10108086 chip=0x42308086 rev=0x61 hdr=0x00
        vendor     = 'Intel Corporation'
        device     = 'Intel Wireless WiFi Link 4965AGN (Intel 4965AGN)'
        class      = network
    ...
  3. Now go to the current release notes for FreeBSD and look through the wireless kernel modules to see which one supports your hardware.
    http://www.freebsd.org/releases/8.1R/hardware.html#WLAN

    Note: I searched for 4965AGN and found my kernel module immediately.
  4. Keep the link open as you move to Step 2.

Step 2 – Make sure the kernel module is loading

If your wireless card is already detected and loading, skip this step.  If not, configure /boot/loader.conf to load your wireless card.

  1. Read the man page for your wireless kernel module, there is a link to it in the hardware notes, to see any special information about loading the kernel module for your kernel module.
  2. Configure the /boot/loader.conf to load the kernel module and make any other required settings to use the kernel module.Example 1 – The Intel iwn kernel module requires a line to load the kernel module and a second line to load the firmware.
    # Wireless
    if_iwn_load="YES"
    iwn4965fw_load="YES"

    Example 2 – The Intel iwi kernel module requires that you accept a license agreement:

    # Wireless
    if_iwi_load="YES"
    legal.intel_iwi.license_ack=1
  3. Save and close the /boot/loader.conf
  4. Now you can either reboot, or you can use kldload to load the kernel modules without rebooting.

Step 3 – Configure the wireless settings in /etc/rc.conf

The rc.conf is where the wireless network card is configured.

  1. In FreeBSD 8 and later, all wireless interfaces should be configured to use the generic wlan device. Then to enable wpa_supplicant, the wlan should be configured to use WPA.
    To make these configurations, add these lines to the /etc/rc.conf.

    wlans_iwn0="wlan0"
    ifconfig_wlan0="WPA DHCP"
  2. Save and close /etc/rc.conf.

Step 4 – Add your Access Point’s (AP) SSID to your /etc/wpa_supplicant.conf

There is a lot of information on how to add an SSID to your /etc/wpa_supplicant.conf file in the man page for wpa_supplicant.conf. But the process is simple.

  1. If you don’t know the SSID, discover or scan for the SSID by running ifconfig wlan0 scan.  Below is an example.
    $ ifconfig wlan0 scan
    SSID/MESH ID    BSSID              CHAN RATE   S:N     INT CAPS
    MyWifi          00:20:e1:96:54:32    6   11M -75:-95  100 E
    OpenNet         da:ce:41:d3:af:3a    6   54M -85:-95  100 IS
    MyWPA           00:24:7b:6b:71:27    1   54M -89:-95  100 EP   RSN WPA WPS
                    00:00:00:00:00:00    1   54M -89:-95  100 E
  2. Now add a network entry for the desired wireless device.  Examples are below:

    Open or no authentication

    network={
            ssid="MyWifi"
            key_mgmt=NONE
    }

    WPA or WPA2

    network={
            ssid="MyWPA"
            psk="SomeP@sswd!"
    }

    More examples

    For more examples, read the man page for wpa_supplicant.conf.

    $ man wpa_supplicant.conf

    Once the SSID is configured properly in the /etc/wpa_supplicant.conf, then an automatic connection to this AP will occur whenever the device is within range.

Step 5 – Install wpa_gui from ports

Often you don’t always know what wireless you are going to connect to and also often you don’t care to store the SSID configuration permanently in the /etc/wpa_supplicant.conf. This is common if you are getting online at an airport, coffee shop, or any hotspot that you don’t frequent. It would be nice to have a graphical interface that shows you the SSIDs available, allows you to connect, but doesn’t store the information. wpa_gui is this tool.

  1. Install wpa_gui from ports
    # cd /usr/ports/net/wpa_giu
    # make install
  2. Add the following two lines to the top of the /etc/wpa_supplicant.conf.
    ctrl_interface=/var/run/wpa_supplicant
    ctrl_interface_group=wheel
  3. Restart the wpa_supplicant.# /etc/rc.d/wpa_supplicant restart wlan0
  4. Run wpa_gui.
    $ wpa_gui
    Selected interface 'wlan0'
    Trying to connect to '/var/run/wpa_supplicant/wlan0'

    wpa_gui opens.

  5. Click Scan and a window listing the available SSIDs appears.
  6. Double-click on an SSID to get the configuration windows.  It will try to select the correct settings as best it can, so often you only need to add the psk or passkey, which is essentially a password.
  7. This will connect you to that SSID.

Note: If you do want to save the networks to the wpa_supplicant.conf by default, then add this line. Otherwise, they are not saved. You may or may not want them to be saved.

update_config=1

Additonal Notes

Note 1: PC-BSD has a network configuration tool, so if you are running PC-BSD, wpa_gui is not necessary.

Note 2: There is a command line tool called wpa_cli that is included in the base system.  wpa_cli is useful if you don’t have a graphical environment.

Note 3: I also configured link aggregation, or lagg, so my wired and wireless interfaces share the same MAC.

ifconfig_em0="up"
ifconfig_iwn0="`ifconfig em0 ether`"
ifconfig_iwn0="ether ${ifconfig_iwn0##*ether }"
wlans_iwn0="wlan0"
ifconfig_wlan0="WPA"
cloned_interfaces="lagg0"
ifconfig_lagg0="laggproto failover laggport em0 laggport wlan0 DHCP"

Resources

http://www.freebsd.org/doc/handbook/network-wireless.html
http://www.freebsd.org/releases/8.1R/hardware.html#WLAN
man wpa_supplicant
man wpa_supplicant.conf
man iwn
man iwi


Copyright ® Rhyous.com – Linking to this page is allowed without permission and as many as ten lines of this page can be used along with this link. Any other use of this page is allowed only by permission of Rhyous.com.