Inside Microsoft® Visual Studio® .NET 2003 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Inside Microsoft® Visual Studio® .NET 2003 [Electronic resources] - نسخه متنی

Brian Johnson

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید










Custom Wizards


Visual Studio .NET has built-in support for creating only two types of wizards, New Project and Add New Item wizards. However, at times you might need to build a wizard that doesn't fit either of these types. Visual Studio .NET supports an extensible wizard architecture that allows you to create and invoke your own type of wizard, called a Custom wizard. An example of a Custom wizard is a wizard you can invoke to insert common code constructs, such as default implementations of classes, methods, or properties, directly into an existing source code file.


Why Custom Wizards?


The Visual Studio .NET automation group didn't add the ability to create Custom wizards simply to provide another way to extend a program with your own software creations; Custom wizards were born out of necessity. The Visual C++ group needed a way to add new functions and variables to classes from within the Class View tool window, and they wanted to do it in a wizard-like way. To make this possible, they added Custom wizards to the list of wizard types. They created wizards to add both functions and variables, and by calling the DTE.LaunchWizard method with the proper parameters to programmatically launch the wizards, they were able to allow the user to modify a class in a way that is familiar to them. So when you right-click on a C++ class within the Class View window and choose Add | Add Function or Add | Add Variable, you're really running a Custom wizard.

To create a Custom wizard, you build a COM object that implements the IDTWizard interface and you create a .vsz file for that wizard just as you would for a New Project or Add New Item wizard. However, unlike with the other types of wizards, you select the list of context parameters that your wizard takes, and a Custom wizard is invoked through your own code rather than through a dialog box. As you've seen, a list of context arguments is passed to a wizard when it is run, supplying information about how the wizard should do its work. If a wizard is to be run as a New Project or Add New Item wizard, Visual Studio .NET calculates the proper context parameters array and passes that array to the IDTWizard.Execute method. A Custom wizard is started programmatically, either from an add-in, a macro, or another wizard, and the calling application fills in the context parameters array.

Note

There are no restrictions on the context parameters that can be passed to a Custom wizard, but we recommend that you make the first argument a GUID that the caller and the wizard agree on beforehand. The wizard should then verify that the GUID passed is the expected GUID before proceeding. This approach helps keep the wizard from incorrectly using the context parameters and throwing an exception or crashing.


Running a Custom Wizard Programmatically


Your program could manually load a wizard COM object, find the IDTWizard interface of that wizard, and pass off the appropriate values to the Execute method, but it would be easier to let Visual Studio .NET handle much of this work for you. You can use the automation model to launch wizards programmatically using the DTE.LaunchWizard method. This method takes as its arguments the path to a .vsz file and an array of context parameters. Because the path to the .vsz file is passed to this method, the .vsz file for a Custom wizard can be stored anywhere on diskit doesn't have to be in a specific location, as the other wizard types do. Once called, the LaunchWizard method instantiates the wizard COM object defined within the .vsz file and creates the custom parameters array that the .vsz file contains. The LaunchWizard method then passes off all the necessary values to the Execute method of that wizard.

You can see the LaunchWizard method in use in the sample CustomWizard. This wizard first verifies that the first argument of the ContextParams array is the expected wizard type GUID, and then it simply walks the list of context and custom arguments that it is passed, displaying a message box for each item that it finds in those arrays. Here's the macro that starts this wizard running:


Sub CallCustomWizard()
Dim contextParams(1) As Object
contextParams(0) = "{9A4B2CFF-7A69-4671-BFA5-AE0D0C44AEFB}"
contextParams(1) = "Hello world!"
DTE.LaunchWizard("C:\samples\CustomWizard.vsz", contextParams)
End Sub

If the wizard sample is placed in the folder C:\samples, this macro packs the wizard type and the string "Hello world!" into an array of type object and then calls LaunchWizard. The wizard defined the GUID {9A4B2CFF-7A69-4671-BFA5-AE0D0C44AEFB} and expects this string as the first element of the ContextParams array; if the wizard doesn't get this string, it will refuse to run and will return immediately with an error.


Chaining Custom Wizards


You can use the LaunchWizard method to chain wizards together, which means calling one wizard within another wizard to simplify creating a project. Suppose you need a solution that contains an XML Web service and you need a Windows Forms application to gather data from that XML Web service and display it to the user. Creating the form project is simple enough: you run the Windows Form Wizard to create the Windows Forms template project, and then you create the wizard object that will add the form template to a solution. But creating the XML Web service for the solution isn't as easy as creating a template and adding it to the solution. An XML Web service project, once created, is found only on a Web server. None of the files for that XML Web service except the project file are found on the local computerthe project file simply points to the server and the location on the server where the files can be found. A wizard could talk to the Web server through a protocol such as Front Page server extensions, giving it the proper commands to store the files of an XML Web service, but it would be easier to call on the Web Service Wizard to create the and store those files for you.

The sample project ChainWizard, which is included with the sample files for this book, demonstrates how to do this. Here's a portion of the Execute method of this wizard:


const string serviceName = "ChainWizardWebService";
object []contextParamsChain = new object[7];
EnvDTE.wizardResult wizardResultChain;
EnvDTE.DTE dte = (EnvDTE.DTE)Application;
// Add our web service by filling in the context parameters,
// and chain to the Web Service Wizard
contextParamsChain[0] = EnvDTE.Constants.vsWizardNewProject;
contextParamsChain[1] = serviceName;
contextParamsChain[2] = "http://localhost/" + serviceName;
contextParamsChain[3] = System.IO.Path.GetDirectoryName(dte.FullName);
contextParamsChain[4] = (bool)ContextParams[4];
contextParamsChain[5] = ";
contextParamsChain[6] = false;
string webSvcTemplatePath = dte.Solution.get_TemplatePath(
VSLangProj.PrjKind.prjKindCSharpProject);
webSvcTemplatePath += "CSharpWebService.vsz";
wizardResultChain = dte.LaunchWizard(webSvcTemplatePath,
ref contextParamsChain);

This code creates and fills in the context parameters that are sent to the wizard object, which is run with the call to LaunchWizard. You calculate the location of the .vsz file for the XML Web service by using the TemplatePath property and passing the project type for the C# project language. Note that this code makes no attempt to create a unique XML Web service name every time it is run. If the wizard is run multiple times, you should either delete the XML Web service created on the server or change the variable value serviceName to a unique value.

The result of running the ChainWizard sample is a solution containing an XML Web service project and a Windows Forms project that consumes the functionality of the XML Web service.


Lab: Decoding Wizard Parameters


How do you determine which arguments to pass to a wizard during chaining? You can do it by tricking Visual Studio .NET into calling a throwaway wizard whose sole use is to capture and let you debug the custom and context parameters passed to the wizard. This is what I did to find what should be passed to the ASP.NET Web Service Wizard in the ChainWizard sample.

To start, run the Visual Basic .NET or C# Class Library wizard from the New Project dialog box. Then modify that project to implement the IDTWizard interface and register the library as a COM object by assigning the code a GUID and a ProgID and setting the flag in the project Property Pages dialog box to register as a COM object, just as you would for other wizards. The next step is to change the .vsz file to point to this throwaway wizard; because our example chains to the C# Web Service Wizard, we'll modify the .vsz file for that wizard. Search in the Visual Studio .NET 2003\VC#\CSharpProjects folder for the file named CSharpWebService.vsz and open the file in Notepad. We're about to modify this file, so it might be a good idea to make a backup copy.

With this .vsz file open in Notepad, simply change the ProgID from VsWizard.VsWizardEngine.7.1 to the ProgID of the throwaway wizard, and then save the .vsz file. Now, back in Visual Studio .NET, where you have the wizard project open, place a breakpoint on the Execute method of your wizard and press F5. (You'll need to set Visual Studio .NET, or devenv.exe, as the debug target first.) In the new instance of Visual Studio .NET that appears, open the New Project dialog box and run the C# ASP .NET Web Service Wizard. Your wizard should be called in place of the ASP.NET Web Service Wizard, and when the breakpoint on the Execute method is hit, you can spy on what kind of data is passed to the wizard through the custom and context parameters.

Don't forget to restore the correct .vsz fileotherwise, the throwaway wizard will be run when you actually want to create an XML Web service.


/ 118