Tuesday, June 24, 2008

Watch Out: Window.ObjectKind is UPPER CASE!

Using Windows2.CreateToolWindow2() to create a VisualStudio addin tool window? If you do, then maybe you want to check how often it is called during the life cycle of your addin. And if you notice that you create it twice, you may want to avoid that by checking the collection EnvDTE80.Windows. If your tool window is already contained you don't want to create a second instance of your tool window. There is a possible surprise, though. Windows2.CreateToolWindow2() expects as the fifth parameter a guid. The online documentation (see here) says it is the "GuidPosition". This is a little misleading since it doesn't really refer to a position. In reality it is the type of the tool window, e.g. the Solution Explorer. Now, when you create the boiler plate code you may just use the example given there. If you do, then change the content of the variable guidpos given in the code to all upper case. So the important bit is the following change:
string guidpos = "{426E8D27-3D33-4fc8-B3E9-9883AADC679F}";
string guidpos = "{426E8D27-3D33-4FC8-B3E9-9883AADC679F}";

I've highlighted the important bit with red color, bold, and a larger font. In addition I have underlined it. I think you got the idea. Why is this change important? Assume you iterate over the collection as follows:
foreach(Window2 toolWin in toolWins) {
string toolWinKind = toolWin.ObjectKind;
if( toolWinKind.Equals(guidString) ) {
 _toolWindow = toolWin;
The Equals() call may always result in 'false' even if you think you are looking at the correct tool window. The reason is that ObjectKind returns the guid all upper case. The example code has two lower case characters in the guidpos variable. The same can also happen when you use "Create GUID" from the "Tools" menu in Visual Studio. It may generate a guid for you with one or more lower case digits ('a' through 'f') as well. It's unfortunate that the online documentation doesn't mention that some time between calling CreateToolWindow2() and calling ObjectKind everything is made upper case. The example code leads to potentially incorrect behavior of your addin as well. This post gives you the heads-up. It took me quite some time to spot this little difference. In my case it was 'f' versus 'F' and only when Equals() insisted on returning false I took a closer look. Maybe this helps you saving some development time. And maybe someone from Microsoft is reading this. I tried to add it as Community Content at MSDN. It wasn't possible. So I rated the article and left a comment adding the suggestions for improvement. This would have been ideal for "Community Content". MSFT, you mind updating the online material? Thank you!

Thursday, June 19, 2008

csUnit: What's Next?

csUnit 2.5 is very well received but since we are always trying to find improvements I'd like to share a couple of items that we plan for the next version. For one, the performance has slightly slipped. Some new features resulted in an runtime penalty which we believe has become too high. So we did some performance analysis and have found ways to get a performance improvement of about 10% to 30% of the next version over version 2.5. Both the command line version and the GUI version benefit from this improvement. The other area we didn't like too much was the slightly cluttered user interface on the test hierarchy tab, which is the most frequently used view in the tool. In addition the search feature on the test hierarchy tab worksfor the test hierarchy only. This is a limitation. So we decided to revisit the search feature. The next version will therefore have a new search feature that works across all tabs. And at the sime time we were able to remove the related buttons from the test hierarchy page and replace them with a single button in the already existing toolbar. This freed up screen real estate for the important information and also simplified the appearance. These are just two of the improvements you will see in the upcoming version 2.6 of csUnit, which we are planning for August. Stay posted. If you'd like to participate in determining the future of csUnit then please don't hesitate to contact me or anybody else of the csUnit team.

Saturday, June 14, 2008

Vista: Finding Encrypted Files

To find encrypted files on Windows Vista do this:
  1. Open a command prompt and switch to a directory in which you have write permissions.
  2. Run the command: "cypher /s:c:\ /N /U > filelist.txt" and wait until finished (this example searches the entire volume c:
  3. When finished open the file filelist.txt. It contains a list of all files that are encrypted.
  4. In the Explorer window navigate to each file and though "Properties" -> "Advanced..." goto to the "Advanced Attributes" page and remove the checkmark from "Encrypt contents to secure data"

Tuesday, June 10, 2008

Addin Command Names

What is the name of a command when you register it for an addin? Typically you use Commands.AddNamedCommand() to register a command. The second parameter is the command name. Now, when you want to look up a command you can use _DTE.Commands using the name you used for AddNamedCommand() and you're done. Right? Wrong! Let's take the csUnit addin for Visual Studio as an example. The addin has the name csUnit.csUnit4VS2005.Connect. This is the class that implements the interface Extensibility.IDTExtensibility2. This interface includes members such as OnConnection(), OnDisconnection(), etc. This full name - 'csUnit.csUnit4VS2005.Connect' - is also used in the addin file (see node Extensibilily / Addin / FullClassName). What VS 2005 and VS 2008 do is this: When you register a command, the name of the command will be automatically prefixed with the name of the addin. So in this case a csUnit command named Foo would turn into csUnit.csUnit4VS2005.Connect.Foo. Be aware of this. Otherwise your code may not be able to find your command in _DTE.Commands.