Many times I want to customize some things or actions during vs compilation,
For example:
Copy the generated file to a specific directory.
DeploymentProgramTo the test directory or environment, such as registering with the Windows Service and updating GAC.
Generate a specific configuration file (such as Web. config) according to the compiling environment PS: in a complex environment, this is my most desired function.
Automatically execute the external exe.
Synchronize DLL files and other resource files.
1. The simplest thing is to use the compile event that comes with Visual Studio. This is easy to use and a feature that comes with Visual Studio. It is actually a little weaker in functionality (well, it is actually very weak)
Copy the DLL file generated by the project to a specific directory. (If you want to copy an entire folder, use xcopy. Of course, people familiar with the command line can come up with more methods)
As shown in
2. Another recommended method is custom compilation extension (you can execute C #Code... More powerful), see the last few statements in the project file below (the project file is the project name. csproj)
< Import Project = "... \ .. \ Build \ Tasks \ build. Tasks" />
< Target Name = "Beforebuild" >
< Message Text = "Start automatic generate configuration file, source file: $ (projectdir) web. config" Importance = "High" >
</ Message >
< Configurationenvironmenttask Templatefile = "$ (Projectdir) web. template. config" Targetfile = "$ (Projectdir) web. config" Datasource = "$ (Environmentname). config" />
</ Target >
</ Project >
Which of the following statements mean:
1. Include a task file (This file contains the definition of configurationenvironmenttask, which is a self-developed class and mainly serves to generate a web. config file according to the environment)
2. Output a row of prompt information start automatic... (this information will be displayed in the output window)
3. Call configurationenvironmenttask and input some parameters (templatefile and so on are all self-defined parameters)
The file content of build. tasks is actually very simple. It mainly describes where the task is defined (build. dll)
<?XML version = "1.0" encoding = "UTF-8"?>
<ProjectXmlns= "Http://schemas.microsoft.com/developer/msbuild/2003">
<UsingtaskAssemblyfile= "Build. dll"Taskname= "Build. configurationenvironmenttask"/>
</Project>
The next point is how to implement this task. The following is the key code of build. dll.
View code
Namespace Build
{
# Region Namespace
Using System. Globalization;
Using System. IO;
Using System. xml;
Using Microsoft. Build. Framework;
Using Microsoft. Build. utilities;
# Endregion
# Region Standard config file sections
/// <Summary>
/// This class generate config/XML file by template
/// </Summary>
Public Class Configurationenvironmenttask: Task
{
# Region Public propreties
/// <Summary>
/// Gets or sets template file path (full path: C: \ WEB. config)
/// </Summary>
[Required]
Public Itaskitem templatefile { Get ;Set ;}
/// <Summary>
/// Gets or sets traget file path, will automatically overwrite this file (full path: C: \ WEB. config)
/// </Summary>
[Required]
Public Itaskitem targetfile { Get ;Set ;}
/// <Summary>
/// Gets or Sets configuration file, will get settings from this path (full path: C: \ WEB. config, relative path: Dev. config)
/// </Summary>
[Required]
Public Itaskitem datasource { Get ; Set ;}
# Endregion
/// <Summary>
/// Execute replace Logic
/// </Summary>
/// <Returns> Ture successful, False Failure </Returns>
Public Override Bool Execute ()
{
String Templatecontent = file. readalltext ( This . Templatefile. tostring ());
Xmldocument xmldoc = New Xmldocument ();
String Filename = Null ;
String Filefolder = Null ;
If (Path. ispathrooted ( This . Datasource. tostring ()))
{
Filefolder = path. getdirectoryname ( This . Datasource. tostring ());
}
Else
{
Filefolder = path. getdirectoryname ( This . Targetfile. tostring ());
}
Filename = path. getfilename ( This . Datasource. tostring ());
If (Filename = Null | String . Isnullorempty (filename) | filename. tolower (cultureinfo. currentculture). Trim () = " . Config " )
{
Filename = @" Local. config " ;
}
This . Log. logmessage ( " Datasource: " + This . Datasource. tostring ());
This . Log. logmessage ( " Ispathrooted: " + Path. ispathrooted ( This . Datasource. tostring ()));
This . Log. logmessage (" Filefolder: " + Filefolder );
This . Log. logmessage ( " Filename: " + Filename );
If (! File. exists (filefolder + @" \ " + Filename ))
{
Throw New Filenotfoundexception ( " Can not find file: " + Filefolder + @" \ " + Filename );
}
Xmldoc. Load (filefolder + @" \ " + Filename );
Foreach (Xmlnode Node In Xmldoc. selectnodes (" /Settings /* " ))
{
Templatecontent = templatecontent. Replace ( " $ ( " + Node. Name + " ) " , Node. innertext). Trim ( New Char [] { ' ' , ' \ R ' , ' \ N ' , ' \ T ' });
}
File. writealltext ( This . Targetfile. tostring (), templatecontent );
Return True ;
}
}
# Endregion Standard config file sections
}
The code is poorly written. This is not the code of the production environment.
The key is the execute method,
The general idea is to read the key-value pairs based on the specified config file and replace the content similar to $ (key) in Web. config.
PS: in the official environment, we actually use a file and environment variable on a website.
Of course, what do you want in this method? modify the configuration file, send an email, or automatically back up the file...
Remember to make your project reference build. dll (we recommend that you put the DLL and task files in the same directory)
Click compile or Ctrl + Shift + B.
All the code in this article has been compiled and run successfully in Visual Studio 2010 and msbuild extenstion 4.0.
In addition, some functions in MS build exenstion are quite good, and many third-party tasks are quite good on the Internet, such as deploying IIS websites and FTP. If you are interested, try it, it may simplify a lot of work.