How to configure post-build events for setup/deployment projects in Visual Studio - visual-studio-2010

My solution has two projects. One is my actual project and another one is setup project.
My actual project has one report folder where I store my all ssrs report. I have one folder in the setup project called "SSRS_Repor". Now I want that when I will do a batch build then setup for my project regenerate, and then I want to copy all files from the report folder of my actual project to SSRS_Repor in my setup project.
If I can do this kind of automation of copying files from one location to another folder of my setup project, then I could be get rid of manual copying of rdls files. I heard this is possible by setup/deployment projects. I searched Google for this for details step-by-step instruction, but I didn't get any good links. So please guide me how can I do it.
I posted it to another forum too, and some one told me below this:
Open or create a setup/deployment project in Visual Studio 2005
Press F4 to display the Properties window
Click on the name of your setup/deployment project in the Solution Explorer
Click on the PostBuildEvent item in the Properties window to cause a button labeled "..." to appear
Click on the "..." button to display the Post-build Event Command Line dialog
Add a command line of your choice in the Post-build event command line text box
Build your project in Visual Studio and verify that the post-build event is executed after the main MSI build
So it is OK, but what do I need to write for copying files from one location to another location? That is not clear to me. So now this is most important for me what to write for copying file during setup generation.
I got another clue like below one. A script for setup Pre/Post Build Event, but not aware properly. I got a sample like
copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)lib\$(ProjectName).dll"
The above statement or line is not clear to me. What do I need to write in my case? I need a step-by-step guide.
Here is the screenshot of my project structure

To answer your question simply:
The commands that you input in the build events (be it pre or post) are the same as you would enter in a command line box.
In your example:
copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)lib\$(ProjectName).dll"
copy is the actual DOS copy command.
/Y is a regular switch that prevents confirmation prompts.
"$(TargetDir)$(ProjectName).dll" is the source file to copy.
"$(SolutionDir)lib\$(ProjectName).dll" is the destination where to copy the file.
You can refer here to have additional information on batch file commands: Batch command list
The $({Identifier}) are macros you can use in Visual Studio Pre/Post Build event designer.
You can refer to the MSDN online help for more details on macros: MSDN Macros List
The line provided to you would not do what you want. It's usually used to copy DLL files to a library folder used by some other projects or solution.
The solution you found to create a new build event is correct.
All you have left to do is write down the command that will actually copy the files.
It would look something like this:
XCOPY "$(SolutionDir)TestProject\Reports\*.*" "$(SolutionDir)TestSetup1\SSRS_Repor" /Q /E /I
/Q : Quiet | Don't display files being copied
/E : Recursive (copy subfolder structure and files)
/I : Consider that destination is a folder if it does not already exist (will create a new folder if required)

Related

How to create Explorer Shortcuts to specific TFS 2010 Source Control Paths

We are slowly moving projects from old file based storage (don't ask) to tfs. Our coders are still used to find the code in the file System.
Since we are talking about 100 Projects each with some sort of history, we have to move them carefully one by one. Resulting that we will have to live for some time with the already existing file structure mixed with the TFS managed files.
To make life easier for our coders, I would like to create a shortcut in the filesystem, for each project that we moved. So the developers can look up if the Project has already been moved, and if yes, go by double click to open up the TFS Source Control Explorer pointing directly to the correct Project.
Is this possible? Thanks for your Response.
I found a simple solution for my needs, which is based on a small batch script, that you'll have to click. It's not a shortcut so to say even though you can still create a shortcut of the batchfile.
Here's the script:
CALL "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86
REG ADD "HKCU\Software\Microsoft\VisualStudio\10.0\TeamFoundation\SourceControl\Explorer\<GUIDofTFS>" /v "SceMostRecentPath" /d "$/<PathToTfsProject>" /f
devenv /Command View.TfsSourceControlExplorer
In fact I combined 2 ideas found in separate sources:
1. Start VS with Source Control Explorer
2. Manipulate Registry to open Source Control Explorer in a specific path
With the command devenv /Command View.TfsSourceControlExplorer you can actually start VS and automatically open Source Control Explorer. Unfortunately there is no way to give a parameter to point it directly to a location you wish. But I noticed that VS2010 seems to persist the last used path and reopens to that place on restarts. A quick research resulted in the registry entry
HKCU\Software\Microsoft\VisualStudio\10.0\TeamFoundation\SourceControl\Explorer\058104ed-f0e2-4126-9ccc-0e37e19c4f91\SceMostRecentPath
By manipulating the value of SceMostRecentPath you can trick VS2010 to open Source Control Explorer with the path in there.
Keep in mind: You will need to replace 058104ed-f0e2-4126-9ccc-0e37e19c4f91 with the GUID of your TFS Installation.
Since we are all using VS 2010 but the installation paths differ, I implemented the path dynamically by making use of the VS100COMNTOOLS variable. First we set up the TFS command line environment:
CALL "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86`
Then we change the registry:
REG ADD "HKCU\Software\Microsoft\VisualStudio\10.0\TeamFoundation\SourceControl\Explorer\[PutYourTfsGUIDHere]" /v "SceMostRecentPath" /d "$/<YourTfsPath>" /f
Finally we do a simple call of devenv.exe with the source Explorer command:
devenv /Command View.TfsSourceControlExplorer
Until they're mapped to a local file path, I don't think this is possible. Though there might be an undocumented way to craft a vstfs:///VersionControl/LatestItemVersion/{itemid} link that might work, I haven't been able to craft one that does the trick.
You could create a powershell script that would check for the local mapping, otherwise ask them where they want to put it and setup the mapping, do a get-latest and go from there...
A bit of trickery with the tf commandline should get you pretty far.
tf workspaces /owner /collecion /computer to see whether there's a local workspace to the right team project.
tf workspace /new /collection to create one if needed
tf workfold /map to create a folder mapping, you could prompt them for a target location
tf get to fetch the latest sources.
Place the .ps1 file in the folder and when opened check for the workspace, if it's there open the local files in the mapped folder. if it isn't, go through the workspace mapping process by invoking the right commands.

Correct syntax to copy and overwrite a file in a post build event

What is the best way to copy and always overwrite a file to the target directory in a postbuild event in VS2010 running on windows 7.
At the moment I am using
robocopy $(SolutionDir) $(TargetDir) "Morning Report Template.xlsm"
I have also tried using Xcopy (with /Y) and even just plain copy. But I have not made it work properly yet. Either I get build errors like "The command "robocopy C:\Working\Projects\SAFEXQueryForm\ C:\Working\Projects\SAFEXQueryForm\SAFEXQueryForm\bin\Release\ "Morning Report Template.xlsm"" exited with code 1." Or else it just doesn't copy.
I need it to copy and overwrite everytime, without build errors and I would also prefer to change the file name which I know Robocopy can't do.
What am I doing wrong? And what is the best way to do this?
EDIT 2015/11/23
This answer provides a better method: https://stackoverflow.com/a/4596552/1011724. You can add the file to the project and then change the "Copy to Output Directory" property of the file.
Original answer
I still don't know what was wrong with my original syntax or how to convince VS that Robocopy's success exit code is 1 but this is what I have now and it seems to work, the only difference being that I changes the directory structure but that shouldn't matter(I'm afraid I don't know if I made other changes in the interim, this was quite a while ago)
xcopy "$(SolutionDir)\Additional Files\Morning Report Template.xlsm" "$(TargetDir)" /Y
and also I have the Run post build event drop down set to On successful build
You need to use a custom build action to achieve this. See http://msdn.microsoft.com/en-US/library/hefydhhy(v=vs.80).aspx for details, but here's what I tried.
I added the input file to the project. Then select the file and show the properties page (right click -> properties). On the General page make sure that the "Item Type" is "Custom Build Tool".
You may need to close and reopen the properties dialog, but having changed "Item Type" to "Custom Build Tool" there should be a "Custom Build Tool" page in the properties dialog. You can then fill in the command line. Make sure that you fill in the "Outputs" section with the name of the file our custom build step generates.
You should then find that the project builds and runs the custom build step whenever it finds that the input file has a date greater than the output file, which I believe is what you are trying to achieve.

Visual studio extension to redirect output files to specified folder

Usually, visual studio puts output files to bin/debug or bin/release.
When solution contains a large number of projects its not easy to modify each project output manually.
Also edits in csproj files no desirable, because some of them is shared between solutions..
My questions: Is anybody knows a tool, which can quickly configure output path ?
UPDATE: my problem solved by TFS Build
Presumably you have at least one project in each solution that is unique to that solution. In the Post-Build event of that, copy the contents of each project's output to the required location.
We often to this using a batch file. It's crude but effective. In our project that's unique to the solution we create a Release.bat file. This contains a number of file copies to copy all of the required components from the various output directories of the other projects. You can then just run the batch file in the post build event. We usually copy everything to a "Latest Release" fodler when the solution is built. If this becomes a proper release we will rename the Latest Release folder to the actual release number.
If you have multiple build configurations, or even just use the Debug and Release configurations, you can use an If statement in the Post-Build event to decide which batch file to run. So you could create a Debug.bat, Release.bat etc which do what you need. It can be tedious to set them up and get them working correctly at first, but they are very useful once fully implemented.
Customize your project using the msbuild properties which you can do if you follow these steps:
Go to the solution explorer and unload one project by right clicking on it and select Unload Project.
Then right click again on the unloaded project and select Edit Project. This will open the XML definition of your project, and you will have intellisense for the layout which will help you perform the next steps.
In the visual studio editor find the first PropertyGroup tag and add these lines near or at the end of the closing PropertyGroup tag:
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<BuildDirectory Condition="$(BuildDirectory) =='' or $(BuildDirectory) == '*Undefined*'">$(SolutionDir)\build\</BuildDirectory>
The above SolutionDir is defined in msbuild properties which you can obtain using this answer: msbuild script using solution information and also check out the well known msbuild properties here
The next step is to find the OutputPath tag for each configuration and edit it like this:
<OutputPath>$(BuildDirectory)\x86\AutomatedDebug\</OutputPath>
The example above assumes you have a configuration named AutomatedDebug with destination platform x86.
The output will be
x:\projects\whereever-your-solution-is\build\x86\AutomatedDebug\
Repeat for each project.
To unload more than one project, collapse all projects in the solution explorer and shift click or ctrl click to select all or some projects, then right click on the selected group to unload, unfortunately you cannot do this for editing, at least in visual studio 2010.
I am the first to admit that this is somewhat cumbersome to do for existing projects, but you could easily create a visual studio project template that has these settings changed so that new projects will use a more convenient default output directory.
You cannot edit the output directory directly in visual studio because the project properties editor escapes any $() enclosed text.
Also you could only modify the OutputPath using the name of a system environment variable enclosed in $(). This last option is to enable a global output directory.
If you build any single project modified in this way using msbuild directly in the commandline the output directory will be created one directory above from where you ran msbuild
..\build\x86\AutomatedDebug
If you are in a team, you should warn them not to edit the output directory directly by hand, as this action will overwrite any customization.
Hope this info is useful.
Greetings.

Possible to create Visual Studio project with Output Type of "none"?

I'm using Visual Studio 2008 and would like to create a sort of container project that holds a number of DLL's that must be installed with a solution. I want them to be in a separate project so that they can be easily attached to a solution as a group.
I created an empty project call TEST, added my DLL's to it with a Build Action of "Content", and set them to "Copy Always". That all works exactly as I want. The problem is that if I set the TEST project Output Type to "Console Application" or "Windows Application" that it won't build because there's no entry point. If I set the Output Type to "Class Library", it builds but I end up with an extra TEST.DLL file that I don't really want.
Is there anyway to sort of set the Output Type to "none"? I want the build actions to take place (so my DLL's get copied) but I don't want the dummy class assembly created. Any ideas?
Thanks!
Assumptions for the following step-by-step guide:
Let's assume that you have a solution with two projects:
Main: your main (start-up) project.
BundledDLLs: a library project which contains the .dlls that should end up in the main project's output directory.
Step-by-step guide:
The easiest way to achieve your goal inside Visual Studio is probably the following:
Add all .dlls to BundledDLLs and set their Copy to output directory to Copy if newer.
This is done in the Project Explorer and the Properties windows.
Configure BundledDLLs's output directory to be identical to Main's output directory.
This can be done in the Build tab of BundledDLL's Project Properties page. Enter something like the following in the Output Path textbox:
..\Main\bin\Debug
Set up BundledDLLs as a dependency of Main.
Do not add BundledDLLs as a project reference to Main, as you usually might; instead, use the Project Dependencies dialog to . This will tell the build tool that whenever Main is built, BundledDLLs needs to be built first.
Do this by right-clicking on the Main project node to open the context menu; select Project dependencies... from there. In the now opened dialog, first select Main from the drop-down list; then check BundledDLLs in the project list below. BundledDLLs is now registered as a dependency of Main.
P.S.: One disadvantage of not having an explicit assembly reference in Main is that some tooling might not recognise the dependency. For example, ClickOnce deployment might not work properly.
Add a post-build event to BundledDLLs that deletes the superfluous BundledDLLs.dll.
As you said, you don't want, and don't need, the dummy output generated when BundledDLLs is built. So add a post-build event that simply deletes this .dll once it's been created.
Open the Build events tab in BundledDLLs's Project Properties page, and enter something like the following in the post-build textbox:
DEL "$(TargetDir)\$(TargetName).*"
(In case you wondered: The reason why you didn't add this project as a project reference to Main earlier is because if you had done so, Main would be looking for BundledDLLs.dll, which it wouldn't be able to find since you don't actually want such a file to be generated.)
P.S.: One disadvantage of adding such a post-build step is that it might interfere with incremental builds. If your project keeps getting recompiled from scratch after this, you might be better off removing the post-build step and living with the extra BundledDLLs.dll in your solution's output directory.
Another option is to use a makefile project, which doesn't require you to build/link anything.
In your project properties (right click property in solution explorer and click "Properties"), under "Configuration Properties" and then under "General", choose "Makefile" from the "Configuration Type" drop-down menu. The build output will include the warning "The property 'NMakeBuildCommandLine' doesn't exist...Skipping" but the build will succeed without building any dll/exe/etc.
While other answers here may better address your specific need, specifying a makefile more directly answers the question title "Possible to create Visual Studio project with Output Type of none?" I hope this is useful for people who google something to that effect and land here.
Credit goes to Xeek in the #winapi freenode irc channel for sharing this tip.
Instead of putting them in a project, you can put the files in a Solution Folder. One of your projects can have a build action that does the copying, but since they won't be in a project, they won't try to "build".

How to add a SqlMetal build step in VS2008?

I've created a one-line batch file to run SqlMetal to regenerate a LINQ to SQL DataContext for my database; this works great.
Refresh_DataContext.bat:
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\sqlmetal.exe"
/server:.\sqlexpress /database:MyDatabaseName
/code:"%~dp0\DataContext.vb" /context:DataContext
/views /functions /sprocs /pluralize
So far I can run this by opening the enclosing folder in Explorer and running the batch file, and I've also added it to the Tools menu (Tools/External Tools.../Add).
Now I'd like to run this batch file whenever I build (in certain configurations). How do I do this?
What you seem to be looking for can be found under "Pre-build event command line" under your project's properties. Click the "Build Events" tab, and you'll have a little space to enter in a command line which does what you want.
Doh! Of course. Web Application projects have pre- and post- build events; Web Site projects don't.

Resources