In the previous examples I have use C# as my language of choice. C# is not your only choice you can also use VB.Net but you can also use JavaScript! When MSBuild creates the class for the inline task it uses CodeDom to do so, and JavaScript is one of its supported languages. Perhaps its actually called JScript. In any case take a look at the project file below which shows this in action.
Here you can see that I created a new inline task called, Jsex01 and its written in Javascript. Then inside of the PrintValues target this task is called. If you execute the PrintValues target the result will be what you see below.
So if you prefer JavaScript to C# or VB.Net then you should try this out!
Do you have a great idea for the next version of Visual Studio and you want to get your voice heard? Now is your chance! Go to twitter and post a message stating your request with the hash tag #vswish and we will take a look at it. We are listening to that channel so please do submit your feedback.
I’m happy to say that I was offered, and accepted, a position on the Web Platform and Tools team with Microsoft. I will be a Program Manager on that team. In a nutshell I will be responsible for helping to make development easier for web developers using .NET and Visual Studio. Its a very interesting role and I’m gonna be pretty challenged in the next few months to adapt to my new role. The Web Platform and Tools team has a bunch of tools that they are responsible for, and one of the is the Web Deployment Tool. I think that this will be one of the areas that I will be working in, so if you have any ideas feel free to drop me a line here or privately at sayed –DOT—hashimi [AT] gmail –DOT—com. I will start in this role in about 2 weeks.
Have you ever executed a .cmd file (or .bat) file and received a message that looks like the following at the top of your script (including image for compatibility) ? This was really annoying to me until I find out what was happening. I noticed that Visual Studio (2010 at least, but I think previous version as well but not sure) was changing the encoding of my .cmd files to be UTF-8! For example consider this simple script (sample.cmd) that I created with Notepad.
echo 'hello world'
When I execute this .cmd file from the command line the results are as shown below.
What I did then was to simply create a copy of that file and placed that in a file named sample-vs.cmd and then edited the script using Visual Studio 2010 to have the contents below.
echo 'hello world from Visual Studio'
When I execute that .cmd file to my surprise the results shown below are displayed.
I was definitely not expecting that (OK yeah I was because I created that script for this blog post, but just go with it). I then opened the file in notepad and it looked normal. So I edited it it notpad, saved it and the result was still the same. The first line was not being processed correctly, it seemed. As I was editing the file I noticed the encoding of the files were different. The encoding for the sample.cmd file was set to ANSI and for sample-vs.cmd UTF-8. See for yourself from the screen shots below.
So I switched the setting for the sample-vs.cmd file to ANSI, executed the script and all was good!
If you are doing any kind of web development and you are not familiar with the Web Platform Installer(WPI) then you need to take a look at it. I just installed WordPress on IIS 7 with just a few clicks and filled in a few text boxes. When you install WordPress there are some prerequisites like mySql and php. The WPI was smart enough to realize that I had neither installed, downloaded those, installed them and configured them. I was prompted for some info for those tools of course. I’ve also installed a few other apps using the WPI like, MSDeploy and dasBlog and I didn’t have any issues what so ever.
When using the WPI there are two main categories that can be installed, Web Platform and Web Applications. The Web Platform category includes items like frameworks (i.e. ASP.NET, PHP), Database (i.e. mySql) and other high level shared components. The Web Applications includes various web applications. Some others that I didn’t list previously include; DotNetNuke, nopCommerce, and umbarco just to name a few. I’m not sure how many apps are available but it looks like at least 50.
If you are an app creator and would like to share your app then you can visit the WPI Developer page for a starting point.
The past few days I was unable to Edit and Continue in Visual Studio 2010 Ultimate from my home machine, which is running Windows 7 64bit. I knew there were some issues with this on 64bit, I figured one of my projects was not targeting x86 so I just ignored it. Then today I was really getting annoyed at seeing the dialog.
So I started playing around with the configuration settings made sure that everything was in order and still no dice.
After that I performed a repair of Visual Studio, and then reset all the settings under Tools>Import and Export Settings and that still didn’t solve the problem. Then I remembered that I change my IntelliTrace settings the other day so I went to disable it and to my surprise I saw the dialog box shown below.
When I changed the IntelliTrace setting to collect call information I didn’t notice the warning stating “Edit and continue is disabled when collecting Call Information”! So I changed the setting and everything was good. Microsoft should add this to the Edit and Continue dialog box not available, I’ll ping a few people I know about that. FYI I created this question on Stackoverflow before I resolved it myself.
Recently I had the chance to work on a WPF app and it was behaving very strangely when I built and ran the application. For instance I tried to debug the application from Visual Studio and I received an error staging “Visual Studio cannot start debugging because the debug target ‘PATH HERE’ is missing. Please build the project and retry, or set the OutputPath and AssemblyName properties appropriately to point at the correct location for the target assembly.”
So I checked the properties, every thing looked good. I even built the project from the command line and it built fine. Anywayz at some point after that I was able to debug the app. But then I noticed that the UI was not getting updated with my changes. So I started digging a bit deeper. I noticed that when I ran a Clean from Visual Studio the output files for that particular project.
I then rebuilt the solution in Visual Studio. From the Output window I selected all the text,copied it, and then pasted that into an editor. After looking at the message
------ Skipped Clean: Project: R…ion: Debug Any CPU ------ Project not selected to build for this solution configuration ------ Skipped Clean: Project: R…Admin.Wpf, Configuration: Debug x86 ------ Project not selected to build for this solution configuration ------ Clean started: Project: Test…er, Configuration: Debug Any CPU ------ Build started 5/8/2010 1:10:02 AM.
I immediately knew that there was an incorrect value in the build configuration manager. You can find the configuration manager from the toolbar.
Here is what I found.
In this dialog there are two project set not to build for Debug builds; the DB project and the Wpf project. The DB project is OK to not build on Debug if there are a small % of DB changes versus code changes. If that is the case the devs can just build the DB project manually when the change it. In the case of the Wpf project, it should be set to build and the fact that it wasn’t was causing all the issues. So I checked the build check box, clicked the Close button and it was all good. You should also make sure that all other configuration as setup correctly. You don’t want to get bitten by this again.
If you are using Visual Studio 2010 then you may already be aware that Web Deployment Tool (aka MSDeploy) is integrated into Visual Studio. I’ve posted a few blog entries already about this tool. Two of the common questions that I get discussing this with people are
How do I exclude files from being placed in the package?
How do I add other files to the created package?
I will address these two questions here, first we look at the easier one, how to exclude files but we will go over a bit of background first.
Web Publishing Pipeline
With Visual Studio 2010 a new concept has been created which is known as the Web Publishing Pipeline. In a nutshell this is a process which will take your web application, build it and eventually create a package that you can use to deploy your application. This process is fully captured in MSBuild. With VS 2010 many targets and many tasks are shipped to support this process. Since its captured in MSBuild format, you can customize and extend to your hearts desire. So what we need to do is hook into this process to perform the customizations that we need. This process is captured in the following files.
The Microsoft.WebApplication.targets file is imported by the web applications projects file, then that file imports the Microsoft.Web.Publishing.targets file.
Excluding files from being packaged
If you open the project file of a web application created with VS 2010 towards the bottom of it you will find a line with.
BTW you can open the project file inside of VS. Right click on the project pick Unload Project. Then right click on the unloaded project and select Edit Project.
This statement will include all the targets and tasks that we need. Most of our customizations should be after that import, if you are not sure put if after! So if you have files to exclude there is an item name, ExcludeFromPackageFiles, that can be used to do so. For example let’s say that you have file named Sample.Debug.js which included in your web application but you want that file to be excluded from the created packages. You can place the snippet below after that import statement.
By declaring populating this item the files will automatically be excluded. Note the usage of the FromTarget metadata here. I will not get into that here, but you should know to always specify that.
Including extra files into the package
Including extra files into the package is a bit harder but still no bigee if you are comfortable with MSBuild, and if you are not then read this. In order to do this we need to hook into the part of the process that collects the files for packaging. The target we need to extend is called CopyAllFilesToSingleFolder. This target has a dependency property, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, that we can tap into and inject our own target. So we will create a target named CustomCollectFiles and inject that into the process. We achieve this with the following (remember after the import statement).
This will add our target to the process, now we need to define the target itself. Let’s assume that you have a folder named Extra Files that sits 1 level above your web project. You want to include all of those files. Here is the CustomCollectFiles target and we discuss after that.
Here what I did was create the item _CustomFiles and in the Include attribute told it to pick up all the files in that folder and any folder underneath it. Then I use this item to populate the FilesForPackagingFromProject item. This is the item that MSDeploy actually uses to add extra files. Also notice that I declared the metadata DestinationRelativePath value. This will determine the relative path that it will be placed in the package. I used the statement Extra Files%(RecursiveDir)%(Filename)%(Extension) here. What that is saying is to place it in the same relative location in the package as it is under the Extra Files folder.
Admittedly this could be easier, but its not too bad, and its pretty flexible.
If you are using MSBuild 4.0 then you may be interested in knowing that there are a couple new switches that you can pass to msbuild.exe when you kick off a build. The new switches, /preprocess(/pp) and /detailedsummary(/ds), are more convenient then necessary.
/preprocess (/pp)
Since you can import other MSBuild files using the Import Element sometimes locating where a target, property or item is being defined can lead to a search that takes you through several files. It can be even more confusing if more than 1 file defines the property or target that you are interested in, because you may have thought that you found the right target but you may one that was overridden by another file. Now with MSBuild 4.0 you don’t have to search through all of those files. You can use the switch /preprocess switch. Here is the snippet from msbuild.exe /? describing it.
/preprocess[:file]
Creates a single, aggregated project file by inlining all the files that would be imported during a build, with their boundaries marked. This can be useful for figuring out what files are being imported and from where, and what they will contribute to the build. By default the output is written to the console window. If the path to an output file is provided that will be used instead.
(Short form: /pp)
Example:
/pp:out.txt
When you use this the full logical project file is dumped to the console, or optionally to a file, and it includes references to where the elements are defined. For example I created the following very simple project files.
As you can see with /pp it is very easy to see exactly what is defined where and at what location.
/detailedsummary (/ds)
Another new feature with MSBuild 4.0 is the /detailedsummary (/ds) command line switch. When you use this switch you will be shown a detailed summary (haha) of build execution. This summary includes the amount of time spent build each project file as well as the node utilization. I just preformed a build with the command msbuild RuleStack.Engine.sln /m /ds and the summary is shown below.
============================== Build Hierarchy (IDs represent configurations) =====================================================
Id : Exclusive Time Total Time Path (Targets)
-----------------------------------------------------------------------------------------------------------------------------------
0 : 0.020s 1.211s C:\...\RuleStack.Engine.sln ()
| 1 : 0.667s 0.667s C:\...\RuleStack.Engine.Common\RuleStack.Engine.Common.csproj ()
| 3 : 0.255s 0.718s C:\...\Unittest\RuleStack.Engine.Tests\RuleStack.Engine.Tests.csproj ()
| | 6 : 0.000s 0.000s C:\...\ObjectBinder\RuleStack.ObjectBinder\RuleStack.ObjectBinder .csproj ()
| | 5 : 0.000s 0.000s C:\...\RuleStack.Data\RuleStack.Data.csproj ()
| | 1 : 0.000s 0.000s C:\...\RuleStack.Engine.Common\RuleStack.Engine.Common.csproj ()
| | 2 : 0.000s 0.000s C:\...\RuleStack.Engine.Backend\RuleStack.Engine.Backend.csproj ( )
| | 8 : 0.292s 0.460s C:\...\RuleStack.Engine.Admin.Web\RuleStack.Engine.Admin.Web.csproj ()
| | | 24 : 0.000s 0.000s C:\...\RuleStack.Engine.Backend\RuleStack.Engine.Backend.csproj ( GetNativeManifest)
| | | 5 : 0.000s 0.000s C:\...\RuleStack.Data\RuleStack.Data.csproj ()
| | . 2 : 0.000s 0.000s C:\...\RuleStack.Engine.Backend\RuleStack.Engine.Backend.csproj ( )
| . 36 : 0.003s 0.003s C:\...\RuleStack.Engine.Admin.Web\RuleStack.Engine.Admin.Web.csproj (GetNativeManifest)
| 2 : 0.319s 0.390s C:\...\RuleStack.Engine.Backend\RuleStack.Engine.Backend.csproj ( )
| | 6 : 0.000s 0.000s C:\...\ObjectBinder\RuleStack.ObjectBinder\RuleStack.ObjectBinder.csproj ()
| | 5 : 0.000s 0.000s C:\...\RuleStack.Data\RuleStack.Data.csproj ()
| | 17 : 0.002s 0.002s C:\...\RuleStack.Data\RuleStack.Data.csproj (GetNativeManifest)
| . 21 : 0.001s 0.001s C:\...\RuleStack.Data\RuleStack.Data.csproj (GetCopyToOutputDirectoryItems)
| 4 : 0.382s 0.567s C:\...\RuleStack.Services\RuleStack.Services.csproj ()
| | 5 : 0.000s 0.000s C:\...\RuleStack.Data\RuleStack.Data.csproj ()
| | 2 : 0.000s 0.000s C:\...\RuleStack.Engine.Backend\RuleStack.Engine.Backend.csproj ( )
| | 24 : 0.002s 0.002s C:\...\RuleStack.Engine.Backend\RuleStack.Engine.Backend.csproj ( GetNativeManifest)
| . 29 : 0.001s 0.001s C:\...\RuleStack.Engine.Backend\RuleStack.Engine.Backend.csproj ( GetCopyToOutputDirectoryItems)
| 7 : 0.333s 0.337s C:\...\ObjectBinder\Test_RuleStack.ObjectBinder\Test_RuleStack.ObjectBinder.csproj ()
| | 6 : 0.000s 0.000s C:\...\ObjectBinder\RuleStack.ObjectBinder\RuleStack.ObjectBinder.csproj ()
| | 13 : 0.001s 0.001s C:\...\ObjectBinder\RuleStack.ObjectBinder\RuleStack.ObjectBinder.csproj (GetNativeManifest)
| . 19 : 0.001s 0.001s C:\...\ObjectBinder\RuleStack.ObjectBinder\RuleStack.ObjectBinder.csproj (GetCopyToOutputDirectoryItems)
| 6 : 0.210s 0.210s C:\...\ObjectBinder\RuleStack.ObjectBinder\RuleStack.ObjectBinder.csproj ()
| 5 : 0.277s 0.277s C:\...\RuleStack.Data\RuleStack.Data.csproj ()
| . 12 : 0.000s 0.000s C:\...\RuleStack.Engine.Common\RuleStack.Engine.Common.csproj (GetNativeManifest)
. 43 : 0.002s 0.002s C:\...\RuleStack.Engine.Admin.Web\RuleStack.Engine.Admin.Web.csproj.metaproj ()
============================== Node Utilization (IDs represent configurations) ====================================================
Timestamp: 1 2 3 4 5 6 7 8 Duration Cumulative
-----------------------------------------------------------------------------------------------------------------------------------
634081842447519669: 0 x x x x x x x 0.018s 0.018s
634081842447699679: 1 x x x x x x x 0.461s 0.479s #########
634081842452309943: | 6 7 5 3 4 2 x 0.130s 0.609s ##
634081842453610018: | | | | 8 | | x 0.086s 0.695s #
634081842454470067: | | | | | | | x 0.001s 0.696s
634081842454480067: x | | | | | | x 0.001s 0.697s
634081842454490068: x | x | | x | x 0.001s 0.698s
634081842454500068: x | x | | x x x 0.001s 0.699s
634081842454510069: x x 7 | | x x x 0.002s 0.701s
634081842454530070: 12 x | | | x x x 0.002s 0.703s
634081842454550071: | 13 x | | x x x 0.001s 0.704s
634081842454560072: | x 7 | | x x x 0.008s 0.712s
634081842454640076: | x | | x x x x 0.054s 0.766s #
634081842455180107: | x | x x x 2 x 0.003s 0.769s
634081842455210109: | x | 17 x x x x 0.002s 0.771s
634081842455230110: | x | x x x 2 x 0.036s 0.807s
634081842455590131: | 19 x x x x | x 0.001s 0.808s
634081842455600131: | x 7 x x x | x 0.018s 0.826s
634081842455780142: | x x x x x | x 0.036s 0.862s
634081842456140162: | x x 21 x x x x 0.001s 0.863s
634081842456150163: | x x x x x 2 x 0.016s 0.879s
634081842456310172: | x x x 8 4 x x 0.003s 0.882s
634081842456340174: | x x x | x 24 x 0.001s 0.883s
634081842456350174: | x x x x x | x 0.001s 0.884s
634081842456360175: | x x x 8 4 x x 0.148s 1.032s ##
634081842457840259: | x x x | x 29 x 0.001s 1.033s
634081842457850260: | x x x | 4 x x 0.023s 1.056s
634081842458080273: | x x x | x x x 0.013s 1.069s
634081842458210281: | x x x 3 x x x 0.004s 1.073s
634081842458250283: | x x x 36 x x x 0.003s 1.076s
634081842458280285: | x x x 3 x x x 0.131s 1.207s ##
634081842459590360: 0 x x x x x x x 0.001s 1.208s
634081842459600360: 43 x x x x x x x 0.002s 1.210s
634081842459620361: 0 x x x x x x x 0.001s 1.211s
-----------------------------------------------------------------------------------------------------------------------------------
Utilization: 57.8 30.3 46.9 39.6 76.5 53.6 45.4 .0 Average Utilization: 43.8
In the snippet above you should know that I replace the path to the files with … to reduce the width of the output. Also the machine that I’m currently using has 8 cores so it shows 8 nodes, on your machine you may have a different number of columns for the node utilization table.
If you are using Visual Studio 2010 then you may already be familiar with the Web.config transformations that are now available. What you might not know is that you can use that same technology to transform config files outside of the build process. You will need Visual Studio 2010 installed on the machine where you perform these transformations. It is very easy to perform these transformation as well. Let’s say that we start with the app.config file shown below.
This MSBuild file uses the TransformXml task which is shipped with Visual Studio 2010. We specify the source file, transform file and the destination. Pretty straight forward.
In order to execute this I open a Visual Studio 2010 command prompt, browse to the directory containing both files, and enter the following command
msbuild trans.proj /t:Demo
Once you do this then you will find the file app.prod.config with the following contents.