(Or why it is a bad idea for an add-in to add add-in file paths to Visual Studio)
When Visual Studio 2005 introduced XML-based add-ins, which used an .AddIn file rather than COM registration), rather than providing just two fixed folders to place such files (one for all users, other for the current user), Microsoft provided five (5!!) folders, listed in the Tools, Options menu, Environment, Add-in/Macros Security section.
Not only that, Visual Studio allows to add more folders using the Add… button or programmatically writing to the “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\AutomationOptions\LookInFolders” registry key (VS 2005).
Not only that, you will have a difficult time expanding VS-proprietary placeholders like %VSAPPDATA%, %VSCOMMONAPPDATA% or %VSMYDOCUMENTS%, if your add-in setup wants to use one of those folders.
Not only that, Visual Studio 2008 added a sixth folder, %ALLUSERSDOCUMENTS%\Microsoft\MSEnvShared\Addins.
Not only that, Visual Studio 2008 actually fails to look for XML files in that new folder (see HOWTO: Using the Process Monitor (ProcMon) tool to diagnose Visual Studio add-ins problems)
And not only that (finally), Visual Studio hardcoded “Application Data” in one of the paths (“%ALLUSERSPROFILE%\Application Data\Microsoft\MSEnvShared\Addins”) without taking into account that that folder is localized and in other languages it doesn’t exist with that name on the hard disk. For example, in Spanish, it is should be “%ALLUSERSPROFILE%\Datos de programa\Microsoft\MSEnvShared\AddIns”.
I documented all that in the article INFO: Default .AddIn file locations for Visual Studio add-ins.
Guess what? Yesterday, while writing an utility that scans the add-in file paths, I noticed that on my Spanish computer Visual Studio 2005/2008 listed “%ALLUSERSPROFILE%\Datos de programa\Microsoft\MSEnvShared\AddIns” as one of the add-in file paths in the Tools, Options menu, Environment, Add-in/Macros Security section. Indeed VS 2005 listed 6 folders instead 5, and VS 2008 listed 7 folders instead of 6.
How could that be? At first I thought that the service pack 1 of both IDEs could have “fixed” the problem adding the localized version of that path maintaining the wrong one (with “Application Data” hardcoded). But I quickly discarded that explanation because I had installed SP1 from long time and those folders were not there. Then I remembered that I had installed recently an add-in (I won’t cite its name), and looking into the contents of the “%ALLUSERSPROFILE%\Datos de programa\Microsoft\MSEnvShared\AddIns” folder, there was the .AddIn files of this add-in. So, the setup of this add-in is placing the .AddIn file in that folder, AND it is adding that folder to the “HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\AutomationOptions\LookInFolders”. In other words, it is trying to “fix” what Microsoft did wrong with that folder. But I think this is a bad idea for this reason: if this add-in is installed on a non-English computer and the user happens to be a developer of add-ins who is unaware of the problem of the hardcoded “Application Data” path, he will see two paths listed:
%ALLUSERSPROFILE%\Application Data\Microsoft\MSEnvShared\Addins
%ALLUSERSPROFILE%\Datos de programa\Microsoft\MSEnvShared\AddIns
And certainly he will use the second one because any non-English developer knows that it is the correct one (using an API call to get the actual localized folder), but when his add-in is installed on another machine, the second path is not in the list of paths that VS scans, and the add-in won’t appear in the Add-In Manager.
Placing the .AddIn file in the first path (%ALLUSERSPROFILE%\Application Data\Microsoft\MSEnvShared\Addins) is also a bad idea because the setup will create that English folder on non-English computers, and then the computers will have those two paths physically on the hard disk.
So, what to do? I’d recommend to use the “%VSCOMMONAPPDATA%\AddIns” folder instead, which is also for all users but it neither mess the list of paths of Visual Studio nor creates English folders on non-English computers. The only drawback is that the folder is actually different each VS version:
For Windows XP:
- VS 2005: “C:\Documents and Settings\All Users\Application Data\Microsoft\VisualStudio\8.0\Addins”
- VS 2008: “C:\Documents and Settings\All Users\Application Data\Microsoft\VisualStudio\9.0\Addins”
For Windows Vista:
- VS 2005: “C:\ProgramData\Microsoft\VisualStudio\8.0\Addins”
- VS 2008: “C:\ProgramData\Microsoft\VisualStudio\9.0\Addins”
To get it programmatically the custom action of your setup that copies the .AddIn file must call the API that returns special folders with the parameter CSIDL_COMMON_APPDATA and then concatenate
“Microsoft\VisualStudio\8.0\Addins” for VS 2005 or “Microsoft\VisualStudio\9.0\Addins” for VS 2008. For example:
- Using the .NET Framework the call is System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)
- Using the free InnoSetup installer, the PascalScript call is ExpandConstant(‘{commonappdata}’) (see: HOWTO: Create a setup for a Visual Studio 2005 / 2008 add-in using Inno Setup)
- Using the Win32 API, you can use the SHGetFolderLocation, SHGetFolderPath, SHGetSpecialFolderLocation, and SHGetSpecialFolderPath functions.
Being the path different for each VS version you can’t use a single .AddIn file with two hosts inside (HostApplication tags) for VS 2005 and VS 2008, but that’s a minor extra work for the setup of an add-in, and we all know that software is all about our users, not about us the developers…