Visual Studio Hacks [Electronic resources] نسخه متنی

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

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

Visual Studio Hacks [Electronic resources] - نسخه متنی

Andrew Lockhart

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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







Hack 34. Customize Your Project Build Process

Find out how to automate tasks that occur prior
to, during, or after a build.

While the Visual Studio build process is
familiar for all .NET developers, not everyone realizes the build
customization capabilities that can be accomplished with just a
little work. You can easily put together tasks that occur before,
after, and even during a build.


With the release of Visual Studio 2005 (Whidbey), a new build
toolcalled MSBuildwill be used within the Visual Studio
environment. This tool will provide many build process workflows and
will be similar to NAnt in capability.


4.12.1. Pre- and Post-Build Event Commands


In nonweb projects, you can create
pre- and post-build event commands. As their names suggest, these are
commands that you can customize to run just prior to or after a
build. You can even control whether the post-build event executes at
all depending on the outcome of the build. You can find these
settings on the project properties under the Build Events tab (see
Figure 4-26).


Figure 4-26. Project build events

Just type in the command you want to occur for each event type. When
you select the text box to enter the command, you can click on the
button on the righthand side of the text box to expand the command
window and gain access to the list of macros or variables available.
These variables help provide some shortcuts to including pathnames,
project output locations, and other information into your event
commands. Note that the variables are sensitive to the type of build
you are compiling, so if you switch to a release build, the variables
referencing the output directory will be correctly pointed at the
\bin\release directory (or wherever you have set
up the output directory to be). Table 4-2 provides
a few examples of the macros available.

Table 4-2. Macro examples

Name


Description


$(TargetPath)


The full directory path to the output directory, including the
project output filename. Example:
c:\CSharpWinFormApp\bin\debug\CSharpWinFormApp.exe.


$(TargetDir)


The full directory path to the output directory. Example:
c:\CSharpWinFormApp\bin\debug\.


$(ProjectDir)


The full directory path to where the project file exists. Example:
c:\CSharpWinFormApp\.

The build event command lines are simply command-line operations that
will be executed at the specified time. In fact, the command line you
enter in the properties tab actually gets copied out into a batch
file (stored in the output directory for the project). These batch
files will be named PreBuildEvent.bat or
PostBuildEvent.bat and are handy to help
troubleshoot your build events if necessary.

Note that a failing build event will be shown in the build output and
listed in the Build Error task list along with any other build
errors. A failing pre-build event will cause the build to stop, while
a failing post-build event will still mark the build as a failure
even if the build of the code succeeded without errors. You can
choose to have the post-build event occur every build, only if the
build succeeded, or when the project output (the resulting
.dll or .exe) actually
changes.

A great example of using a custom post-build event is when you have
multiple configuration files. When you add an
app.config file to your project, it will
automatically be copied to the output directory of the project and renamed
to match up with the project output file (e.g.,
CSharpWinFormApp.exe.config), but the IDE will
not do the same with other custom configuration files. What if your
project had multiple .config files to break up
the settings? For example, you have app.config
to store application configuration but then you also have an
EndUser.config file to store
user-specific settings that you didn't want to mix
with the application settings. By default, this configuration file
would not be copied to your output directory, and the application
would receive an exception if it went looking for the file during
execution. To get around this, a custom post-build event can copy the
EndUser.config file to the output directory
every time a build succeeds.

In the Build Events tab, choose to run a Post-Build event when a
successful build occurs and add a Post-Build event command line of:

copy "$(ProjectDir)EndUser.config" "$(TargetDir)"

Note the use of quotes around the
variables and commandsthe quotes are there because there may
be spaces in the file and pathnames. Also, the variables that
generate pathnames will append an ending slash automatically. After a
successful build of this project the current version of the
EndUser.config file in the project directory
will be copied to the output directory.

Copying files after a build is just one example of how these build
events can be useful. More complex operations can be performed as
well. For example, a Windows script or executable could be run when a
build completes to kick off a set of test scripts against the newly
built output. The build event could just as easily automatically
create and register an output type library for use with COM or even
register a newly built component with the GAC.

Pre- and post-build commands are available only to nonweb C#
applications in Visual Studio .NET 2003, but they are also available
to nonweb Visual Basic .NET applications in Visual Studio 2005.


4.12.2. Handling Build Events


Some of
the limitations of the custom pre- and post-build command events are
that they are available for only nonweb projects and are only project
specific. They don't give you the flexibility to
deal with building a multiproject solution or provide a way of
handling more complex build outcomes other than a successful build, a
failed build, or a changed project output. For more advanced handling
of build events, we turn to the Visual Studio Macro Environment.

To hook into the IDE build events, all we need to do is create some
simple
macros. Open up
your Macro IDE (from Tools Macros Macro IDE)
[Hack #51] . If you
haven't used the Macro IDE before, the first thing
you'll notice is that it resembles the regular
VS.NET IDE, except the Macro IDE is used solely for the creation,
editing, and compiling of macros that can be used within your Visual
Studio IDE.

Open up the MyMacros project and see if it already
contains an EnvironmentEvents module. If it
doesn't, go ahead and copy the one from the Samples
directory into your MyMacros project. The code
looks like this:

Option Strict Off
Option Explicit Off
Imports EnvDTE
Imports System.Diagnostics
Public Module EnvironmentEvents
#Region "Automatically generated code, do not modify"
'Automatically generated code, do not modify
'Event Sources Begin
<System.ContextStaticAttribute( )>
Public WithEvents DTEEvents As EnvDTE.DTEEvents
<System.ContextStaticAttribute( )>
Public WithEvents DocumentEvents As EnvDTE.DocumentEvents
<System.ContextStaticAttribute( )>
Public WithEvents WindowEvents As EnvDTE.WindowEvents
<System.ContextStaticAttribute( )>
Public WithEvents TaskListEvents As EnvDTE.TaskListEvents
<System.ContextStaticAttribute( )>
Public WithEvents FindEvents As EnvDTE.FindEvents
<System.ContextStaticAttribute( )>
Public WithEvents OutputWindowEvents As EnvDTE.OutputWindowEvents
<System.ContextStaticAttribute( )>
Public WithEvents SelectionEvents As EnvDTE.SelectionEvents
<System.ContextStaticAttribute( )>
Public WithEvents SolutionItemsEvents _
As EnvDTE.ProjectItemsEvents
<System.ContextStaticAttribute( )>
Public WithEvents MiscFilesEvents As EnvDTE.ProjectItemsEvents
<System.ContextStaticAttribute( )>
Public WithEvents DebuggerEvents As EnvDTE.DebuggerEvents
'Event Sources End
'End of automatically generated code
#End Region
End Module

This sets up the types of IDE events you can hook into. Now if you
open the EnvironmentEvents module in your
MyMacros folder, you can select the
BuildEvents from the Class Name drop-down (the
left drop-down box above the code). Then from the right Method Name
drop-down, you can select one of four build events to hook into:

OnBuildBegin


Will fire when any build operation is fired from the IDE. It fires
only once for a full solution or multiproject build operation.


OnBuildDone


Will fire when a build operation completes. This event fires only
once for a full solution or multiproject build operation.


OnBuildProjConfigBegin


Will fire when a project build begins. This event is used to catch
each project build event within a solution or multiproject build
operation.


OnBuildProjConfigDone


Will fire when a project build completes. This event is used to catch
the completion of each project build within a solution or
multiproject build operation.




These events fire even if build errors or warnings occur, and the
default behavior of Visual Studio is to build all projects in a
solution even if projects earlier in the build have failed.

For an example, you can add the capability to stop the build process
when a project fails and display a message box in the IDE to note
when the build process is complete (in case someone
isn't paying attention to the Build output).

4.12.2.1 Canceling a failed build


The normal
behavior of Visual Studio is to build every project in a solution,
even if one or more of those projects fails. If you have a half-dozen
projects in your solution, then this can sometimes take a little
while. It is much faster if the build quits when any of the projects
fails. By handling a build event, you can ensure that.

Start by selecting the OnBuildProjConfigDone event from the Method
Name drop-down above the code. The Macro IDE will automatically
generate the method signature to hook the event:

Private Sub BuildEvents_OnBuildProjConfigDone( _
ByVal Project As String, _
ByVal ProjectConfig As String, _
ByVal Platform As String, ByVal SolutionConfig As String, _
ByVal Success As Boolean) _
Handles BuildEvents.OnBuildProjConfigDone
End Sub

Since this event will fire whenever a project completes a build, you
can easily stop the rest of the build from occurring by using the
ExecuteCommand method of the DTE object to send a
Build.Cancel command to the IDE. The DTE
object [Hack #86]
is a reference to the Visual Studio IDE, and using
DTE.ExecuteCommand method to cancel the build is
the same as hitting Ctrl-Break during a build or typing
Build.Cancel into the IDE command window. Using
the Success parameter of the event signature, you can determine
whether you want to stop the build. The code looks like this:

Private Sub BuildEvents_OnBuildProjConfigDone( _
ByVal Project As String, ByVal ProjectConfig As String, _
ByVal Platform As String, ByVal SolutionConfig As String, _
ByVal Success As Boolean) _
Handles BuildEvents.OnBuildProjConfigDone
If Success = False Then
'The build failed...cancel any further builds.
DTE.ExecuteCommand("Build.Cancel")
End If
End Sub

4.12.2.2 Alert the user on a successful build


Now, the idea was to capture the end of the build
process to alert the user that the build was complete. For that you
hook into the OnBuildDone event the same way you
did for the project build complete. This time,
you'll use a standard Windows message box to display
an informative alert:

Private Sub BuildEvents_OnBuildDone( _
ByVal Scope As EnvDTE.vsBuildScope, _
ByVal Action As EnvDTE.vsBuildAction) _
Handles BuildEvents.OnBuildDone
'Alert that we finished building!
System.Windows.Forms.MessageBox.Show("Build is complete!")
End Sub

These are some pretty simple examples, but you have the power of the
.NET Framework in your hands for any of these events so you are
limited only by what you can come up with to handle. You can share
these with other developers by just sending them the code to include
in their own macro project or take it a step further and create a
Visual Studio add-in that hooks these events and distribute it that
way. If you take a look at the other IDE events you can tap into, you
will understand why the Visual Studio IDE is so extensible.

Something to consider when you are implementing custom build events
is that they are handled within the IDE only. Build events
implemented using the extensibility of the IDE (macros or add-ins)
will not fire if the build is run from the command line [Hack #78] . However, pre- and post-build
event commands will execute even if the build is being run via the
command line with devenv.exe /build. This could be
important if you want to automate your build process on a build
machine.

Michael Wood


/ 172