Ken Levy, product manager of the VSX team just published the VSX community letter for July 07.
In my opinion this initiative provides a lot of transparency to the community about what the VSX team has been working on, recent news, announcements, events and on what they are working on now plus the roadmap for the future. Following this direction there is also a VSX Team blog.
Of course there is a lot of work to do to build a VSX community, my friend and VSX guru Victor already mentioned his vision of a VSX Community and I completely agree with him.
But I think that this is a really good thing and the VSX team is going to put a lot of effort to continue building the community.
On the news section there is a pointer to VSSDK Assist, many thanks to Ken and the VSX team to provide a pointer on the community letter and to increase the visibility of the project.
Pablo
There is a really useful and undocumented assembly that comes with the VS SDK 4.0 that is located under %VSSDK_InstallDir%\%Version_Number%\Prerelease\VSCT\VSCTLibrary.dll
The purpose of this assembly is to provide an API to support the creation/update and browsability of VSCT command definition files.
As I unfortunately said there is no documentation at this moment at MSDN but with the help of Reflector we can browse the API definition easily.
Example:
Lets suppose that we want to create a VSCT based on the following ctc definition:
#include "stdidcmd.h"
#include "vsshlids.h" #include "msobtnid.h" #include "CommandIds.h" #include "Resource.h" #include "Guids.h" #define OI_NOID guidOfficeIcon:msotcidNoIcon
#define IDB_MENU_IMAGES 300
CMDS_SECTION guidVsPackage2Pkg
NEWGROUPS_BEGIN
// NewGroup Parent Group Priority guidVsPackage2CmdSet:MyMenuGroup, guidSHLMainMenu:IDM_VS_MENU_TOOLS, 0x0600; NEWGROUPS_END BUTTONS_BEGIN
// Command Parent Group Priority Image Type Visibility Text guidVsPackage2CmdSet:cmdidMyCommand, guidVsPackage2CmdSet:MyMenuGroup, 0x0100, guidVsPackage2CmdSet:bmpPic1, BUTTON, , "My Command name"; BUTTONS_END BITMAPS_BEGIN
// Bitmap Bitmap Index,... guidVsPackage2CmdSet:IDB_MENU_IMAGES, bmpPic1 BITMAPS_END CMDS_END // guids.h: definitions of GUIDs/IIDs/CLSIDs used in this VsPackage
// package guid
// { 55d8e094-bc5c-4458-8bf8-421a99af60cf }
#define guidVsPackage2Pkg { 0x55D8E094, 0xBC5C, 0x4458, { 0x8B, 0xF8, 0x42, 0x1A, 0x99, 0xAF, 0x60, 0xCF } }
#ifdef DEFINE_GUID
DEFINE_GUID(CLSID_VsPackage2,
0x55D8E094, 0xBC5C, 0x4458, 0x8B, 0xF8, 0x42, 0x1A, 0x99, 0xAF, 0x60, 0xCF );
#endif
// Command set guid for our commands (used with IOleCommandTarget)
// { fda7d55d-d66c-47d2-85bf-00258bec545a }
#define guidVsPackage2CmdSet { 0xFDA7D55D, 0xD66C, 0x47D2, { 0x85, 0xBF, 0x0, 0x25, 0x8B, 0xEC, 0x54, 0x5A } }
#ifdef DEFINE_GUID
DEFINE_GUID(CLSID_VsPackage2CmdSet,
0xFDA7D55D, 0xD66C, 0x47D2, 0x85, 0xBF, 0x0, 0x25, 0x8B, 0xEC, 0x54, 0x5A );
#endif
The following simple program shows the usage of the VSCTLibrary.dll API:
using Microsoft.VisualStudio.CommandTable;
using System;
using System.Globalization;
namespace VSCTTest
{
class Program
{
static void Main(string[] args)
{
CreateCommandTable();
}
private static void CreateCommandTable()
{
Guid guidSHLMainMenu = new Guid("d309f791-903f-11d0-9efc-00a0c911004f");
Guid guidVsPackage2Pkg = new Guid("55d8e094-bc5c-4458-8bf8-421a99af60cf");
Guid guidVsPackage2CmdSet = new Guid("fda7d55d-d66c-47d2-85bf-00258bec545a");
uint idm_vs_menu_tools = 133;
uint myMenuGroup = 4128;
uint cmdidMyCommand = 256;
uint idb_menu_images = 300;
uint bmpPic1 = 1;
CommandTable table = new CommandTable();
table.AddGuidSymbol(guidSHLMainMenu, "guidSHLMainMenu");
table.AddGuidSymbol(guidVsPackage2Pkg, "guidVsPackage2Pkg");
table.AddGuidSymbol(guidVsPackage2CmdSet, "guidVsPackage2CmdSet");
table.AddIDSymbol(guidSHLMainMenu, idm_vs_menu_tools, "idm_vs_menu_tools");
table.AddIDSymbol(guidVsPackage2CmdSet, myMenuGroup, "MyMenuGroup");
table.AddIDSymbol(guidVsPackage2CmdSet, cmdidMyCommand, "cmdidMyCommand");
table.AddIDSymbol(guidVsPackage2CmdSet, idb_menu_images, "IDB_MENU_IMAGES");
table.AddIDSymbol(guidVsPackage2CmdSet, bmpPic1, "bmpPic1");
table.CreateGroup(
table.GetIDFromGuid(guidVsPackage2CmdSet),
myMenuGroup,
table.GetIDFromGuid(guidSHLMainMenu),
idm_vs_menu_tools,
1536);
BitmapItem bitmap = table.CreateBitmap(
table.GetIDFromGuid(guidVsPackage2CmdSet),
idb_menu_images);
CommandButton button = table.CreateButton(
table.GetIDFromGuid(guidVsPackage2Pkg), //If you know the Guid alias you could do table.FindSymbolGuid("guidVsPackage2Pkg")
table.GetIDFromGuid(guidVsPackage2CmdSet),
cmdidMyCommand,
table.GetIDFromGuid(guidVsPackage2CmdSet),
myMenuGroup,
256);
button.IconGID = table.GetIDFromGuid(guidVsPackage2CmdSet);
button.IconIndex = bmpPic1;
button.SetMenuText(0, "My Command name", CultureInfo.CurrentCulture);
SaveOptions options = new SaveOptions(SaveOptions.SaveFormat.XML);
table.Save(@"C:\MyCommandDefinition.vsct", options, null);
}
}
}
This is the result of the program execution:
<CommandTable language="en-US" xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable">
<Commands>
<Groups>
<Group guid="guidVsPackage2CmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="{d309f791-903f-11d0-9efc-00a0c911004f}" id="0x0085" />
</Group>
</Groups>
<Bitmaps>
<Bitmap guid="guidVsPackage2CmdSet" resID="IDB_MENU_IMAGES" usedList="bmpPic1" />
</Bitmaps>
</Commands>
<Commands package="guidVsPackage2Pkg">
<Buttons>
<Button guid="guidVsPackage2CmdSet" id="cmdidMyCommand" priority="0x0100" type="Button">
<Parent guid="guidVsPackage2CmdSet" id="MyMenuGroup" />
<Icon guid="guidVsPackage2CmdSet" id="bmpPic1" />
<Strings>
<ButtonText>My Command name</ButtonText>
</Strings>
</Button>
</Buttons>
</Commands>
<Symbols>
<GuidSymbol name="guidSHLMainMenu" value="{d309f791-903f-11d0-9efc-00a0c911004f}">
<IDSymbol name="idm_vs_menu_tools" value="0x0085" />
</GuidSymbol>
<GuidSymbol name="guidVsPackage2Pkg" value="{55d8e094-bc5c-4458-8bf8-421a99af60cf}" />
<GuidSymbol name="guidVsPackage2CmdSet" value="{fda7d55d-d66c-47d2-85bf-00258bec545a}">
<IDSymbol name="MyMenuGroup" value="0x1020" />
<IDSymbol name="cmdidMyCommand" value="0x0100" />
<IDSymbol name="IDB_MENU_IMAGES" value="0x012C" />
<IDSymbol name="bmpPic1" value="0x0001" />
</GuidSymbol>
</Symbols>
</CommandTable>
I am using this API heavily on VSSDK Assist to create VS commands that target the new VSCT format.
Pablo
For more information about VSCT and the new way of defining VS commands you can check Aaron's posts CTC is dead...Long Live VSCT! (Part 1) and CTC is dead...Long Live VSCT! (Part 2) or mine.
So, lets go to the main topic of this post:
Important: This applies to the VSCT compiler that comes with the VSSDK V4 for VS 2005.
The VSCT compiler can perform multiple tasks. Its main usage is for compiling VSCT command definition files, but on this post I am going to show another useful operation that could be performed with the VSCT compiler:
VSCT decompilation:
You can use the VSCT compiler to decompile an assembly or a cto file and obtain the VSCT command definition file.
One important thing to note is that the output of the VSCT compiler is also .cto file (same as CTC.exe).
Because the outputs are the same, it doesn't matters if the CTO embedded in the assembly was generated with CTC.exe or with VSCT.exe. And the good thing is that you don't need to specify what are you decompiling, all its done automatically by VSCT.exe. This also means that you could do an implicit CTC to VSCT transformation.
Example:
The VSCT.exe is located under %VSSDK_InstallDir%\%Version_Number%\Prerelease\VSCT\
vsct.exe C:\Temp\MyPackage\MyPackage\obj\Debug\MyPackage.cto MyPackage.vsct
or
vsct.exe C:\Temp\MyPackage\MyPackage\bin\Debug\MyPackage.dll MyPackage.vsct
Pablo