Welcome to MSDN Blogs Sign in | Join | Help

Code to install Community Toolbox Controls

I have been able to get some code from one of my colleagues and Extensibility support specialist, Ed Dore, that may help with the Toolbox control installation in Visual Studio 2005. I must remind you that the code that I post here comes with a Disclaimer.

In the code below you need to replace the following with your values:

<Path to the control dll>: Path to the dll that contains the toolbox control

<Toolbox Tabname>: Name of the Toolbox tab on which to add the controls.

HTH,

Chetan

 

using System;

using
System.Collections.Generic;

using
System.Text;

using
System.Runtime.InteropServices;

using
EnvDTE;

using
EnvDTE80;

using
System.IO;

namespace
InstallToolboxControls
{
   

// Definition of the IMessageFilter interface which we need to implement and 

   
// register with the CoRegisterMessageFilter API.

    [ComImport(), Guid("00000016-0000-0000-C000-000000000046"
),
    
InterfaceTypeAttribute(ComInterfaceType
.InterfaceIsIUnknown)]
    
interface IOleMessageFilter
// Renamed to avoid confusion w/ System.Windows.Forms.IMessageFilter

    {
        [
PreserveSig
]
       
int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr
lpInterfaceInfo);
        [
PreserveSig
]
        
int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int
dwRejectType);
        [
PreserveSig
]
        
int MessagePending(IntPtr hTaskCallee, int dwTickCount, int
dwPendingType);
    }
 



    class Program :
IOleMessageFilter

    {
        [
DllImport("ole32.dll"
)]
        
private static extern int CoRegisterMessageFilter(IOleMessageFilter newFilter, out IOleMessageFilter
oldFilter);
       
 static string ctrlPath = <Path to the control dll>;
        [
STAThread
]
        
static void Main(string
[] args)
        {
            

Program program = new Program
();
            program.Register();
            

if (args[0].Equals("-Install", StringComparison
.CurrentCultureIgnoreCase))
                program.InstallControl();
            

else if (args[0].Equals("-UnInstall", StringComparison
.CurrentCultureIgnoreCase))
                program.UninstallControl();
            program.Revoke();
            


// to ensure the dte object is actually released, and the devenv.exe process terminates.

            GC
.Collect();
            
GC
.WaitForPendingFinalizers();
        }
        

void
InstallControl()
        {
            

// Create an instance of the VS IDE,

            Type type = System.Type.GetTypeFromProgID("VisualStudio.DTE.8.0"
);
            
DTE dte = (DTE)System.Activator.CreateInstance(type, true
);
 
            

// create a temporary winform project;

            string tmpFile = Path.GetFileNameWithoutExtension(Path
.GetTempFileName());
            
string tmpDir = string.Format("{0}{1}",Path
.GetTempPath(),tmpFile);
            
Solution2 solution = dte.Solution as Solution2
;
            
string templatePath = solution.GetProjectTemplate("WindowsApplication.zip", "CSharp"
);
            
Project proj = solution.AddFromTemplate(templatePath, tmpDir, "dummyproj", false
);
            
// add the control to the toolbox.

            EnvDTE.Window window = dte.Windows.Item(EnvDTE.Constants
.vsWindowKindToolbox);
            EnvDTE.
ToolBox toolbox = (EnvDTE.ToolBox
)window.Object;
            EnvDTE.
ToolBoxTab
myTab = toolbox.ToolBoxTabs.Add(<Toolbox TabName>);
            myTab.Activate();
            myTab.ToolBoxItems.Add(

"MyUserControl", ctrlPath, vsToolBoxItemFormat
.vsToolBoxItemFormatDotNETComponent);
            dte.Solution.Close(
false
);
            
Marshal
.ReleaseComObject(dte);
            
Console.WriteLine("Control Installed!!!"
);
        }


        void
UninstallControl()
        {
            

Type type = System.Type.GetTypeFromProgID("VisualStudio.DTE.8.0"
);
            
DTE dte = (DTE)System.Activator.CreateInstance(type, true
);
 
            EnvDTE.

Window window = dte.Windows.Item(EnvDTE.Constants
.vsWindowKindToolbox);
            EnvDTE.
ToolBox toolbox = (EnvDTE.ToolBox
)window.Object;
            EnvDTE.
ToolBoxTab
myTab = toolbox.ToolBoxTabs.Item(<Toolbox Tabname>);
            myTab.Activate();
            myTab.Delete();
            


Marshal
.ReleaseComObject(dte);
            
Console.WriteLine("Control Uninstalled!!!"
);
        }
       

void
Register()
        {
           

IOleMessageFilter
oldFilter;
            CoRegisterMessageFilter(
this, out
oldFilter);
        }
       

void
Revoke()
        {
            

IOleMessageFilter
oldFilter;
            CoRegisterMessageFilter(
null, out
oldFilter);
        }


        #region
IOleMessageFilter Members
        
public int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr
lpInterfaceInfo)
        {
            

return 0;
//SERVERCALL_ISHANDLED

        }
        
public int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int
dwRejectType)
        {
            

if (dwRejectType == 2)
// SERVERCALL_RETRYLATER

            return 200;
// wait 2 seconds and try again

            return -1;
// cancel call

        }

        public int MessagePending(IntPtr hTaskCallee, int dwTickCount, int
dwPendingType)
        {
            

return 2;
//PENDINGMSG_WAITDEFPROCESS

        }

        #endregion

    }
}


 

Posted by ChetanC | 11 Comments
Filed under:

Visual Studio 2005 Automation Samples now available

The Visual Studio 2005 Automation Samples are now available for download.

http://msdn.microsoft.com/vstudio/downloads/code/automation/default.aspx

Please feel free to download the samples and try them out. The samples consists of examples of how to use the Visual Studio Extensibility to do a whole bunch of things from Solution Explorer Context Menus, Tool Windows, Custom Tools Options pages etc.

Posted by ChetanC | 2 Comments

Failure to install Toolbox controls via ContentInstaller or Tools.InstallCommunityControls

If you have the SQL Server Management Studio Express CTP or SQL Server 2005, then it is overwriting some registry key settings. The workaround for this is:

  1. Under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Packages\{36839529-3AF3-47fa-8194-F4A3FA9F0ED7}change the CodeBase value to use the Visual Studio 8.0 location, for e.g. file:///D:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Microsoft.VisualStudio.ToolBoxControlInstaller.dll
  2. Under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Packages\{36839529-3AF3-47fa-8194-F4A3FA9F0ED7}\SatelliteDll, change the Path value to point to the Common7\IDE folder for e.g. D:\Program Files\Microsoft Visual Studio 8\Common7\IDE\
  3. Open the Visual Studio Command Prompt and run devenv /setup

This should fix the issue.

Thanks,

Chetan

 

Posted by ChetanC | 3 Comments

Automatically qualifying class names

Have you ever wondered if it was possible to just go on coding without having to always first go and write the using or the Imports statement in C# or VB or J# or how about just fully qualifying the class names in place by using a keyboard shortcut. Well Visual Studio 2005 currently provides a simple mechanism of doing exactly this. For your example, if you had the statement without having the required using statement,

private StringBuilder sb;

then with the cursor on 'StringBuilder', the keyboard shortcut Shift+Alt+F10 will provide you the options of either adding a 'using' statement or fully qualifying the class in place.

In addition, the code editor also provides a hint that you need to qualify the class by showing a small red rectangle at the end of the class name. If you hover over that rectangle you will see a small drop down. This drop down also provides you with the same options as the keyboard shortcut.

Posted by ChetanC | 3 Comments

Programmatically setting TaskList view

In Visual Studio 2005, any Task that is added from an Add-in or a Macro using the TaskList automation object appears under the ‘Add-ins and Macros’ provider drop down in the TaskList. Currently there is no direct way, using the Automation Object Model, of selecting that provider to make the tasks added visible. To do this the best way is to call Commands.Raise using the following parameters: 

DTE.Commands.Raise("{1496A755-94DE-11D0-8C3F-00C04FC2AAE2}", 2200, "Add-ins and Macros", Customout)

This method can also be used to bring to front other providers such as the Comments or Shortcuts by just replacing the string ‘Add-ins and Macros’ with the provider names.

 

Posted by ChetanC | 1 Comments
Filed under:

Recompiling Add-in resources with every build

In the Displaying custom bitmap for VS add-in command button from satellite DLL, Huizhong showed how to create a Managed Satellite dll. The steps for creating the Satellite dll need to be performed everytime your make a change to the resources. And it would need to be repeated for every language/culture that your add-in supports. Wouldn’t it be great if the resources were built with every compile? To do this is very simple. You follow all the steps mentioned above for creating the resources file. Then follow the steps below:

1. Select the project and right click to open the Project Properties.
2. Open the Build Events dialog (Click on Build Events for C#, Compile->Build Events for VB)
3. Then in the Post Build Events type the following. Make sure to replace the <yourresourcename> with your resource name.
"$(DevEnvDir)\..\..\SDK\v2.0\Bin\resgen.exe" "$(ProjectDir)<YourResourceName>.resx" "$(TargetDir)<YourResourceName>.resources"
mkdir "$(TargetDir)en-US"
%windir%\Microsoft.NET\Framework\v2.0.50727\Al.exe /embed:"$(TargetDir)<YourResourceName>.resources" /culture:en-US /out:"$(TargetDir)en-US\$(TargetName).resources.dll"

Repeat the commands for all the language resource files that you intend to provide for the Add-in.
4. Click OK.

Now whenever you do a build, the resources will also be compiled.

Posted by ChetanC | 0 Comments
Filed under:

Community Content Installer PowerToys

Craig Skibo has just posted an updated version of the Community Content Installer Power Toys. These are tools that will help you build, uninstall community content. If you haven't yet then give it a try. The download is available at

http://workspaces.gotdotnet.com/CCIPowerToys

Posted by ChetanC | 0 Comments

Packaging Add-ins and Toolbox Controls for use with Visual Studio Content Installer

The Visual Studio Content Installer allows users to install community content such as add-ins, toolbox controls etc. The Visual Studio Content Installer uses a Visual Studio Installer (VSI) file which contains the content to install. Each VSI file contains a .vscontent file and the content files. The .vscontent file describes the content to install.

Creating a VSI that will install add-ins is very easy as indicated by the following steps:
1. Create the add-in(s)/toolbox controls you want to install.
2. Create a folder such as MyContent and copy all the .addin(s) and .dll(s) files for your content to this folder. This folder is optional although it helps bring all the content you want to a single place.
3. Create a .vscontent files such as the following in the folder:

<?xml version="1.0" encoding="utf-8" ?>
<VSContent xmlns="
http://schemas.microsoft.com/developer/vscontent/2005">
  <Content>
    <FileName>MyAddin.dll</FileName>
    <FileName>MyAddin.addin</FileName>
    <DisplayName>My Addin</DisplayName>
    <Description>This is my addin</Description>
    <FileContentType>Addin</FileContentType>
    <ContentVersion>1.0</ContentVersion>
  </Content>
  <!-- If you have more add-ins than you need to create multiple Content tags, one for each add-in -->
  <Content>
    <FileName>MyToolboxControlLibrary.dll</FileName>
    <DisplayName>My Toolbox Controls</DisplayName>
    <Description>These are my toolbox controls</Description>
    <FileContentType>Toolbox Control</FileContentType>
    <ContentVersion>1.0</ContentVersion>
  </Content>
  <!-- If you have more controls than you need to create multiple Content tags, one for each control -->
</VSContent>

4. Now create a zip file that contains all the files in the folder. Please note that the zip file should not contain the folder information as that is not needed. E.g. the files in the zip file will be something like the following without the path information:

MyAddin.addin
MyAddin.dll
MyToolboxControlLibrary.dll
MyContent.vscontent

5. Rename the zip file to be .vsi.

That's it. You have a VSI file that will install your add-in using the Visual Studio Content Installer.

 

Posted by ChetanC | 3 Comments

Installing Managed ToolBox Controls Programmatically

In the past with Visual Studio 2003, it was possible to programmatically add .Net or Managed toolbox controls using the DTE. With Visual Studio 2005 this method of programmatically adding the controls has been deprecated in favor of using one of the following two methods:

1. Visual Studio Content Installer
2. Tools.InstallCommunityControls command.

The difference between the two is that one is an external program that can install all kinds of community content such as addins, macros, snippets etc and the other is a built in command.

Using Visual Studio Content Installer
This executable, VSContentInstaller.exe, is available under \Program Files\Common Files\Microsoft Shared\MSEnv. The input for this executable is a VSI file. More information on this is available here: http://msdn2.microsoft.com/en-us/library/ms246580.aspx

Using the Tools.InstallCommunityControls command
You can use this command to add custom toolbox controls either from within Visual Studio or from the command line. For either case you need to follow the steps outlined below to install the controls.
Copy the controls to the My Documents\Visual Studio 2005\Controls\<companyname>\ folder. The <companyname> is used as the name of the tab which will contain controls.

For command line installation:
Open the Visual Studio Command prompt and execute the following command:
devenv /command Tools.InstallCommunityControls

For installation from within Visual Studio:
Open the Command Window (View->Other Windows->Command Window) and execute the following command: Tools.InstallCommunityControls.

Having the ability to execute a command from the command line can be very useful in creating install scripts and a batch file such as the one below can install the community controls.

@echo off
set TabName=%1
set DllName="%2"
set ControlsFolder="%userprofile%\My Documents\Visual Studio 2005\Controls\%TabName%"
%ControlsFolder%
mkdir %ControlsFolder%
copy %DllName% %ControlsFolder%
"%VS80COMNTOOLS%\..\IDE\devenv.exe" /command Tools.InstallCommunityControls
set TabName=
set DllName=
set ControlsFolder=

Another way to do this using DTE is to use DTE.ExecuteCommand:


DTE2 dte;
dte = (DTE2)Activator.CreateInstance(Type.GetTypeFromProgID("VisualStudio.DTE.8.0"));
dte.ExecuteCommand("Tools.InstallCommunityControls", "");
dte.Quit();

One thing to note is that this mechanism does not fit well if you have folder redirection and some more work in terms of setting right permissions etc is required.

 

Posted by ChetanC | 7 Comments

About Me

I am a member of the Visual Studio Extensibility Team and mainly responsible for the quality of the Automation Object Model in addition to Add-ins, Macros and anything else related to extensibility.

Other things that interest me and I help drive in the Visual Studio is Code Coverage and automating UI.

I would use this blog to provide Visual Studio Extensibility tips, white papers, samples etc.

 

 

 

Posted by ChetanC | 0 Comments
 
Page view tracker