Visual Studio Hacks [Electronic resources]

Andrew Lockhart

نسخه متنی -صفحه : 172/ 131
نمايش فراداده

Hack 88. Create a File Template

The Add New Item dialog isn't set in stone. You can extend it by adding your own item or project template.

When you create a new file in your Visual Studio Projects, you generally use the Add New Item dialog (see Figure 12-1). If you look at the categories listed on the left half of that window, you can see that the dialog box is organized according to the types of files you might need to create in a given project type.

Visual Studio 2005 includes an enhanced and improved mechanism to create item and project templates. These enhancements were not available at the time of this writing, but stay tuned to http://www.visualstudiohacks.com for more information when they become available.

Figure 12-1. Visual Studio .NET 2003 Add New Item dialog

Visual Studio provides many different types of template files for the many different types of projects. Rather than just displaying them all in a long list, the Visual Studio team provided some of the gentle guidance you would expect. If you're working on a Web Project, it initially displays all the templates for the types of files that might be used in Web Projects. The most common type of file that developers create in an ASP.NET Web Project is a Web Form. Accordingly, the Web Form template is first one in the list.

Once you choose a given template, you're provided the chance to name the file that will be created from it. A fairly generic name is suggested, like WebForm1.aspx for those created from the Web Form template. You'll almost always change this name.

The final steps are for Visual Studio to add the new file instance, with your chosen filename, to your project and display it in the editor pane of the IDE. Depending on the template you chose, you'll see the appropriate initial content in the editor.

It's what appears in that initial content that is up for grabs in this hack. If this is a source code file, you'll see plain text. The plain text is the starter code or markup for the given file that you or another developer will expand upon. This hack shows you how to create your own template and have it produce the initial plain text you need.

12.4.1. Create Your Own Template

Visual Studio provides a number of built-in templates for nearly all of the file types that are involved in the different types of .NET applications. One hack opportunity is to take one of the existing templates and just modify it to your needs. The other opportunity is to create one from scratch, which is what I will be covering in this hack.

12.4.2. Visual Studio .NET 2003 Is Missing a Template

Actually, in this hack, I'd like to make up for a hole in Visual Studio. In addition to the Visual Studio IDE, Microsoft also offers a free tool for web development called Microsoft ASP.NET Web Matrix, or Web Matrix for short. The Web Matrix is a small tool that is not as fully featured as Visual Studio. Visual Studio is able to create many more file types than the Web Matrix. So you'd think that Visual Studio's set of templates would definitely be the superset of file types. Not quite. There's an HTTP Handler file type that appears in the Web Matrix Add New File dialog (see Figure 12-2). Strangely enough, this is missing from Visual Studio. So let's make up for this disparity.

Figure 12-2. ASP.NET Web Matrix Add New File dialog

Similar to the .aspx extension for the Web Form templates, ASP.NET HTTP Handlers use an .ashx extension. We won't go into all the differences between a Web Form and an HTTP Handler in this hack. The salient difference to note is that the initial text that the HTTP Handler template uses will be different from the Web Form template. Whereas the .aspx file contains markup text with angle brackets, the HTTP Handler template is actually all code; in this case, it's C# or Visual Basic .NET.

12.4.3. Get Your Template Listed in the Add New Item Dialog

Navigate to the C:\Program Files\Microsoft Visual Studio .NET 2003 folder. Depending on what language (for example, C# or VB), look for either the VC# or VB7 folder. Inside the given language folder, look for CSharpProjectItems or VBProjectItems, respectively. Compare the filenames in the folders to the templates in the Add New Item dialog. This is where Visual Studio stores templates. It uses a combination of .vsz files and .vsdir files. So to get our template display, we've got to create the appropriate .vsz and .vsdir files. The entry in the .vsdir file will point to our .vsz file.

12.4.3.1 VSZ Files

Visual Studio .NET uses .vsz files to launch wizards. These are simple text files that look like the .ini files of old, but with only one section.

To create a new VSZ file, you can copy one of the existing files or start from scratch by creating a new text file in your favorite text editor and saving it with the .vsz file extension. Inside of the file, you first need to specify what version of Visual Studio this template is for, which is done by specifying:

VSWIZARD 7.0

This tells Visual Studio that your template will function with Visual Studio .NET 2002 (7.0) or 2003 (7.1).

You may notice that some of the templates have VSWIZARD 6.0 specified, meaning that the template was created for Visual Studio 6. Templates with this specified are still understood and work with Visual Studio .NET 2002 and 2003.

The next line specifies the class that should be used for the wizard. In this example, I use VsWizard.VsWizardEngine.7.1 (the default wizard engine).

You could write your own wizard engine by creating a class that implements the IDTWizard interface.

Next, you will need to specify any number of parameters to send to the wizard engine. This example specifies the name of the wizard, the type of project, and whether the wizard includes a UI. The complete .vsz file can be seen here for a C# first and then a VB.NET version of the HttpHandler:

VSWIZARD 7.0
Wizard=VsWizard.VsWizardEngine.7.1
Param="WIZARD_NAME = CSharpHTTPHandler"
Param="WIZARD_UI = FALSE"
Param="PROJECT_TYPE = CSPROJ"
VSWIZARD 7.0
Wizard=VsWizard.VsWizardEngine.7.1
Param="WIZARD_NAME = VBNETHTTPHandler"
Param="WIZARD_UI = FALSE"
Param="PROJECT_TYPE = VBPROJ

The WIZARD_NAME parameter specifies the name of the wizard, in these examples, either CSharpHTTPHandler or VBNETHTTPHandler. The WIZARD_UI parameter specifies whether this is a simple template or a complete wizard; in this example, we are just creating a template, so we will pass false. The last parameter specifies the type of project this item will be added to, CSPROJ and VBPROJ, respectively.

12.4.3.2 VSDir Files

VSDir files are simple text files that tell the Add New Item and New Project dialogs what to display, including details like the name and icon.

Just like the .vsz files, the .vsdir files are plain text files. The format is different though. There are multiple entries inside, one per line, with the pipe symbol (|) separating the different parts of the given entry.

While you can update one of the existing .vsdir files, it is better to create a new .vsdir file. If you modify one of the existing files, your changes will be overwritten if the user reinstalls or repairs his installation of Visual Studio.

First, create a new blank text file in your favorite text editor, save it with an extension of .vsdir, and save it in the Web Project Items subfolder. Next, you need to add a line that represents the new template. Here is the code you need to add for C# and VB.NET. (You should put all the code on a single line, rather than wrapping it as it's shown here):

C#:

..\CSharpHTTPHandler.vsz| |HTTP Handler
|15|VSNet Hacks HTTPHandler
|{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}|4534
|0|HTTPHandler.ashx

VB.NET:

..\VBNETHTTPHandler.vsz| |HTTP Handler
|15| VSNet Hacks HTTPHandler
|{164B10B9-B200-11D0-8C61-00A0C91E29D5}|4533
|0|HTTPHandler.ashx

Although it is broken up here, all code should appear on one line in the text file. These entries have up to nine parts. Let's look at the VB.NET code as an example.

The first part (..\VBNETHTTPHandler.vsz) is the relative path to the .vsz file for the template. The second part (the space between the | and |) is optional and left blank in this example.

The third part (HTTP Handler) contains the words that go under the icon for the template in the Add New Item dialog, so keep it short.

The fourth part (15) is important; it's known as the SortPriority. It determines the order in which the templates appear in the dialog. The ones included with Visual Studio start with 10 and continue in increments of 10. For example, the next template that normally appears is the WebService template. It has a SortPriority of 20. I use 15 so that this one shows up between these two.

The fifth part (VSNet Hacks HTTPHandler) is the description that appears in the box of the same dialog when you click on the icon. You'll have a little more room for this, but not much; it has to fit on a single line.

The sixth and seventh ({164B10B9-B200-11D0-8C61-00A0C91E29D5} and 4533) parts have to do with the icon that'll be used in the dialog to represent this custom template. The sixth part is the DLL path or CLSID of a DLL that has an icon resource in it. You can just leave this the same as the one used for the default WebForm. Similar to the resource strings mentioned above, the seventh part is the resource number in that DLL that points to the particular icon in the DLL. Stick with the one from the WebForm for now. The eighth part (0) is a bit mask for some flags; again, you should also stick with the values for the WebForm template.

The ninth part (HTTPHandler.ashx) is the last one. It's the suggested filename I talked about earlier. Set it to HTTPHandler.ashx. Visual Studio will use this as a suggested base name and adjust it to HTTPHandler<N>.ashx, where N will get replaced with an increasing integer in that pattern with which you're familiar (HTTPHandler1.ashx, HTTPHandler2.ashx, etc.).

12.4.4. Wizards Directory Structure

Now that you've got the Add New Item dialog supplied with the necessary .vsz and .vsdir files, you must put the template where Visual Studio expects it to be. Look back in the VC# and VB folders for the VC#Wizards and VBWizards subfolders. Inside these folders, you'll find the various wizards and templates.

Inside the wizards folders are further subfolders that contain each individual wizard. The names of these folders match the WIZARD_NAME parameter from the .vsz files. So you'll want to add a CSharpHTTPHandler and HTTPHandler folder to the VC#Wizards and VBWizards folders.

Inside these folders, you must follow some conventions for templates and scripts that Visual Studio will require to be able to find your files. You'll need a Templates folder and a Scripts folder. Inside each of those folders needs to be a 1033 folder. 1033 isn't really a magic number. It's a LocaleID that represents standard English. Since we're just dealing with an English installation of Visual Studio here, this is what the folder needs to be named. If you were to use an installation of a different spoken language, you should expect a different number.

12.4.5. HTTPHandler.ashx Template File

You now have nearly everything set up that you need to have this hack work. You've got Visual Studio acknowledging that your template exists. If you bring up the Add New Item dialog box, you'll see an entry for the HTTP Handler (see Figure 12-3). If you click the Open button, it will now try to find the HTTPHandler.ashx file in the Templates/1033 folder of VC#Wizards or VBWizards folder.

Figure 12-3. Hacked Visual Studio .NET 2003 Add New Item dialog

Next, you need to create the actual template. Since you're going to use the HTTP Handler from Web Matrix, you can fire it up and copy the template or just use the following code:

VB.NET:

<%@ WebHandler language="VB" class="[!output SAFE_ITEM_NAME]" %>
Public Class [!output SAFE_ITEM_NAME] : Implements IHttpHandler
Public Sub ProcessRequest(context As HttpContext) 
Implements IHttpHandler.ProcessRequest
' TODO: Write request handling code here
End Sub
Public ReadOnly Property IsReusable As Boolean 
Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
End Class

C#:

<%@ WebHandler language="C#" 
class="[!output SAFE_NAMESPACE_NAME].[!output SAFE_CLASS_NAME]" %>
using System;
using System.Web;
namespace [!output SAFE_NAMESPACE_NAME] {
public class [!output SAFE_CLASS_NAME] : IHttpHandler {
public void ProcessRequest(HttpContext context) {
// TODO: Write request handling code here
}
public bool IsReusable {
get {
return true;
}
}
}
}

You will need to replace the names of the classes and namespaces with [!output SAFE_NAMESPACE_NAME] or [!output SAFE_CLASS_NAME] in C# or [!output SAFE_ITEM_NAME] for the class name in VB.NET. These will be replaced with namespace and class names by the wizard engine.

Change the name of the file to be HTTPHandler.ashx so that it matches the suggested base name you gave in the .vsdir file entry. Save the file into the Templates/1033 folder.

If you are creating a C# wizard, you next need to create an .inf file that lists the files to add to your project. Create a new text file in a text editor and add the following line to that file:

HTTPHandler.ashx

Next, save the file with the name templates.inf.

12.4.6. Default.js Script

This is the final step. When Visual Studio gets to the point of adding the template file to the project, it invokes a JavaScript file. This enables anyone who wants to extend Visual Studio to be able to perform any custom steps that might be necessary. The preferred choice for providing this type of extension is scripting.

You don't need anything complicated to add the HTTPHandler.ashx file to the project. Create a new text file and add the following code to that text file:

C# template

function OnFinish(selProj, selObj)
{
try
{
var strProjectName     = wizard.FindSymbol("PROJECT_NAME");
SetTargetFullPath(selObj);
var strProjectPath    = wizard.FindSymbol("TARGET_FULLPATH");
var InfFile = CreateInfFile( );
AddFilesToCSharpProject(selObj, strProjectName, 
strProjectPath, InfFile, true);
}
catch(e)
{
if( e.description.length > 0 )
SetErrorInfo(e);
return e.number;
}
finally
{
if( InfFile )
InfFile.Delete( );
}
}
function SetFileProperties(oFileItem, strFileName)
{
}

VB.NET template

function OnFinish(selProj, selObj)
{
try
{
var strItemName = wizard.FindSymbol("ITEM_NAME");
var strTemplatePath = wizard.FindSymbol("TEMPLATES_PATH");
var strTemplateFile = strTemplatePath + "\\HTTPHandler.ashx";
var item = AddFileToVSProject(strItemName, selProj, 
selObj, strTemplateFile, true);
return 0;
}
catch(e)
{     
if( e.description.length > 0 )
SetErrorInfo(e);
return e.number;
}
}

Save the file as default.js in the Scripts/1033 folder of your wizard.

12.4.7. Try It Out

That's it. Create a Visual Studio .NET 2003 Project. Bring up the Add New Item dialog. The HTTP Handler item should appear as the second one in the dialog box. Adjust the HTTPHandler1.aspx name if needed and click the Open button. A new HTTPHandler.ashx file will appear in your project .

Steven Dewalt