I'm creating a command line program that uses a defined set of external files (.txts and the like) at runtime. I need it to have these in its working directory when run. Currently, I have them in a folder in the solutiondir with an xcopy into the projectdir as a pre-build event. What's the "accepted" way to set up a situation like this?
If its a .net project then you can mark those files are copy to output directory.
in c++ land (vcproj) you need to use the Pre/Post build step and copy them into the $(TargetDir)/$(ProjectDir)
Related
I have a C# Visual Studio solution with about 15 projects. When I build the solution I want all DLL and EXE files for each project to go to a common folder (called Deploy).
The way I was thinking about doing it was, for each project's Post-build Event Command Line section put the following commands:
IF NOT EXIST $(SolutionDir)Deploy (
'If directory does not exist, create it
MKDIR $(SolutionDir)Deploy
) ELSE (
'Delete directory to make sure it's "clean"
RMDIR /F /S /Q $(SolutionDir)Deploy
MKDIR $(SolutionDir)Deploy
)
'Copy executable and required DLLs to Deploy directory
COPY /Y $(TargetPath) $(SolutionDir)Deploy
COPY /Y $(TargetDir)*.dll $(SolutionDir)Deploy
The problem with doing it this way, however, is I have 15 projects and would have put this in each individual project's post build event section and also, every time I add a new project, I would have to remember to do the same for it.
I checked the solution file properties and did not see a way to set a solution-wide post build event to copy all the files so I did a few Google searches.
One page said to use a C++ Makefile project. I added this type of project to my solution and clicked on the project properties page and found that there is a section under Configuration Properties->NMake with the following:
Build Command Line
Rebuild All Command Line
Clean Command Line
Using the Makefile project's Command Line option poses a similar problem to above. Many different commands to copy each of my 15 project's output files such as:
COPY /Y $(SolutionDir)Project1\bin\$(ConfigurationName)\*.exe $(SolutionDir)Deploy
COPY /Y $(SolutionDir)Project2\bin\$(ConfigurationName)\*.exe $(SolutionDir)Deploy
...
COPY /Y $(SolutionDir)Project15\bin\$(ConfigurationName)\*.exe $(SolutionDir)Deploy
There is another apparent problem with doing it this way. As you can see I took advantage of the $(SolutionDir) and $(ConfigurationName) macros but I had to hard-code each project name.
I didn't see any macros like $(AllProjects), $(AllProjectDirs), etc.
Also, it appears that command line commands for Makefile projects are for building, not post-build events, so I gave up on this idea altogether.
I then tried using a Visual Studio Installer project. After adding the project to my solution I right-clicked the project and saw that there was an Add->Project Output... option. This brought up a dialog allowing me to add one of my other project's Primary Output. I repeated this for each of my other projects and rebuilt.
What resulted was an .MSI file in the output folder. I then opened installer project properties and changed the Package files option to As loose uncompressed files and rebuilt. The output folder now contained all my project's EXE and DLL files!
Most people would be satisfied at this point and move on but I am the kind of person who likes to find the best way to do things.
There was one thing I didn't like about using the installer project option, the fact that, besides copying the files from all my projects, it also created an MSI file (which I don't need) and I didn't see any option tell it not to create one.
Can anyone recommend a another/better way to accomplish my goal of copying all project output files to a single folder?
Thank you.
P.S. I was thinking I could just make a batch file to search and copy all the EXE and DLL files to the Deploy folder but I would have to run the batch file outside of the Visual Studio IDE and also hard-code the configuration folder (Debug or Deploy).
Can't you just change the Output Directory of the C++ projects? See How to: Change the Build Output Directory.
On the menu bar, choose Project, Properties.
Expand the Configuration Properties node, and choose General.
Change the Output Directory value to the new output directory.
If you want both options, you can also create multiple configurations for your VS projects and solutions, similar to the standard "Debug" and "Release" ones. Create a new configuration from one of the existing ones, then change the output directory and save. Now you can just switch the configuration at the solution level to build into another directory. See this link for detailed steps:
How to: Create and Edit Configurations
My Visual Studio 2013 Custom Build Tool step is failing because the directory in which the step is being executed is not the directory where the project file is (which was by default the case up until recently). I can patch it by adding a cd command to the start of the step to change to the project directory but I was wondering if anyone could tell me
how this directory path is set
how to change it.
The build always assumes the project directory as 'base' directory.
This gives msbuild a set location (Builds to bin\debug is a subfolder off 'Base', reference hint paths and a lot more besides).
I would just change the execute of your tool to be reference based (i.e ....\tool.exe or similar) or make use of the path environment variables ($(OutDir),$(TargetPath),$(ProjectPath),$(TargetDir) etc).
Another option that I make use of is to have a batch file called 'post.bat' that has the necessary steps to execute a custom tool. This is then placed in the project folder and added to the project as an artefact.
Without knowing exactly where your custom tool resides relative to the project (or solution) or what the 'working directory' requirements of the custom tool are I cannot suggest more.
I have resources.resx file in my C++/CLI project and want to create a build to to automatically build an accessor class to help access the resources when needed. I have searched a lot but haven't found a decent solution yet (using vs2010).
I can create the accessor class with this:
resgen /str:c++ resources.resx
This creates a resources.h file (which I want) and a resources.resources file (which I can delete). But I'd like to have the command being run whenever I change the resources.resx file and this gives me some headache as the file already has a build target, "Managed resource compiler", and while it runs resgen on that file, it includes 7 other resources files and doesn't have the /str switch.
The only automatic solution so far is to make a pre-build event command but that means recompiling the whole project every single time I make a build.
Any suggestions?
I solved the issue like this. In the Pre-Build Event of the project I inserted this:
resgen /str:c++,myApp,resources,resources.h.new resources.resx myApp.resources.resources
del myApp.resources.resources
fc /b resources.h resources.h.new > NUL:
if NOT "%ERRORLEVEL%"=="0" ( type resources.h.new > resources.h )
del resources.h.new
Basically, I create a new resources.h and compare it with the existing file. If there are any differences, I use type to copy the file in order to update the timestamp. This make the build engine only update resources.h when it is needed. Not pretty, but it gets the job done.
I have a few VS 2010 C# projects that are shared between several solutions. I would like these projects to build to the directory of the solutions they are open in. How do I do this?
I considered setting up different build configurations (Debug_Xsln, debug_Ysln, Release_Xsln...) but wasn't sure if there was a better way.
http://msdn.microsoft.com/en-us/library/42x5kfw4(v=VS.100).aspx
You can use a postbuild event with xcopy and the macro $(SolutionName) or $(SolutionDir) to copy the compiled files into the correct folder.
Go into properties for the project, build events tab, and in Post Build event command line enter something like this:
xcopy "$(ProjectDir)bin\$(ConfigurationName)\*.*" "$(SolutionDir)$(ProjectName)\bin\$(ConfigurationName)" /i /d /y
The benefit of this method is you can copy the build output of one project to multiple locations
OR
(as Ziplin discovered)
If you only have one location you want the build output to go, you can use the macros above to set the output path, like this:
$(SolutionDir)$(ProjectName)\bin\$(ConfigurationName)
just go to the project properties on the build tab and set your macroed location as the output path
On a successful build, I wish to copy the contents of the output directory to a different location under the same "base" folder. This parent folder is a relative part and can vary based on Source Control settings.
I have listed a few of the Macro values available to me ...
$(SolutionDir) = D:\GlobalDir\Version\AppName\Solution1\build
$(ProjectDir) = D:\GlobalDir\Version\AppName\Solution1\Version\ProjectA\
I want to copy the Output Dir contents to the following folder :
D:\GlobalDir\Version\AppName\Solution2\Project\Dependency
The base location "D:\GlobalDir\Version\AppName" needs to be fetched from one of the above macros. However, none of the macro values list only the parent location.
How do I extract only the base location for the post build copy command ?
Here is what you want to put in the project's Post-build event command line:
copy /Y "$(TargetDir)$(ProjectName).dll" "$(SolutionDir)lib\$(ProjectName).dll"
EDIT: Or if your target name is different than the Project Name.
copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)lib\$(TargetName).dll"
If none of the TargetDir or other macros point to the right place, use the ".." directory to go backwards up the folder hierarchy.
ie. Use $(SolutionDir)\..\.. to get your base directory.
For list of all macros, see here:
http://msdn.microsoft.com/en-us/library/c02as0cs.aspx
You could try:
$(SolutionDir)..\..\
I think this is related, but I had a problem when building directly using msbuild command line (from a batch file) vs building from within VS.
Using something like the following:
<PostBuildEvent>
MOVE /Y "$(TargetDir)something.file1" "$(ProjectDir)something.file1"
start XCOPY /Y /R "$(SolutionDir)SomeConsoleApp\bin\$(ConfigurationName)\*" "$(ProjectDir)App_Data\Consoles\SomeConsoleApp\"
</PostBuildEvent>
(note: start XCOPY rather than XCOPY used to get around a permissions issue which prevented copying)
The macro $(SolutionDir) evaluated to ..\ when executing msbuild from a batchfile, which resulted in the XCOPY command failing. It otherwise worked fine when built from within Visual Studio. Confirmed using /verbosity:diagnostic to see the evaluated output.
Using the macro $(ProjectDir)..\ instead, which amounts to the same thing, worked fine and retained the full path in both build scenarios.
Would it not make sense to use msbuild directly? If you are doing this with every build, then you can add a msbuild task at the end? If you would just like to see if you can’t find another macro value that is not showed on the Visual Studio IDE, you could switch on the msbuild options to diagnostic and that will show you all of the variables that you could use, as well as their current value.
To switch this on in visual studio, go to Tools/Options then scroll down the tree view to the section called Projects and Solutions, expand that and click on Build and Run, at the right their is a drop down that specify the build output verbosity, setting that to diagnostic, will show you what other macro values you could use.
Because I don’t quite know to what level you would like to go, and how complex you want your build to be, this might give you some idea. I have recently been doing build scripts, that even execute SQL code as part of the build. If you would like some more help or even some sample build scripts, let me know, but if it is just a small process you want to run at the end of the build, the perhaps going the full msbuild script is a bit of over kill.
Hope it helps
Rihan
I solved my problem by reinstall VS and then download .Net Core (3.x and 2.x) sdk packages
Here is my post build script
Creates the custom path for my own. Including library and version.
Copies the .dll (target file)
Copies the *.md files.
script:
md c:\_References\$(ProjectName)\$(AssemblyVersion)
xcopy $(ProjectDir)$(OutDir)$(TargetFileName) c:\_References\$(ProjectName)\$(AssemblyVersion) /y
xcopy $(ProjectDir)*.md c:\_References\$(ProjectName)\$(AssemblyVersion) /y