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

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

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

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

Brian Johnson

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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










Working with Language-Specific Project Objects


The Visual Studio .NET project object model was designed to provide functionality common to all project types. However, some projects can support additional, unique functionality. For example, a C# project has a references node within its project, but a Setup project does not. If you could programmatically add and remove these references, you'd get a lot of flexibility in writing add-ins, macros, and wizards. To enable such project-specific programming, the Visual Studio .NET project object model is extensible, allowing each project type to offer additional methods and properties beyond those defined by the Project object.

You can access the specific object type by using the Object property of the Project object. This property returns an object of type System.Object, which you can convert to the object model type supported by a specific language. The most commonly used project extension is the VSProject object, which is available for a Visual Basic .NET or C# project types.



VSProject Projects


VSLangProj.VSProject is the interface that defines extensions to the EnvDTE.Project object for Visual Basic .NET or C# projects. Once you've retrieved the EnvDTE.Project interface for one of these project types, you can get to the VSLangProj.VSProject interface by calling the Project.Object property. The following macro code, which assumes that the first project in the Projects collection is a Visual Basic or C# project, retrieves the VSProject object for that project:


Sub GetVSProject()
Dim project As EnvDTE.Project
Dim vsproject As VSLangProj.VSProject
project = DTE.Solution.Projects.Item(1)
vsproject = CType(project.Object, VSLangProj.VSProject)
End Sub

References


References are pointers to software components that a project can use to reduce the amount of code a programmer needs to write. A project uses the type information contained within a reference to display information in the form of IntelliSense statement completion. A reference also provides information to the compiler for resolving symbols used in programming code. A reference can be an assembly or another project loaded into the solution, and you can create references to COM components by wrapping the COM object type information library with an interop assembly. You can add references through the user interface by right-clicking the References node in a Visual Basic or C# project, choosing Add Reference from the shortcut menu, and then selecting a component in the dialog box that appears.

Using the VSLangProj.References object, you can enumerate, add, or remove references. To get to the References object, you use the VSProject.References property. For example, the following code retrieves the References object and then enumerates the references that have been added to a project:


Sub EnumReferences()
Dim proj As EnvDTE.Project
Dim vsproj As VSLangProj.VSProject
Dim references As VSLangProj.References
Dim reference As VSLangProj.Reference
proj = DTE.Solution.Projects.Item(1)
vsproj = proj.Object
references = vsproj.References
For Each reference In references
MsgBox(reference.Name)
Next
End Sub

You add a reference to an assembly by calling the References.Add method and passing the path to the assembly. The Add method copies the assembly into the project output folder unless a copy of the assembly with the same version and public key information is stored in the global assembly cache (GAC). This is done so that when the project output is run or loaded by another assembly, the correct assembly referenced can be loaded. The following macro code adds a reference to an assembly:


Sub AddReferenceToAssembly()
Dim vsproj As VSLangProj.VSProject
Dim proj As EnvDTE.Project
proj = DTE.Solution.Projects.Item(1)
vsproj = CType(proj.Object, VSLangProj.VSProject)
vsproj.References.Add("C:\Program Files\Microsoft Visual Studio .NET " _
& "2003\Common7\IDE\PublicAssemblies\extensibility.dll")
End Sub

This code finds the VSProject object for a project and then adds a reference to the Extensibility.dll metadata assembly (assuming that the default installation location of Visual Studio .NET was used)the same assembly that contains the definition of the IDTExtensibility2 interface, which is used for building add-ins. You can't add assemblies located within the GAC as references to a project because the Visual Basic and C# project systems maintain a separation between the files that are referenced for building against and files that are used during a component's run time.

During development, a component that is compiled by one project in a solution might be needed by a component in another project. You can create a reference from one project to another project by using the References.AddProject method. This method accepts a Project object and adds a reference to that project, as shown here:


Sub AddProjectReference()
Dim vsproj As VSLangProj.VSProject
Dim proj As EnvDTE.Project
'Find the project the reference will be added to:
proj = DTE.Solution.Projects.Item(1)
vsproj = CType(proj.Object, VSLangProj.VSProject)
'Find the referenced project:
proj = DTE.Solution.Projects.Item(2)
'Make the project to project reference:
vsproj.References.AddProject(proj)
End Sub

Adding a reference to a COM object requires a few values that are COM-centric and might not be very intuitive to the non-COM programmer: the type library GUID, or library identifier (LIBID), of the type library that defines the COM component, and the version major and minor values of that type library. Using these values, you can add a reference to the type library of a COM component, and Visual Studio .NET will automatically create an interop assembly for that type library. The following macro code adds a reference to the type library for Windows Media Player:


Sub AddCOMReference()
Dim vsproj As VSLangProj.VSProject
Dim proj As EnvDTE.Project
proj = DTE.Solution.Projects.Item(1)
vsproj = CType(proj.Object, VSLangProj.VSProject)
vsproj.References.AddActiveX( _
"{22D6F304-B0F6-11D0-94AB-0080C74C7E95}", 1, 0)
End Sub

Web References


The .NET Framework not only makes traditional software development easier, but it also makes new software development methodologies possible. One of these new methodologies involves XML Web services. XML Web services enable software development across the Internet by placing software code on a server, which can then be accessed by software that is run on the user's computer. Visual Studio .NET makes connecting desktop software to XML Web services as easy as adding a Web reference. When a reference to an XML Web service is made, a special file written using the Web Services Description Language (WSDL) file is downloaded from the server computer and a proxy class (a class that contains the logic to translate a method or property call from the client computer across the Internet to the server computer) is generated from the WSDL file. This proxy class can then be used to call to the XML Web service.

The following macro adds a Web reference to a project. It retrieves the VSProject object for a project and then calls the AddWebReference method with the URL for the XML Web service. This example uses the TerraServer Web service provided by Microsoft, which offers detailed geographic information and satellite images for the United States. This Web service is located at http://terra­server.homeadvisor.msn.com/TerraService.asmx


Sub AddTerraServerWebRef()
Dim vsProj As VSLangProj.VSProject
Dim serviceURL As String
'Set the URL to the TerraServer web service
serviceURL = "http://terraserver.microsoft.net/TerraService.asmx"
'Find the VSProject for a project
vsProj = DTE.Solution.Projects.Item(1).Object
'Add the web reference
vsProj.AddWebReference(serviceURL)
End Sub

When this Web reference is made, the WSDL file describing the XML Web service is downloaded from the server computer and the proxy class for the service is generated and automatically added to the project. This class is placed in a namespace defined by the server's URL, but in reverse order. So, for example, if the XML Web service were located at http://www.microsoft.com, the namespace for the service would be com.microsoft.www. In this example, TerraServer is located at the server URL http://terraserver.homeadvisor.msn.com so the namespace used is com.msn.homeadvisor.terraserver. Once a reference to an XML Web service has been added to a project, using that service is as easy as calling methods on the generated proxy class.


Lab: Using an XML Web Service


While working on this book, I bought an electronic telescope that can automatically find and point to stars. But before I could use it, I needed to program the telescope with the latitude and longitude of my locationRedmond, Washington. But how could I find this information? The solution was to write a small program that can be run on any computer with an Internet connection to find my location through the TerraServer XML Web servicea kind of cheap, Web-enabled GPS locator.

After creating a new C# console application and adding a reference to the TerraServer Web service, I had all the pieces necessary to find the location of a city anywhere within the United Sates. To find a location, a variable of type Place, which is filled in with the name of a city, state, and country, is passed to the TerraService.GetPlaceFacts method. This method returns an object of type PlaceFacts, which holds, among other data, the latitude and longitude of the specified city. The following code is the same code I used to find my geographic location; all you do to find the latitude and longitude of your own location is to change the strings for the city, state, and country.

[View full width]

static void Main(string[] args)
{
//Declare variables:
com.msn.homeadvisor.terraserver.PlaceFacts placeFacts;
com.msn.homeadvisor.terraserver.TerraService terraService;
com.msn.homeadvisor.terraserver.Place place;
//Create the necessary objects:
terraService = new com.msn.homeadvisor.terraserver.TerraService();

place = new com.msn.homeadvisor.terraserver.Place();
//Find the Latitude and Longitude for Redmond, Washington:
place.City = "Redmond";
place.State = "Washington";
place.Country = "USA";
//Call to the web service,
retrieving the requested information:
placeFacts = terraService.GetPlaceFacts(place);
//Display the information to the console:
System.Console.Write(place.City + " Latitude and Longitude: ");

System.Console.Write(placeFacts.Center.Lat.ToString());
System.Console.Write(" ");
System.Console.WriteLine(placeFacts.Center.Lon.ToString());
}



Imports


To make the programmer's life easier, Visual Basic .NET and C# source code can contain using and Imports statements to shorten the identifiers used to access the namespace defined by a library of code. For example, to display a message box, you could use the longer, more specific identifier to resolve to a class name:


System.Windows.Forms.MessageBox.Show("Hello World")

But if this code were repeated a number of times, you'd have to type the name­space identifier over and over, which could lead to programming errors. You can use an Imports statement in Visual Basic to shorten what you have to type:


Imports System.Windows.Forms

Later in the program, you can use this shorter form of the code:


MessageBox.Show("Hello World")

Visual Basic also allows you to enter import statements through a project's Property Pages dialog box (Figure 8-3) rather than typing the Imports statement into the source code. By using the dialog box instead of typing the statement into code, you can make the imports available for all the files within the project, not just the file that uses the Imports statement.


Figure 8-3. Entering import statements through the project's Property Pages dialog box



Using the VSProject.Imports collection, you can enumerate, remove, and add imports for the entire project. The following macro adds the System.XML namespace to a Visual Basic .NET project:


Sub AddSystemXMLImport()
Dim vsProj As VSLangProj.VSProject
Dim vsImports As VSLangProj.Imports
vsProj = DTE.Solution.Projects.Item(1).Object
vsProj.Imports.Add("System.Xml")
End Sub

Note

The Imports object is valid only for the Visual Basic .NET project type. Any attempt to access this object for another project type will return null if you're using C# to access this object or will return Nothing if you're using Visual Basic .NET.



ProjectProperties


Each project has a number of options associated with it that allow you to control how you interact with that project. You can set these options under the Common Properties node of a project's Property Pages dialog box. The options include the name of the component that the compiler should build, the kind of project to be generated (an .exe or a .dll), and layout options for the HTML designer. You can also set these options programmatically by using the Properties property of the Project object. This property returns the same Properties object that's used throughout Visual Studio .NET to set options. The following macro walks the list of properties available to a project as well as the values and types of each property:


Sub WalkVSProjectProperties()
Dim project As EnvDTE.Project
Dim properties As EnvDTE.Properties
Dim [property] As EnvDTE.Property
Dim owp As InsideVSNET.Utilities.OutputWindowPaneEx
owp = New InsideVSNET.Utilities.OutputWindowPaneEx(DTE, _
"Project properties")
project = DTE.Solution.Projects.Item(1)
properties = project.Properties
For Each [property] In properties
owp.WriteLine("Name: " + [property].Name)
owp.WriteLine("Value: " + [property].Value.ToString())
owp.WriteLine("Type: " + [property].Value.GetType().FullName)
owp.WriteLine()
Next
End Sub

You can use this Property object not only to read the values of properties but also to set the properties for a project. The following macro demonstrates this. It sets the icon to use for a project when it is compiled. This code assumes that an icon named Icon.ico is located in the folder containing the project file.


Sub SetProjectIcon()
Dim project As EnvDTE.Project
Dim [property] As EnvDTE.Property
Dim projectPath As String
project = DTE.Solution.Projects.Item(1)
'Get the Property object for the icon:
[property] = project.Properties.Item("ApplicationIcon")
'Construct the path to the icon based off of the
' project path:
projectPath = project.FullName
projectPath = System.IO.Path.GetDirectoryName(projectPath)
projectPath = projectPath + "\Icon.ico"
'Set the icon for the project:
[property].Value = projectPath
End Sub


/ 118