Visual Studio macro (-D) from command output - visual-studio

I'm trying to get the output of git describe into my build as a preprocessor define, to use in versioning modules. Unfortunately, it's being a bit contrary (not sure where the issue is).
I had a pre-build event like:
for /f "delims=" %a in ('git describe') do set GITID=%a
which works from the command prompt, but returned code 255 in the build (which caused an error). So I changed it to:
git describe > buildprops_gitid.txt
set /p GITID= < buildprops_gitid.txt
which again, works in command prompt (and doesn't error during build). The file is created with the correct value.
In the preprocessor settings, I then have:
BUILD_TARGETFILE=$(TargetFileName)
BUILD_GITID=$(GITID)
The former works fine, putting the target filename into the file as expected. The latter doesn't work, instead putting an empty string. I suspect this is related to the env var being lost somewhere along the way.
Is there a way to get the output of CLI programs and use that as variables ($(var)) within Visual Studio?

the workaround i found for this was to generate an include file in a pre-build event.
something like the following version.bat script:
#echo off
FOR /F "tokens=*" %%i IN ('call git describe --always') DO echo #define VCSVERSION "%%i" > vcsversion.h
and then add #include "vcsversion.h" in the code.
this is basically the solution i suggested here

Related

AWS CLI file extension association warning on Windows

Using aws cli with python 3 on Windows, always getting a warning, but the program runs well after this message.
For example:
>>> aws --version --debug
Не найдено сопоставление для расширения имени файла .py.
aws-cli/1.15.83 Python/3.6.0 Windows/7 botocore/1.10.82
(vaguely -' Cannot find association for filename extension .py')
Any idea which part of aws scripts issues this warning and how to fix it? At what part does aws use Windows call?
As #Evgeny describes in Windows after install AWS CLI the file aws.cmd has this line that calls the command assoc and produces the warning:
for /f "tokens=2 delims==" %%i in ('assoc .py') do (
The command assoc .py shows if there is an association to python files in Windows. If you don't have a python executable associated with *.py files in your main command line (no in environments of Anaconda).
You can test that opening a command line window and try to run a simple script in a folder this way:
>test.py
If you get an error and you like to remove the warning you have to make a new association for python files, with one of this options.
By command line (as administrator)
assoc .py=py_auto_file
ftype py_auto_file="C:\Anaconda3\python.exe" "%1" %*
By GUI changing Defaults apps
Right clic any file with extension *.py and select properties, and select a program that manage this file, for example in "C:\Anaconda3\python.exe" or change the default app.
In Windows 10 you can follow this sequence "Start menu, select Settings > Apps > Default apps"
you have to meet the dependency with: https://www.python.org/downloads/
so that windows could have something to register file-type .py with.
or you'd have to register .py to open with python3.exe (or alike).
I managed to get feedback on a issue on Github. Basically, there is a one line change that can supress the warning.
In aws.cmd instead of:
for /f "tokens=2 delims==" %%i in ('assoc .py') do (
use:
for /f "tokens=2 delims==" %%i in ('assoc .py 2^> nul') do (
This diverts warnings to null. There is also a
pull request
with this suggested change, but it was not mergerged to code unfortunately.
Anyone experiencing this problem can change a local file aws.cmd as <your python directory>/Scripts folder.

Variable not being set in Visual Studio Post-build event command line

I have the following script in a Windows batch file that fetches the version of a DLL file and renames an existing file by inserting the version in its file name. This works fine when I put it in a .bat file and run it in Windows. The resultant file name is GCSv1.1.0.7316.zip.
SET WMICommand="WMIC DATAFILE WHERE name='E:\\Projects\\GCS\\bin\\Debug\\Client.dll' get Version /value"
for /f "tokens=2 delims==" %%x in ('%WMICommand%') do (set vers=%%x)
echo %vers%
echo GCS_v%vers%.zip
ren E:\Projects\GCS\InstallerTemplateProject\DeployFolder\GCS_Package.zip GCS_v%vers%.zip
I need to take this same script and put it in a Post-build event command line in Visual Studio to rename the generated file as a last step in the build process. Which is as follows:
SET WMICommand="WMIC DATAFILE WHERE name='$(SolutionDir)GCS\bin\debug\\Client.dll' get Version /value"
for /f "tokens=2 delims==" %%x in ("%WMICommand%") do (set vers=%%x)
ren "$(SolutionDir)GCS\InstallerTemplateProject\DeployFolder\GCS_Package.zip" GCS_v%vers%.zip
But for some reason, the renaming is not happening properly because it is being renamed to GCS_v.zip.
Clearly the %vers% variable is not being set when it is in the Post-build event command line. Why does it work when executing it in a .bat file on Windows, but not when executing in a post-build? What should I do differently to the variable here? The goal is to get the second batch working in visual Studio. The first batch I wrote it just to test it out.
Each of the batchfiles is invoked independently and instantiates its own environment, so the second batch does not acquire the changes made the the first's variables.
Two obvious solutions
Use setx to set the variable into the second batch (with the downside that it will also be included in the environment of any other batch started following the setx) - probably then use setx to clear the variable from the second batch.
Write the variable to a file and read the file back into the second batch.
Ah - my misinterpretation, caused by skimming. I'd assumed the first batch was a pre-build and the second a post-build.
The problem appears to be that VS is not substituting the actual (and no doubt per-project) value of Solutiondir into the batch - which it logically cannot do because there's no guarantee that $(whatever) isn't a string with another interpretation within a random batchfile.
I'd suggest that you try
set>afilename.txt
as the first command within the post-build batch, which will create a file containing the value of most of the environment variables. It may very well be that a variable named something like solutiondir is installed in the environment for the post-build batch - but I can't guarantee that...

cmd script printing out but not executing

Hi all I'm currently writing up a small bash script to automate some stuff for me but I've hit a bit of a snag My current file looks like the following:
for /f "delims=" %%f in ('dir /b "D:/*"') do C:\MediaInfo\MediaInfo.exe "--Inform=Video;%Width% "D:\%%f"
pause > nul
The pause thing is just there so I can see the output. While the part after the |do| command works fine if I manually type it in (as in I know my syntax for that is correct) however when running the batch script instead of actually executing the above commands it simply prints them out to the command console. Am I missing some syntax here or similar. Also as a side note I would like to push the resulting value of that query into an int so I can use it, do you know if this is possible in bash or should I look at trying to use a higher level language? Thanks!
I have no notion of the intricacies of mediainfo - but it would be unusual if it was to accept unbalanced quotes in its command line as you have posted. I'd suggest an extra after %Width%

batch file to merge .js files from subfolders into one combined file

I'm struggling to get this to work. Plenty of examples on the web, but they all do something just slightly different to what I'm aiming to do, and every time I think I can solve it, I get hit by an error that means nothing to me.
After giving up on the JSLint.VS plugin, I'm attempting to create a batch file that I can call from a Visual Studio build event, or perhaps from cruise control, which will generate JSLint warnings for a project. The final goal is to get a combined js file that I can pass to jslint, using:
cscript jslint.js < tmp.js
which would validate that my scripts are ready to be combined into one file for use in a js minifier, or output a bunch of errors using standard output.
but the js files that would make up tmp.js are likely to be in multiple subfolders in the project, e.g:
D:\_projects\trunk\web\projectname\js\somefile.debug.js
D:\_projects\trunk\web\projectname\js\jquery\plugins\jquery.plugin.js
The ideal solution would be to be able to call a batch file along the lines of:
jslint.bat %ProjectPath%
and this would then combine all the js files within the project into one temp js file. This way I would have flexibility in which project was being passed to the batch file.
I've been trying to make this work with copy, xcopy, type, and echo, and using a for do loop, with dir /s etc, to make it do what I want, but whatever I try I get an error.
You could create a batch file with the following contents:
#echo off
pushd "%~1"
for /r %%x in (*.js) do (
type "%%~x"
)
popd
and then run it via:
jslint.bat PATH > tmp.js
If you don't want to use redirection, you can try:
#echo off
pushd "%~1"
echo.>tmp.js
for /r %%x in (*.js) do (
copy tmp.js + "%%~x" tmp.js > NUL
)
popd
note that for simplicity, I haven't bothered doing any error-checking (e.g. checking whether an argument is supplied (although if one isn't, it'll just use the current directory), testing that tmp.js doesn't already exist, etc.).
A great place for tips on batch files is DosTips.com
Have a look at http://nefariousdesigns.co.uk/archive/2010/02/website-builds-using-make/
The post is written for Linux world but still you might be able to salvage something out of it.

Setting a variable from an executable

I am running an executable in a batch file with two parameters;
cmd /k ""executable" "param1" "param2""
This returns a string that I want to launch. I can't figure out how to set this return in a variable and subsequently launch it in IE.
Any ideas?
If the returned string contains a single line you may use FOR /F to set the value of an environment variable. For example:
s1.cmd
echo this is a one line string
s2.cmd
#SETLOCAL
#ECHO OFF
for /f "tokens=*" %%a in ('cmd /c s1.cmd') do set MY_VAR=%%a
echo got: %MY_VAR%
ENDLOCAL
Result
C:\> s2.cmd
got: this is a one line string
C:\>
You can use the following syntax to capture the output of your executable into a variable:
FOR /F "tokens=*" %%i in ('%~dp0YOUR_APP.exe') do SET TOOLOUTPUT=%%i
Source
then you can pass the value on to IE like so:
START "YOUR_WINDOW_NAME" /MAX /D"C:\Program Files\Internet Explorer\" iexplore %TOOLOUTPUT%
I take it that the application code that determines the url is too complicated to be reproduced in a batch file directly, or the source to the executable has been lost. If not I personally would prefer to have the logic visible in the batch file itself.
start %1 %2
Edit: Romulo A. Ceccon posted a much better solution which doesn't involve any file system access and dirty tricks. Left this here for reference (it works with command.com as well if you need 9x compatibility), but please prefer Romulo's solution.
Go through an environment variable you set by using an intermediate helper script you dynamically generate from a template. You will need write permissions somewhere, otherwise it cannot be done (the Windows command shell language is very, very limited.)
Let's call your helper script template helper.tpl with the following contents:
set INTERMEDVAR=
Make sure that helper.tpl has only a single line (no trailing CRLF!) and make sure you don't have any spaces after the equals sign there.
Now, in your main script, capture the output from your command into a temporary file (let's call it my_output_file.tmp):
cmd /k ""executable" "param1" "param2"" > my_output_file.tmp
Then copy the contents of the helper template and the output together into your helper script, let's call it my_helper_script.cmd:
copy /b helper.tpl + my_output_file.tmp my_helper_script.cmd
Then evaluate the helper script in the current context:
call my_helper_script.cmd
Now the INTERMEDVAR variable is set to the first line of the output from "executable" (if it outputs more than one line, you're on your own...) You can now invoke IE:
start iexplore.exe "%INTERMEDVAR%"
And don't forget to clean up the created files:
del /q /f my_output_file.tmp my_helper_script.cmd
This will obviously not work when invoked multiple times in parallel - you'll have to parametrize the temporary file and helper script names using the current cmd.exe's PID (for example) so that they won't overwrite each other's output, but the principle is the same.
However, if you can get a real shell, use that. cmd.exe is extremely cumbersome.

Resources