VS2010: How to use Environment Variables in Post-Build - visual-studio-2010

On my PC I have created a system environment variable called 3DSMaxInstallDirectory
At the command line, if I give
echo %3DSMaxInstallDirectory%Plugins\
I get
D:\Program Files\Autodesk\3ds Max 2011\Plugins\
In Visual Studio I enter into the Post-Build section
copy "$(TargetDir)$(TargetName).*" "$(3DSMaxInstallDirectory)Plugins\"
However on build I get
Error 4 The command "copy "C:\Users\Sebastian\Documents\Visual Studio 2010\Projects\MaxBridge\MaxBridgeImporterPlugin\bin\Debug\MaxBridgePlugin.*" "Plugins\"
" exited with code 1. MaxBridgeImporterPlugin
The results on Google are a confusing mix of suggestions that Visual Studio doesn't support EVs, Visual Studio does support EVs, Visual Studio needs %..% and Visual Studio needs $(..) - and none of which seem to work on my computer.
What is the correct way to use my environment variable in Visual Studio?
(Yes, the directory exists, and the reason I don't want to set the path explicitly is I am preparing to share this project, and every step someone else has to take after downloading and before building is another barrier.)

This works for me in the Post-Build setting of the 'Build Events' of the project.
echo %CodeContractsInstallDir%
echo %DXSDK_DIR%
echo "%ONLYME%"
ONLYME is a environment var in the User variables of my profile.
The others are System wide vars.
ONLYME stays empty if I start VS2010 as administrator, the systemvars still have values as expected.
I'm on V2010 SP1

The '%' character is reserved by MSBuild, so you have to replace it by the %25 hexadecimal escape sequence as documented in MSDN.
copy "$(TargetDir)$(TargetName).*" "%253DSMaxInstallDirectory%25\Plugins" should actually work. However: Visual Studio's commandline editor displays it correctly, but MSBuild then interprets %253 wrongly. I can't tell whether it's a bug or a feature but you must not start your environment variable's name with a digit.

Visual studio doesn't properly encode/decode "special" characters in the XML config file. I'm able to get it to work as expected by manually escaping the command as a URL (http://www.w3schools.com/tags/ref_urlencode.asp).
ECHO %CD%
Results in an output log:
Target "PreBuildEvent" in file "blahblahblah"
Task "Exec"
Command:
ECHO %CD%
C:\blah\blah\blah\Debug
Done executing task "Exec".
However, using URL escapes in the project proerties dialog appears to work:
ECHO %25CD%25

According to this MS Link, the syntax is now the same as using a project file variable, which means you don't have to worry about escaping the % character anymore. For example, if BIN_PATH is an environment variable and the following line is added to the post build step:
echo $(BIN_PATH)
This line will then display the value of BIN_PATH to the output window after the build.
But, be aware that the environment variable must be defined before VS is started. I lost about 45 minutes when I first tried this before it dawned on me that maybe the reason why it was not working was because VS loads the environment variables on startup. So, I exited VS, restarted, and it worked like a charm.
You still might need the old % character syntax if your environment variable is the same as a VS project variable, since "the property in the project file overrides the value of the environment variable."

If you want to use an environment variable that is defined after VS is started, the rules differ for .vcxproj and .csproj projects. In .vcxproj projects, writing %MY_ENV_VAR% in the Project Properties won't work - you need to use the escape syntax %25MY_ENV_VAR%25. But a .csproj project does accept %MY_ENV_VAR%; using the escape syntax causes the escape sequence to be mangled, giving %2525MY_ENV_VAR%2525. (This in VS2017 at least.)

Related

debugging with visual studio using redirected standard input

I am debugging c++ console application with Visual studio. I exhausted of inserting the same input every time I debug this program. I would like to use the same input more times.
I do this without debugging in command line with command: Program.exe < 1.in
Is it possible to use debugging with standard input redirected from file???
I already tried looking in to procejt properties. I tried setting Command to $(TargetPath) < 1.in instead of $(TargetPath).
I also tried setting Command Arguments to < 1.in. Niether of these method worked.
I am using Visual Studio 2012. But this is probably same in all versions of studio.
This is a supported debugging scenario. You do have to make sure that the debugger can find the file. Leave the Command setting at $(TargetPath). A possible value for the Command Arguments setting is:
< "$(ProjectDir)test.txt"
if the input file "test.txt" is located in the project directory. Or type the full path of the file to be sure. The MSDN article that describes this feature is available here.
I just create a file called stdin.txt in the project
1) set the Build Action to Content
2) Copy to Ouput Directory: Copy if newer
Then when you build stdin.txt is copied to the same folder as the executable.
Then in project properties debug|command line arguements enter the following
< stdin.txt
There is no need to use a path macro
If you don't want to mess with the the path you can add a new file with a right click on the source files folder in the solution explorer and then paste to it the content from the wanted file. And then change the command argument to the new file name.

Project path or other macro in command-line parameters for console project in VS2010

The debug tab of the project properties for a console application in VS2010 allows me to set command-line parameters to pass to the project whilst debugging.
I would like to set a parameter which is a path and the path is specific to each developer/machine, as it is a path which resides in the solution folder and each environment is different.
For pre- and post-build events, I can use macros such as $(ProjectDir), but I can't find a way to do this for command-line parameters - is there a way? A hack is fine, as long as it's not too awful!
Thanks
I haven't found a way to use $(ProjectDir) in the command line arguments, but you can access files contained within the project by:
Tell Visual Studio to copy specific files to the output directory by changing their "Copy to Output Directory" property.
Change your command line arguments from $(ProjectDir)/FileNeededDuringRuntime to FileNeededDuringRuntime.
This is more of a hack since it probably doesn't cover all the cases of using the variable, but it may get you by if you're just referencing a few files.
Macros can be used in command line arguments for C++ projects, see:
How to pass solution folder as parameter in command line arguments (for debug)?
You could have an empty C++ project "Set as StartUp Project" and change its "Configuration Properties -> Debugging -> Command" from "$(TargetPath)" (default for new projects) to "$(ProjectDir)..\OtherProjectRelativeDebugFolder\OtherProjectsOutputFileName.exe".
Since OtherProjectRelativeDebugFolder and OtherProjectsOutputFileName are relative and thus location independent you should be fine with that.
You said:
A hack is fine, as long as it's not too awful!
Is an empty project that produces an empty dll (unless you find a way to stop it, e.g. delete on post-build) too awful?
BTW. Environment variables aren't resolved in "Debug -> command line arguments" for C# either. I'll be experimenting on setting an environment variable, passing its name (because it isn't resolved) and reading it in the program. Passing the name is intended to show where the environment variable comes from, i.e. project settings.
Edit:
I hoped to find a way to set the environment variable to the value of a macro, e.g. in a build event. A simple shell "set" command is not persistent, so it didn't work out. Instead I was able to use a relative path as working folder to get things work for me. I also found a workaround that uses a file for persistent storage:
VS2010 - Project Macro Variables in Start Options Command Line Arguments

Finding build output in Visual Studio 6 (visual basic)

I realize this is going to be an exotic question, but I just can't find the answer.
I'm trying to fix up and enhance an old visual basic-based application.
My problem is: where is the output directory with the compiled binaries?
Thanks.
If some clarification is needed, please ask.
In the .VBP, if there is a line specifying the path like this
Path32="C:\"
Then the resulting EXE will be built at that location. Otherwise, it will be built in the same directory as the .VBP file. The path can be relational as well and may not be a fully qualified path.
I think you want the /outdir switch. This overrides the Path32 setting in the Project file.
VB6[.EXE] [[{/run | /r}] | [/runexit] | [{/make | /m}] projectname]
[/out filename] [/outdir path] [/d const=value{[:constN=valueN]}]
[/mdi | /sdi] [{/cmd argument | /c argument}]
Options:
/run or /r projectname Tells Visual Basic to compile projectname and run it,
using the arguments stored in the Command Line
Arguments field of the Make tab of the Project
Properties dialog box.
/runexit projectname Tells Visual Basic to compile projectname and run it.
Visual Basic will exit when the project returns to
design mode.
/make or /m projectname Tells Visual Basic to compile projectname and make an
executable file from it, using the existing settings
stored in the project file.
/out filename Specifies a file to receive errors when you build using
/m or /runexit. If you do not use /out, command line
bild errors are displayed in a message box.
/outdir path Specifies a directory path to place all output files in
when using /make. This path must already exist.
/d or /D const=value... Tells Visual Basic which values to use for conditional
compilation constants when making an .EXE or ActiveX
component with the /make switch. Separate multiple
constants with colons.
/cmd or /c argument Specifies a command string to be passed to the Command$
function. When used, it must be the last switch on the
command line.
/mdi or /sdi Changes the Visual Basic environment to either Single
Document Interface (SDI) or Multiple Document Interface
(MDI) mode. Visual Basic remains in this mode until
you change it.
/? Displays a list of valid command line switches.
You may use a group name in place of projectname in any of the above switches.
Works fine here.
There is no equivalent 'bin/lib' output directory for VB6. When you compile a VB6 project, the default is to compile to the same folder as the project (vbp file). It is also possible to compile to any other folder available to the user.

How to pass the assembly name as a command-line argument when debugging

I have an NUnit test assembly (a .NET DLL). When I click Run in Visual Studio I want it to launch NUnit and run the tests in this assembly. I can do all of that.
Instead of specifying the full assembly name and path in the command line arguments, does Visual Studio support some sort of macro that expands into that for the Command Line Arguments box? Most other development tools I have used support this, but I cannot find anything in the documentation about this.
I was expecting something like: %assembly_full_path%
The reason I want to do this is so if the assembly name or build location changes, then I don't have to update the command line arguments as well.
This doesn't work as far as I can tell. Macros in the Command Line arguments box do not get expanded. Not even environment variables. Bummer.
A workaround is to create a custom tool. Tools + External Tools, Add. Title = Run tests, Command = nunit.exe, Arguments = $(TargetPath), Initial Directory = $(TargetDir). Tweak as needed. You could assign a keystroke to this new tool command, even F5.
Using VS2005, the only item I need to provide in the Command Line Arguments is the name of the dll. I suspect VS sets the default working directory to the project's output directory, as I've never specified the path and yet the tests always load correctly.

Calling batch files with make and making changes persistent

I'm programming with Visual C++ Express on the command line using makefiles (GNU Make).
For this to work, I have to call the Visual Studio batch file vsvars32.bat to set up the environment. This has to be done everytime I open a new cmd.exe, before using make.
When I try to call the batch file from my makefile, it obviously executes the batch file as
an own process, because the environment is the same afterwards.
So my question: is there a way to execute scripts in cmd.exe like the built-in source command of the Linux/Unix bash? Apart from installing bash on Windows, of course.
Edit after posting my own answer:
The above question is not quite right, it should be like this:
Is it possible to call an environment-changing batch file from within a makefile, so that the changed environment persists for the other programs called in the makefile?
The answer to the original question is yes: you can use the built-in call command of cmd.exe. But since call is a built-in command and not a real program, it doesn't work in a makefile, only if you call a batch file from another batch file.
Answer compiled from the previous answers:
I made a batch file called make.bat which contains the following:
call "%VS90COMNTOOLS%vsvars32.bat"
call make.exe %*
This does the job.
But calling an environment-changing batch file from within a makefile, so that the changed environment persists for the other programs called in the makefile, seems to be impossible.
Edit: After overflowing my PATH variable by repeatedly calling vsvars32.bat, I made the following changes:
if not "%VISUALCVARS%" == "TRUE" (
set VISUALCVARS=TRUE
call "%VS90COMNTOOLS%vsvars32.bat"
)
call make.exe %*
use 'Call':
#echo off
pushd.
call "C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars3235.bat"
msbuild LinqSupportClassesSDKBuild.csproj /t:rebuild /p:Configuration=Release /nologo /v:q /clp:ErrorsOnly;
popd
this is the cmd file we use to build our linq provider.
At least in my install of Visual Studio (albeit somewhat ancient VS .NET 2003), one of the links in the VS start menu group is to open a cmd.exe instance with the environment already setup. You might find these helpful:
How to Add Visual Studio Command Prompt (VSCP) to your IDE as a tool?
Running the command prompt from visual studio tools menu
Shortcut: Launch Visual Studio Command Prompt from Visual Studio
They are more geared toward launching the command prompt from the IDE, but they do include information on launching it with the appropriate environment as well which you may find helpful for your purposes.
How do you launch your console? If you are just launching 'cmd' then instead, create a shortcut that executes (%comspec% resolves to c:\windows\cmd.exe or whatever is relevent on your system)
%comspec% /k ""C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat"" x86
Obviously, change the path to point to the proper installation folder.
More generally, as the above poster pointed out, if a .cmd file needs to process another .cmd file rather than launch it as a seperate process, use the 'call' batch command.
Wrap GNU make in a script (mmake.bat). Put the script in the path somewhere.
The script itself should run the vsvars32.bat and then make, like this
vsvars32.bat
make %*
As far as I remember, invoking a script from another script like this is done within the same shell (similar to Bash "." command).
I have found three solutions to this problem:
1) If the environment variables being set by the batch file are static (that is, they are always the same values), set those values for your entire user profile. Right-click on My Computer, click Properties-->Advanced-->Environment Variables. Add the variables from the batch file to the User Variables or System Variables section (User variables are only visible by you, System variables are visible by all users of that computer).
2) Write a wrapper batch file that calls the environment setup script then calls the Makefile.
3) Instead of using the SET command to set environment variables in the batch file, use the SETX command (requires the Windows Resource Kit). SETX is similar to SET, except it makes its changes to the master environment in the registry and will take effect in all command prompts launched in the future (but not the current one).

Resources