2010-04-16

Moved to www.selfelected.com

I have moved this blog to http://www.selfelected.com/

Happy hacking!

2010-04-12

Visual Studio 2010 installation

If you get
---------------------------
Microsoft Visual Studio 2010 Ultimate Setup
---------------------------
Some components must be installed in c:\Program Files\Microsoft Visual Studio 10.0\ directory. Check that you have write permissions and enough space in that directory.
---------------------------
OK
---------------------------
when you try to install Visual studio 2010; don't despair.
There is a big chance you try to install from a mounted virtual disc.

The resolution is to copy the files in the mounted disk to real files and run it from there. One could possibly also assign the mounted disk a letter but I haven't tried this.

I have learned that there is also some problem when installing from a network share. The symptom is something about a .cab file with a faulty digital signature.

2010-03-16

Coderush and camelCase and select

I am a long time fan of DPack. Some time ago Coderush stepped up to a must-have.

The other day I noticed that Coderush did camel case selection. It is like this:
Open the Vsnet editor with your favourite project and go to a camelCased or PascalCased word. Select it with ctrl-shift-right/left. This is old news.
Now instead use alt-shift-right/left; only a part of the word is highlighted. Perfect when copy-pasting variables like CustomerName and SerialNumber.

Coderush comes both in gratis and pay versions.

2010-03-15

Aspnet MVC 2 starter project compilation error

When starting your first Aspnet MVC2 project you might immediately run into compilation errors like these:

Error 1 The type or namespace name 'Controllers' does not exist in the namespace 'MvcApplication1' (are you missing an assembly reference?) C:\myprojectpath\MvcApplication1.Tests\Controllers\HomeControllerTest.cs 8 23 MvcApplication1.Tests

Error 3 The type or namespace name 'Models' does not exist in the namespace 'MvcApplication1' (are you missing an assembly reference?) C:\myprojectpath\MvcApplication1.Tests\Controllers\AccountControllerTest.cs 10 23 MvcApplication1.Tests

Error 4 The type or namespace name 'AccountController' could not be found (are you missing a using directive or an assembly reference?) C:\myprojectpath\MvcApplication1.Tests\Controllers\AccountControllerTest.cs 317 24 MvcApplication1.Tests



The origin of the problem is that the test project doesn't reference the web project. Just add the reference and you're good to go.

I haven't found the solution on google yet so I write this here to someones possible future aid.

2010-03-04

Checking events in VBNet

Due to some reason unknown to man the team behind VBNet decided that the developer should not be able to see if someone listened to your event or not. It is good in most cases but very bad in another.

In Csharp raising an event goes something like this:
var ev = MyEvent;
if( null != ev ){ ev( this, args ); }


Just look through the snippets (look in the context menu in the editor) and you will find the correct way to raise an event in Csharp.

VBNet on the other hand hides the if statement and the temporary variable from the developer. It is enough to write
RaiseEvent Me, args
and the event will be raise if there is someone listening - no need to check for null.

But what if you want to check if someone is listening. In my case I needed to know if the custom control was properly wired into the scaffolding of the application; the user control sometimes whished for more information and I had to know if someone was listening.
In Csharp this would have been easy with a check for null. But VBNet...

The solution is hidden. Just check the variable "MyEventEvent". This means that your MyClick event has a hidden variable MyClickEvent that you can check for like this:
If MyClickEvent IsNot Nothing Then

I don't like to use hidden and unoffical solutions but this is the only way I know of.

Honor those who should.

Selfelected - ideas

I just started another blog which only presents ideas yet to be implemented.
http://selfelected.wordpress.com/
Feel free to implement anyone of them.

2010-02-04

DesignMode in Visual Studio, inheritance, process name and a work around

The text and code below is only tested for Winform. WPF might behave differently; hopefully behaves differently.

I won't go into any details on why the ISite.DesignMode is good and sometimes even crucial to have. It is much better done in the link at the bottom.

First out there is unfortunately a caveat with DesignMode, it doesn't work with inherited forms and user controls. This is a problem since I always inherit from the base form in my projects and tell others to do the same. It also doesn't work inside the form's or the user control's constructor and then by any method that is called by the constructor. Long call chains to might make this hard to track down.
Secondly there is another way to check for design mode and that is to check for the LicenseManager.UsageMode but this in turn doesn't work in event handlers.
Thirdly one can set a flag in the base Form and base UserControl. But this doesn't solve the problem since we cannot be sure with what to set this value.
Fourthly is a workaround where one can check for the name of the process itself which is Visual Studio's process name (devenv) in case of design mode. This process name might change in future releases of Visual Studio and is also different for other IDEs.
Fifthly is other process information like the name of the module and stuff. Check into the Process and you'll see that the app is called MyApp.vshost.exe while being debugged.

The fourth solution (processname=devenv) seems to be the most viable but I believe there is something useful in the fifth (other process information). There must be a way to notice that the name of all your code doesn't match the name of the running environment; namespace, assembly name, whatever. I still haven't figured out how though.

Below is some code to copy-paste.
It is not 100% correct though since the DesignMode property isn't virtual. This might end with some really tough-to-track-down bugs where one iterates the forms but don't get the overloaded DesignMode flag. The code also doesn't promise to work forever since there is a magic string naming the name of the Visual Studio process.


public partial class MyAppForm : System.Windows.Forms.Form
{
protected new bool DesignMode
{
get
{
return HelperMethods.IsDesignMode(this);
}
}
}

public partial class MyAppUserControl : UserControl
{
protected new bool DesignMode
{
get
{
return HelperMethods.IsDesignMode(this);
}
}
}

class HelperMethods
{
public static bool IsDesignMode(System.ComponentModel.Component x)
{
var site = x as System.ComponentModel.ISite;
return
( null == site ? false : site.DesignMode ) ||
System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime ||
System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv";
}
}
The code above is also in pastebin for easier copy-paste.
A good article is here: http://dotnetfacts.blogspot.com/2009/01/identifying-run-time-and-design-mode.html
There is a description of how to debug this here: http://brennan.offwhite.net/blog/2006/08/30/design-time-debugging-aspnet-20-in-visual-studio-2005/

2010-01-28

Share a file in Visual Studio

I didn't think it was possible but it has been for years; to share a file between projects in a solution.

Add a file the normal way but instead of pressing Open, use the little dropdown arrow next to.  Then you have the possibility to "link" instead of "add".

This makes it possible to have one and only one file for many places.  It can be a source code file or a readme or anything really.
I have yet to try it with TFS and SVN to make sure it doesn't mess upp the version management.

Honor those who should.

On a side note: Sourcesafe has linking ability within itself.  I miss it in TFS.  Though: It is easy to lose the master file and keep copies wich makes strange icons.  It also doesn't play well with the VB6 editor when a file will be checked out and another not, but they should be, but the VB6 ide doesn't understand it and you have to do an explicit checkout and... never mind.  It was a long time ago.

2010-01-24

Changed keyboard settings

In Windows 7 (and possibly Vista) the keyboard layout is sometimes changed back to some sort of default.

The problem shows itself like this - I use the 1337 keyboard layout in Visual Studio.  Then without warning the keyboard layout changes to US layout; a layout I don't even have installed.  The 1337 layout is based on US though so somehow it shines through.

To get back to 1337 I choose "Open the language bar" in the systray context menu.  The language bar then pops up in another place (top of screen for me) and I can then choose keyboard layout.

The problem will reappear more times until I reboot again.

2010-01-16

Get calling method's name automatically in dotnet

Way too many times have I written

void MyFunction( int aNumber)
{
MyHomemadeLogClass.Logg( "MyFunction", "aNumber=" + aNumber.ToString());
...
}
to get logging functionality.

It would be so nice to just write

void MyFunction( int aNumber)
{
MyHomemadeLogClass.Logg();
...
}
It is no hard to do. Use reflection to get the call stack to get to the method and the parameters. Convert all this to a readable string.
Unfortunately it is not that easy to log the contents of the parameters, one has to get into some sort of debugger area to do that.

class ReflectionUtility
{
private static System.Reflection.MethodBase GetCallingMethod()
{
return new System.Diagnostics.StackTrace().GetFrame(2).GetMethod();
}
public static string GetCallingMethodFullNameReturnParametertypes()
{
return MethodFullNameReturnParametertypes(GetCallingMethod());
}
private static string MethodFullNameReturnParametertypes(System.Reflection.MethodBase method)
{
return string.Format("{0} {1}.{2} ({3})",
((System.Reflection.MethodInfo)method).ReturnType, // System.Void, System.Int32 etc.
method.DeclaringType.FullName, // MyNamespace.MyClass.
method.Name, // MyMethod.
string.Join(",", method.GetParameters().Select(p => p.ParameterType.ToString() + " " + p.Name).ToArray()) // () or (int) or (int,string) etc.
);
}
}
To use this in a Logging class one must implement a GetCallingCallingMethod or even worse, but it would make this example hard to read.

One can use the Conditional attribute to avoid the call when not debugging.

I also put the code on pastebin to make the copy-paste easier. (I have yet to find a good way to present code.)