MZ-Tools Articles Series: HOWTO: Change the build platform of a project from a Visual Studio add-in

And the final chapter of this series about to create solution configurations, project configurations and project platforms, and the lack of support to create new solution platforms, and how to change project configuration, is about changing the project platform for a given solution platform, something that had to wait 3 versions of Visual Studio (2005, 2008, 2010) until support was added in VS 2012:

HOWTO: Change the build platform of a project from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013014.aspx

PRB: Cannot change the build platform of a project from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013015.aspx

Posted by carlosq | 1 comment(s)

MZ-Tools Articles Series: HOWTO: Change the build configuration of a project from a Visual Studio add-in

Once we learned how to create solution configurations, project configurations and project platforms, and the lack of support to create new solution platforms, the next thing is to be able to change the project configuration for a given solution configuration. Alas, this is possible in VS 2005 and 2012 but VS 2008 and 2010 have a bug that ruins the attempt:

HOWTO: Change the build configuration of a project from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013012.aspx

BUG: Build configuration of a project cannot be changed from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013013.aspx

 

Posted by carlosq | with no comments

Book review: Continuous Integration in .NET

Manning Publications provided me a free electronic copy of their book "Continuous Integration in .NET" that I was interested in. If you have started with automated unit testing, continuous integration (CI) is the next major step to increase the quality of the software that you deliver.

This book is excellent to get you introduced in CI for .NET and to get started with a set of tools (not only from Microsoft) such as:

  • CruiseControl.NET, TeamCity and Team Foundation Server (2010) as CI servers
  • MS build as build automation tool
  • NUnit, MS Test as unit testing framework
  • PartCover as test coverage tool
  • White, Selenium and FiNesse for integration, functional, acceptance tests
  • FxCop (Code Analysis), NDepend for compiled code analysis
  • StyleCop for source code analysis
  • Sandcastle as documentation generation tool
  • MS Setup, WiX and MS Deploy as setup / deployment tools
  • Etc.

I read programming books on a Kindle app for iPad / iPhone rather that on a computer, so I appreciate that the book is easy to read, with handy screenshots that avoid you to install/use the tools on a computer to get the idea about them.

The book covers the basics of each area and tool, detailing some good and not so good things of each tool, and providing examples of use with a sample project. If you have decided that you are going to stick to free tools, you can skip some sections (and the same applies if you have decided to use only Microsoft tools).

But once you have decided which of the above area(s) of CI and tools you are going to use, likely you will need other books/docs to get deeper. For example, for unit testing I recommend The Art of Unit Testing, also from Manning, but wait until the second edition is published. If you decide to use Team Foundation Server (TFS) version 2012, I recommend the free book Testing for Continuous Delivery with Visual Studio 2012. For other tools, you will need to use the documentation of the product.

The book is also a good resource to get your team introduced to CI is that is your scenario. Many developers tend to be much more focused on the code / manual testing than on automated testing, let alone on continuous integration which maybe they ignore at all. Maybe with books like this they realize the spectrum of things that can be done automatically and in a continuous fashion.

Posted by carlosq | with no comments

MZ-Tools Articles Series: HOWTO: Add / delete build project platforms from a Visual Studio add-in

After learning how to add / delete build project configurations from a Visual Studio add-in, the counterpart to do the same with project platforms:

HOWTO: Add / delete build project platforms from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013011.aspx

This article completes the creation / deletion of solution configurations, solution platforms, project configurations and project platforms. In the next articles I will show how to change programmatically the project configuration/platform for a given solution configuration/platform, along with some issues doing it.

Posted by carlosq | with no comments

MZ-Tools Articles Series: HOWTO: Add / delete build project configurations from a Visual Studio add-in

The next article of the convoluted build configuration automation model (EnvDTE/EnvDTE80) and its diagram is about adding or deleting project configurations programmatically:

HOWTO: Add / delete build project configurations from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013010.aspx

Posted by carlosq | with no comments

MZ-Tools Articles Series: PRB: Build solution platforms cannot be added / deleted from a Visual Studio add-in

The convoluted build configuration automation model (EnvDTE/EnvDTE80) and its diagram was already so tricky to add / delete solution configurations that it has to explode from some angle: the lack of direct (*) support to add / delete solution platforms:

PRB: Build solution platforms cannot be added / deleted from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013009.aspx

(*) There is a kind of workaround creating project platforms propagated as new solution platforms (via EnvDTE.ConfigurationManager.AddPlatform(newName, existingName, true) that I will explore in a new post / article.

Posted by carlosq | with no comments

MZ-Tools Articles Series: HOWTO: Add / delete build solution configurations from a Visual Studio add-in

The next article about the convoluted build configuration automation model (EnvDTE/EnvDTE80) and its diagram series of articles that I have started shows the code to add or delete solution configurations from a Visual Studio add-in. The deletion approach of the automation model has a hidden trap explained in the article and code:

HOWTO: Add / delete build solution configurations from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013008.aspx

Posted by carlosq | with no comments

MZ-Tools Articles Series: HOWTO: Get or set the active solution configuration/platform from a Visual Studio add-in

After explaining how to get information about the solution and project configurations/platforms, it's time now to know how to modify them. The most common question about this is how to change the active solution configuration / platform:

HOWTO: Get or set the active solution configuration/platform from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013007.aspx

Posted by carlosq | with no comments

MZ-Tools Articles Series: HOWTO: Get the project configurations / platforms from a Visual Studio add-in

Continuing with the convoluted build configuration automation model (EnvDTE/EnvDTE80) and its diagram series of articles that I started yesterday, today a new installment about how to get the information about the build configuration / platforms for a given EnvDTE.Project from a Visual  Studio add-in:

HOWTO: Get the project configurations / platforms from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013006.aspx

Posted by carlosq | with no comments

MZ-Tools Articles Series: HOWTO: Get the solution configurations / platforms from a Visual Studio add-in

Long time ago I wrote about the convoluted build configuration automation model (EnvDTE/EnvDTE80) and its diagram. Since questions about this keep appearing in the MSDN VSX Forum, I am going to write some articles about how to get/modify/add solution/project configurations/platforms. 

The first one is about how to get the information of the Configuration Manager from a Visual  Studio add-in:

HOWTO: Get the solution configurations / platforms from a Visual Studio add-in
http://www.mztools.com/articles/2013/MZ2013005.aspx

Posted by carlosq | with no comments

Book review: The Art of Unit Testing, 2nd edition (Roy Osherove)

After buying and reading the book Dependency Injection in .NET (Mark Seemann), I was about to buy The Art of Unit Testing (Roy Osherove), when I learned that the second edition will be available in a couple of months. I contacted Roy and Manning Publications Co were kind enough of providing me a complimentary copy of the Early Access Edition of The Art of Unit Testing, Second Edition, which I have read avidly in the last few days.

I was interested in the book because while I had worked with automated testing for the version 7.0 of my MZ-Tools add-in, I was not sure if I was doing it properly and I wanted to learn about integration testing / unit testing, the difference between fakes, mocks and stubs and the best practices. After reading the book, there is no doubt that Roy knows the stuff, and explains everything to make it clear:

- Part 1 explains the basics of unit testing and a first unit test.

- Part 2 explains the three kinds of testing: result testing, state testing and interaction testing, and how stubs are used for result / state testing and mocks are used for interaction testing. The last chapter of this part (and the first chapter of the next part) explains isolation (mocking) frameworks (as well as appendix B). It seems that not all isolation frameworks are created equal (constrained vs unconstrained) and the book explains quite well how they differ.

- Part 3 has one chapter to dig deeper into isolation frameworks and two chapters that I was very interested in: test hierarchies/organization and the pillars of good unit tests. The book puts an enormous effort in the importance of writing tests that are 1) Trustworthy 2) Maintainable and 3) Readable, and I couldn't agree more because I have written tests that don't follow those principles... this part of the book provides tons of good practices to the point of almost reaching perfectionism.

- Part 4 has two chapters: one devoted to integrating unit testing into the organization and other to working with legacy code (lacking unit testing). It is sad that books have to have such chapters because many developers and managers don't see the value of automated testing, thinking only about the short term costs and not about the QA in the long term. But since this is the reality, this part can help you a lot in that case.

I have enjoyed the book a lot. It seems that as part of his consulting job, Roy has seen tons of bad practices (as any team leader has seen with any kind of code, sadly) and this edition is a new attempt to explain developers how to become artists of unit testing. If they fail, it won't be because of this excellent book.

Posted by carlosq | with no comments

Book review: Dependency Injection in .NET (Mark Seemann)

After hearing about Microsoft Unity from the .NET architects at my current company (my daily job), I bought the book Dependency Injection in .NET, by Mark Seemann some weeks ago to learn dependency injection and Inversion of Control (IoC) containers, just for curiosity because I thought it wouldn't apply to my MZ-Tools add-in, or to Visual Studio extensions. I couldn't be more wrong. I think this is the book that more profoundly has changed my mindset about creating software , because the concepts of programming against interfaces and loose coupling (explained in part 1 of the book) are one of the most important things that you need to master as a developer to create maintainable software, as now I have realized. Dependency Injection (DI) is the means to achieve loose coupling. The second part of the book explains DI patterns, anti-patterns and refactorings. The third part explains the three dimensions of DI: object composition, object lifetime and interception. The fourth part explains several DI containers of the many ones available for .NET. As the book explains, DI containers are optional, but even if you don't use them, the software will benefit a lot from a loose coupled design.

How does this relate to developing Visual Studio add-ins? After reading the book I have realized that in my case in at least three aspects, and I wish I had read the book before:

1) Visual Studio add-ins hold a tight coupling with some dependencies such as the EnvDTE.dll, EnvDTE80.dll and VSLangProj.dll assemblies, that provide the automation model for add-ins. In all likelihood, all the features of your add-in depend on EnvDTE.Solution, EnvDTE.Project, EnvDTE.EditPoint, etc. Imagine now that you have to migrate your add-in to a Visual Studio package (SDK), because Microsoft plans to remove add-ins. It would be much easier if the features of your add-in would depend only on interfaces such as ISolution, IProject, IEditPoint that are implemented by classes that encapsulate the automation model for add-ins (EnvDTE.Solution, EnvDTE.Project), and later by classes that encapsulate the SDK services of packages (IVsSolution, IVsProject).

2) A loose coupled design and dependency injection allows to use unit testing more easily. Automated testing for add-ins is hard. So far I had done integration testing (with my own test runner), which while it is automated, it is slow and can't be integrated easily with continuous integration (CI). Now I want to use unit testing too (because of the fast speed) through stubs, but since I haven't used dependency injection I am finding problems to achieve a clean approach.

3) MZ-Tools 8.0 will support Visual Studio, VB6 and VBA as hosts. I am encapsulating the very different automation models with concrete classes such as SolutionEx, ProjectEx, etc. using partial classes and conditional compilation. But after reading the book I have realized that it would be better to use either interfaces or abstract classes.

I will try to find time to write a series of posts with code about using loose coupled design and dependency injection developing add-ins for Microsoft IDEs. Stay tuned.

Posted by carlosq | with no comments

Microsoft "expecting to remove add-ins from Visual Studio in a future version". Will they be in Visual Studio 2013 announced today?

According to the answers to my last two bugs reported yesterday about add-ins on Microsoft Connect:

"Addins are an old technology that we are advising customers to move away from. We expect to remove this from the product in a future version."

Macros were gone in Visual Studio 2012, and it seems that add-ins will be gone in "a future version". Coincidentally, Visual Studio 2013 has been announced today (you can read the announcement in Brian Harry's blog and Somasegar's blog). Now the intriguing question is for those of us with a heavy investment in add-ins such as MZ-Tools is: will VS 2013 support add-ins or will we be forced to migrate to packages (SDK)?

Posted by carlosq | with no comments
Filed under:

MZ-Tools Articles Series: BUG: Error ocurred in add-in wizard if add-in project created inside solution folder

Don't you like when you find two bugs in a row? Apart from this other bug, I also found this one using the add-in wizard of Visual Studio, and again the curious part is that it worked in Visual Studio 2005, but was broken in Visual Studio 2008 and the bug persists.

I have reported to Microsoft Connect:

Error ocurred in add-in wizard if add-in project created inside solution folder:
https://connect.microsoft.com/VisualStudio/feedback/details/789324/error-ocurred-in-add-in-wizard-if-add-in-project-created-inside-solution-folder

and I have documented in the MZ-Tools Series articles:

BUG: Error ocurred in add-in wizard if add-in project created inside solution folder:
http://www.mztools.com/articles/2013/MZ2013004.aspx

Posted by carlosq | with no comments

MZ-Tools Articles Series: BUG: Checkbox to create CommandBar disabled in add-in wizard if name contains '.'

I have created tons of add-ins in the last years using the add-in wizard of Visual Studio, and the other day I wanted to use a project name with a '.' dot character in the name. I noticed this bug that I have reported to Microsoft Connect:

Checkbox to create CommandBar disabled in add-in wizard if name contains "."
https://connect.microsoft.com/VisualStudio/feedback/details/789323/checkbox-to-create-commandbar-disabled-in-add-in-wizard-if-name-contains

and I have documented in the MZ-Tools Series articles:

BUG: Checkbox to create CommandBar disabled in add-in wizard if name contains '.'
http://www.mztools.com/articles/2013/MZ2013003.aspx

The curious part is that it worked in Visual Studio 2005, but was broken in Visual Studio 2008 and the bug persists.

Posted by carlosq | with no comments

MZ-Tools Articles Series: HOWTO: Get the full browse URL of an .aspx page

I wrote some years ago HOWTO: Open the Web Browser and navigate to a page from a Visual Studio add-in or macro (http://www.mztools.com/articles/2008/MZ2008012.aspx). The other day someone asked in the MSDN VSX forum how to show an .aspx page in the browser programmatically, which is easy if you can get the full browse URL of the .aspx page. It happens that the ProjectItem class of Web Site projects and Web Application projects has different ways of getting / composing the browse URL, so I have written an article with sample code about this:

HOWTO: Get the full browse URL of an .aspx page
http://www.mztools.com/articles/2013/MZ2013002.aspx

Posted by carlosq | with no comments

Debugging .NET Framework working only "sometimes"

I am these days (well, nights) debugging an extremely difficult issue with the ImageList control and I had that idea that debugging the .NET Framework (source step) would help a lot. That feature was introduced in VS 2008 and my feeling these years when I tested it from time to time was that sometimes it worked, sometimes it didn't. Yesterday that I needed it badly I searched the web and I discovered that I was not alone. There are tons of issues and workarounds about it. I tried all them to no avail.

Finally someone from Microsoft posted here (only a few weeks ago after all these years!) that the root cause is out-of-date PDBs, and that it is going to happen each time that Microsoft releases a new build of an assembly, which is not only in service packs but also any security patch. Since there is cadence between the release of the assembly and the release of the PDB (that has been up to 1 year in the past!), this feature is basically broken, bad designed.

The alternative, suggested strongly by that guy, is to use .NET Reflector, a paid tool which for developers of Visual Studio extensions is even more useful to debug Visual Studio assemblies (not just .NET Framework assemblies) as I explained in this guest post on their blog.

Posted by carlosq | 1 comment(s)

Msaddndr.dll file officially not installed by Microsoft Office 2013

As I posted back in November, the setup of an add-in for the VBA editor of Office 2013 written with VB6 could fail with the following error:

"Unable to register DLL/OCX:RegSvr32 failed with exit code 0x5"

I mentioned that the cause was that the file Msaddndr.dll is no longer installed by Office 2013 and today I have found that Microsoft wrote an official Knowledge Base (KB) article stating it a month later:

A custom add-in that uses interfaces in the Msaddndr.dll file does not work in Office 2013
http://support.microsoft.com/kb/2792179

The workaround is, of course, that your setup installs that file. BTW, I got yesterday a bug report from a user of my MZ-Tools 3.0 for VBA with that same error but using a MZTools3VBASetup.exe that already (supposedly) installed the file. It happened that the system already had that file installed, but an old version, and the setup only installed it if not present, so it was not replaced by the newest version. So, when applying this workaround, ensure that your setup installs the file if not present, or if it is an older version, because it seems that there are at least two versions of Msaddndr.dll out there.

 

Posted by carlosq | with no comments
Filed under:

Windows PowerShell scripts to register a .NET-based add-in for a COM-based host application

Before Visual Studio 2005 introduced XML-based registration for add-ins with an .AddIn file (which enabled X-Copy deployment), add-ins for Microsoft applications required two steps to be registered:

  • To register the add-in dll as ActiveX (COM) component
  • To register the add-in dll as add-in for the host application through some registry entries

This is still true for COM-based add-ins for Visual Studio (any version) and for other hosts such as Microsoft Office or its VBA editor which only support COM-based add-ins.

Some months ago I wrote how to create a COM add-in for the VBA editor of Office using .NET, which is almost the only way to create an add-in for the VBA editor of Office 64-bit, since it doesn't support 32-bit COM add-ins.

I am working since some months ago on a .NET-based version of my MZ-Tools add-in for the VBA editor of Office 32/64-bit and I always wanted a single script to perform the two steps above. This was a nice excuse to learn Windows PowerShell, so I bought a book and after reading some chapters to get the concepts today I decided to create the scripts that call regasm.exe to register the .Net assembly for COM-Interop and create the registry entries for the add-in to be recognized by the VBA editor:

1) This is the content of a file named Functions.ps1 which contains reusable functions:

# To run .ps1 scripts you need to execute first: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Regasm32 = 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe'
$Regasm64 = 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm.exe'

function Register-Assembly32([string]$Assembly, [string]$RegistryKey, [string]$FriendlyName)
{
   Execute-Command -RegAsm $Regasm32  -Arguments '/codebase' -Assembly $Assembly
   Register-AddIn -RegistryKey $RegistryKey -FriendlyName $FriendlyName
}

function Register-Assembly64([string]$Assembly, [string]$RegistryKey, [string]$FriendlyName)
{
   Execute-Command -RegAsm $Regasm64 -Arguments '/codebase' -Assembly $Assembly
   Register-AddIn -RegistryKey $RegistryKey -FriendlyName $FriendlyName
}

function Unregister-Assembly32([string]$Assembly, [string]$RegistryKey)
{
   Execute-Command -RegAsm $Regasm32 -Arguments '/unregister' -Assembly $Assembly
   Unregister-AddIn -RegistryKey $RegistryKey
}

function Unregister-Assembly64([string]$Assembly, [string]$RegistryKey)
{
   Execute-Command -RegAsm $RegAsm64 -Arguments '/unregister' -Assembly $Assembly
   Unregister-AddIn -RegistryKey $RegistryKey
}

function Register-AddIn([string]$RegistryKey, [string]$FriendlyName)
{
    New-Item         -Path $RegistryKey -Force
    New-ItemProperty -Path $RegistryKey -Name Description  -PropertyType String -Value $FriendlyName
    New-ItemProperty -Path $RegistryKey -Name FriendlyName -PropertyType String -Value $FriendlyName
    New-ItemProperty -Path $RegistryKey -Name LoadBehavior -PropertyType DWord  -Value 3
}

function Unregister-AddIn([string]$RegistryKey)
{
    if (Test-Path -Path $RegistryKey)
    {
        Remove-Item -Path $RegistryKey
    }
}

function Execute-Command([string]$RegAsm, [string]$Arguments, [string]$Assembly)
{
    $psi = New-Object System.Diagnostics.ProcessStartInfo
    $psi.CreateNoWindow = $true
    $psi.UseShellExecute = $false
    $psi.RedirectStandardOutput = $true
    $psi.RedirectStandardError = $true
    $psi.FileName = $RegAsm
    $psi.Arguments = $Arguments + ' ' + $Assembly
    $process = New-Object System.Diagnostics.Process
    $process.StartInfo = $psi
    [void]$process.Start()
    $StandardOutput = $process.StandardOutput.ReadToEnd()
    $StandardError = $process.StandardError.ReadToEnd()
    $process.WaitForExit()
    [system.windows.forms.messagebox]::show($StandardOutput + $StandardError)
}

2) Then I have other scripts that include that script:

MyAddInVBA32Registration.ps1:

$ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path
. (Join-Path $ScriptDirectory Functions.ps1)

$Assembly = (get-item Env:\USERPROFILE).Value + '\Documents\MyAddIn\Exe\Debug\MyAddIn.dll'

Register-Assembly32 -Assembly $Assembly -RegistryKey 'HKCU:\Software\Microsoft\VBA\VBE\6.0\AddIns\MyAddIn.Connect' -FriendlyName 'My Add-In'

MyAddInVBA64Registration.ps1:

$ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path
. (Join-Path $ScriptDirectory Functions.ps1)

$Assembly = (get-item Env:\USERPROFILE).Value + '\Documents\MyAddIn\Exe\Debug\MyAddIn.dll'

Register-Assembly64 -Assembly $Assembly -RegistryKey 'HKCU:\Software\Microsoft\VBA\VBE\6.0\AddIns64\MyAddIn.Connect' -FriendlyName 'My Add-In'

MyAddInVBA32Unregistration.ps1:

$ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path
. (Join-Path $ScriptDirectory Functions.ps1)

$Assembly = (get-item Env:\USERPROFILE).Value + '\Documents\MyAddIn\Exe\Debug\MyAddIn.dll'

Unregister-Assembly32 -Assembly $Assembly -RegistryKey 'HKCU:\Software\Microsoft\VBA\VBE\6.0\AddIns\MyAddIn.Connect'

MyAddInVBA64Unregistration.ps1:

$ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path
. (Join-Path $ScriptDirectory Functions.ps1)

$Assembly = (get-item Env:\USERPROFILE).Value + '\Documents\MyAddIn\Exe\Debug\MyAddIn.dll'

Unregister-Assembly64 -Assembly $Assembly -RegistryKey 'HKCU:\Software\Microsoft\VBA\VBE\6.0\AddIns64\MyAddIn.Connect'

To run the scripts you need to enable PowerShell execution first and they need to be run with admin rights.

I am finding PowerShell with a learning curve harder than expected and with some "by-design" issues that makes it "tricky" in my opinion, but I hope to learn it in depth.

Posted by carlosq | with no comments

MZ-Tools Articles Series updated

Many of the MZ-Tools Articles that I have written in the last years seemed a bit outdated because each one has a header like this:

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: March 2010   Microsoft Visual Studio .NET 2003


  Microsoft Visual Studio 2005

Where the date and the list of Visual Studio versions would reflect the moment in time when I wrote them.

I have reviewed all them (200+) and many are now updated to reflect that they apply until the last Visual Studio 2012 version when that is the case:

Author: Carlos J. Quintero (Microsoft MVP) Applies to: Microsoft Visual Studio .NET 2002
Date: March 2010   Microsoft Visual Studio .NET 2003
Updated: March 2013   Microsoft Visual Studio 2005
      Microsoft Visual Studio 2008
      Microsoft Visual Studio 2010
      Microsoft Visual Studio 2012

So, most HOWTO articles are now current. The exceptions are those articles which are BUG or PRB (issue), that I haven't bothered to check if they are still present.

Posted by carlosq | with no comments
More Posts Next page »