How to do variable interpolation in a windows batch file using the Qt "system" command? - windows

When developing an application with Qt the project file has the file extension "pro". In this pro file one can perform platform-dependent commands by using the "system" directive. Example:
RESPONSE = $$system( cmd /c dir)
I want to use variable interpolation. Windows uses for this the % character. When I create a batch file, called utc.bat that writes its output to the file utc.txt, having as content:
#echo off
REM for /f %%x in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%x
echo %Year%-
and run it from a terminal the content of utc.txt is:
2017-
If I run the same command from within the pro file:
system(utc.bat > utc.txt)
the content of utc.txt is
-
Apparently the variable interpolation %Year% does not work. I hope somebody knows the answer of how to get it working.

Related

Run Autocad exe and load script file error

This is My first post in here
I need a help for your side I have made a batch file for run autocad exe and load a script file but give error when I run the batch file
#echo off
set KEY_NAME=HKCU\Software\Laxman Enterprises\Xpresslisp Tools
set VALUE_NAME=installpath
set FN=loadload
set FE=scr
FOR /F "tokens=2*" %%A IN ('REG.exe query "%KEY_NAME%" /v "%VALUE_NAME%"') DO (set pInstallDir=%%B)
set approot=%pInstallDir:~0,-1%
echo %approot%\%FN%.%FE%
"C:\Program Files (x86)\AutoCAD 2002\acad.exe" /b %approot%\%FN%.%FE%
pause
Error: while running batch file autocad opens and in commandline the script file not loading "Xpresslisp.scr": Can't find file."
and bellow one is working
script file loading without getting error
#echo off
set path=%USERPROFILE%
set fol=Documents
set NAME=1
set SUFFIX=scr
"C:\Program Files (x86)\AutoCAD 2002\acad.exe" /b %path%\%fol%\%NAME%.%SUFFIX%
pause
Regarding your second question in the comments...
Bellow command will create the text file and write the first line to it e.g. "some text" like in the command below.
Echo some text > full_path_to_txt_file
Command below will append new text to same file.
Echo some text >> full_path_to_txt_file
'>' char creates file and writes firs line
'>>' char append text
check that %path%\%fol%\%NAME%.%SUFFIX% returns the Full Path to the "Xpresslisp.scr" file !
if it does, inspect the Full Path and see if it contains any white spaces.
if it does, enclose the %path%\%fol%\%NAME%.%SUFFIX% with apostrophes
"%path%\%fol%\%NAME%.%SUFFIX%"
It may be something as simple as blindly removing the last character of the installpath without knowing for sure what it is, (doublequote or backslash?).
As there is unlikely to be multiple copies of any filename in the Xpresslisp Tools tree, I would suggest something like this:
#Echo Off
Set "KEY_NAME=HKCU\Software\Laxman Enterprises\Xpresslisp Tools"
Set "VALUE_NAME=installpath"
Set "FN=loadload"
Set "FE=scr"
(Echo=FILEDIA 0
Echo=(LOAD "C:\\loadmyfile.lsp"^)
Echo=FILEDIA 1)>%FN%.%FE%
For /F "Tokens=2*" %%A In ('Reg Query "%KEY_NAME%" /v "%VALUE_NAME%"') Do (
For /F "Delims=" %%C In ('Dir/B/S/A-D "%%~B"\"%FN%.%FE%" 2^>Nul') Do (
Start "" "%ProgramFiles(x86)%\AutoCAD 2002\acad.exe" /b "%%~C"))
This doesn't care if there is a trailing backslash or not and will only run the AutoCAD command if the file is there.

How to find where windows is installed using batch file

Is there a way to create a simpel batchfile that finds the drive where windows is installed?
Use %SystemDrive% from the command prompt or in a batch file.
echo %SystemDrive%
or
d:>%SystemDrive%
c:>
Ken White has the "normal" way to get the system drive via %SystemDrive%. But that variable can easily be corrupted by setting your own value.
An alternative that should "always" work for any Win version later than XP is to use:
for %%A in ("%__APPDIR__%") do echo %%~dA
Of course you can set your own InstallDrive variable to the value of %%~dA.
The %__APPDIR__% variable is one of two special dynamic "variables" that always report the correct value, even if a user tries to override the value by explicitly defining their own variable of that name. However, the value can be overridden on XP. See Why can't I access a variable named __CD__ on Windows 7? for more info about dynamic variables %__CD__% and %__APPDIR__%.
Just in case 'finds the drive' doesn't just mean the drive letter:
#Echo Off
For /F "Tokens=2,5,6 Delims=\|" %%I In ('WMIC OS Get Name') Do Echo=%%I %%J %%K
Timeout -1
…and for no real reason:
#Echo Off
For /F "Tokens=2,5,6 Delims=\|" %%I In ('WMIC OS Get Name') Do (
Set _di=%%I %%K %%J )
Set/A _dn=%_di:~-1%+1
For /F "UseBackQ Tokens=2 Delims==" %%L In (`WMIC DiskDrive Where^
"DeviceID Like '%%PHYSICALDRIVE%_dn%'" Get Model /Value`) Do Echo=%_di% %%L
Timeout -1
Type cd %windir% in a dos command prompt, and then press ENTER.
Note the current folder. This is the folder in which Windows is installed.
You actually do not need a batch file for that. Just hold the windows key and press R to open up a small window in which you type %windir% and hit Enter.
A Windows Explorer window will pop up showing the directory of the Windows installation. You can the click onto the bar, where the directory is shown (like the URL-bar of the browser) to get the direct path including any parent folders and the drive letter.

Running a non bat extension file as a batch file

Let's say I have a text file, it contains batch commands. How can I run that text file as a batch file from within one, without renaming it. I want too keep a portable aspect too it, so no registry keys or such.
The reason for no renaming is too prevent leftover unrenamed files upon unexpected closure.
The simplest way is this:
cmd < file.txt
As in the previous answers, there are several commands that will not work in this file, like GOTO, SETLOCAL and others. However, multiline nested if and for commands do work as long as for replaceable parameters use just one percent (like in the command-line).
Although this method alaways show in the screen the executed commands (#echo off not works here), you may redirect the output to NUL and in the "Batch" file redirect the desired output to CON. For example, this is test.txt:
#echo off
echo Hello World! > CON
(for /L %a in (1,1,10) do (
echo Turn: %a
if %a equ 4 echo TURN NUMBER FOUR!
)) > CON
Output example:
C:\> cmd < test.txt > NUL
Hello World!
Turn: 1
Turn: 2
Turn: 3
Turn: 4
TURN NUMBER FOUR!
Turn: 5
Turn: 6
Turn: 7
Turn: 8
Turn: 9
Turn: 10
type some.txt>temp.bat
call temp.bat
del /q /f temp.bat
Is creating a temp file cheating?It's not mentioned as restriction in the question.Though you can loose the %ERRORLEVEL% because of the del command , but you can keep it in temp variable:
type some.txt>temp.bat
call temp.bat
set temp_el=%errorlevel%
del /q /f temp.bat
exit /b %temp_el%
I'm pretty sure you cannot do what you want. Windows will not let you configure the OS to recognize any other extensions as batch files. Only .bat and .cmd are supported.
You could process a series of simple commands within a text file using a FOR /F loop, but it will be very restrictive. For example, it will not support IF, FOR, GOTO Label, or CALL :Label. There are probably other restrictions. Within your main batch file, you could have the following:
for /f delims^=^ eol^= %%A in (script.txt) do %%A
You might be able to support IF and/or FOR if you execute the command via a new CMD.EXE shell, but then you cannot preserve the value of variables that might be SET by the command.
for /f delims^=^ eol^= %%A in (script.txt) do cmd /c "%%A"
See the windows shell commands
assoc. Associates a filename extension (e.g. *.txt) with a file type.
ftype. Lets you create a new file type that tells the windows shell how to open a particular kind of file.
From a command prompt, typing assoc /? or ftype /? will get you help on them. Or use your google-fu to find the MS docs.
*.bat is mapped to the file type batfile; *.cmd is mapped to the file type cmdfile. In windows 7 they are identical. If you want to be able to run files named *.foobar as a batch files, just type:
assoc .foobar=cmdfile
Then, assuming a file named 'sillyness.foobar' existing on the path, you just just type
c:\> sillyness
and it will find sillyness.foobar and execute it as a batch file. The Windows shell has a priority for how it resolves conflicts when you have files with the same name and different extensions (.com vs .cmd vs .bat, etc.)
Something like
assoc .pl=perlscript
ftype perlscript=perl.exe %1 %*
will set you up to run perl scripts as if they were .bat files.
If your batch commands are simple sequential ones then you could use this at the command prompt. Double the % signs for use in a batch file.
for /f "delims=" %a in (file.txt) do %a

How to copy a location to a batch file from a file that is dragged and dropped to open the batch file

So I've been trying to create a batch file for a piece of software called DiscEX the software requires command line use from cmd.exe windows xp or higher the way it's initiated is like this discex (any arguments needed) location of iso file.
Now I can get the software to run using the batch file but I can't seem to figure out how to copy the target location of a file that was dragged onto it to open the batch file up
Here is what the batch file in notepad looks like.
#echo off
echo Welcome to AutoDiscEx
pause
C:\windows\system32\discex
pause
also I need to be able to start in the working directory of a portable hard drive.
All you need to do is
C:\windows\system32\discex "%1"
to get a file path argument passed into the batch
If the batch file is in the working directory already, put
cd /d %~dp0 in the batch after #echo off
If you want to determine what drive is the external usb drive, use
#echo off
setlocal
set wmi='wmic logicaldisk where "volumeserialnumber='32A78F3B'" get caption'
for /f "skip=1 delims=" %%A in (%wmi%) do (
for /f "tokens=1 delims=:" %%B in ("%%A") do (set drive=%%B)
)
echo %drive%
where volumeserialnumber is the output from vol [driveletter of USB drive:] with the - removed.
When you drag a file on a batch file, the full file path is available in the first argument (%1) of the batch file. If you need this argument to be fed to the discex application as its first argument, you can do:
#echo off
echo Welcome to AutoDiscEx
pause
C:\windows\system32\discex %1
pause

Access clipboard in Windows batch file

Any idea how to access the Windows clipboard using a batch file?
To set the contents of the clipboard, as Chris Thornton, klaatu, and bunches of others have said, use %windir%\system32\clip.exe.
Update 2:
For a quick one-liner, you could do something like this:
powershell -sta "add-type -as System.Windows.Forms; [windows.forms.clipboard]::GetText()"
Capture and parse with a for /F loop if needed. This will not execute as quickly as the JScript solution below, but it does have the advantage of simplicity.
Updated solution:
Thanks Jonathan for pointing to the capabilities of the mysterious htmlfile COM object for retrieving the clipboard. It is possible to invoke a batch + JScript hybrid to retrieve the contents of the clipboard. In fact, it only takes one line of JScript, and a cscript line to trigger it, and is much faster than the PowerShell / .NET solution offered earlier.
#if (#CodeSection == #Batch) #then
#echo off
setlocal
set "getclip=cscript /nologo /e:JScript "%~f0""
rem // If you want to process the contents of the clipboard line-by-line, use
rem // something like this to preserve blank lines:
for /f "delims=" %%I in ('%getclip% ^| findstr /n "^"') do (
setlocal enabledelayedexpansion
set "line=%%I" & set "line=!line:*:=!"
echo(!line!
endlocal
)
rem // If all you need is to output the clipboard text to the console without
rem // any processing, then remove the "for /f" loop above and uncomment the
rem // following line:
:: %getclip%
goto :EOF
#end // begin JScript hybrid chimera
WSH.Echo(WSH.CreateObject('htmlfile').parentWindow.clipboardData.getData('text'));
Old solution:
It is possible to retrieve clipboard text from the Windows console without any 3rd-party applications by using .NET. If you have powershell installed, you can retrieve the clipboard contents by creating an imaginary textbox and pasting into it. (Source)
Add-Type -AssemblyName System.Windows.Forms
$tb = New-Object System.Windows.Forms.TextBox
$tb.Multiline = $true
$tb.Paste()
$tb.Text
If you don't have powershell, you can still compile a simple .NET application to dump the clipboard text to the console. Here's a C# example. (Inspiration)
using System;
using System.Threading;
using System.Windows.Forms;
class dummy {
[STAThread]
public static void Main() {
if (Clipboard.ContainsText()) Console.Write(Clipboard.GetText());
}
}
Here's a batch script that combines both methods. If powershell exists within %PATH%, use it. Otherwise, find the C# compiler / linker and build a temporary .NET application. As you can see in the batch script comments, you can capture the clipboard contents using a for /f loop or simply dump them to the console.
:: clipboard.bat
:: retrieves contents of clipboard
#echo off
setlocal enabledelayedexpansion
:: Does powershell.exe exist within %PATH%?
for %%I in (powershell.exe) do if "%%~$PATH:I" neq "" (
set getclip=powershell "Add-Type -AssemblyName System.Windows.Forms;$tb=New-Object System.Windows.Forms.TextBox;$tb.Multiline=$true;$tb.Paste();$tb.Text"
) else (
rem :: If not, compose and link C# application to retrieve clipboard text
set getclip=%temp%\getclip.exe
>"%temp%\c.cs" echo using System;using System.Threading;using System.Windows.Forms;class dummy{[STAThread]
>>"%temp%\c.cs" echo public static void Main^(^){if^(Clipboard.ContainsText^(^)^) Console.Write^(Clipboard.GetText^(^)^);}}
for /f "delims=" %%I in ('dir /b /s "%windir%\microsoft.net\*csc.exe"') do (
if not exist "!getclip!" "%%I" /nologo /out:"!getclip!" "%temp%\c.cs" 2>NUL
)
del "%temp%\c.cs"
if not exist "!getclip!" (
echo Error: Please install .NET 2.0 or newer, or install PowerShell.
goto :EOF
)
)
:: If you want to process the contents of the clipboard line-by-line, use
:: something like this to preserve blank lines:
for /f "delims=" %%I in ('%getclip% ^| findstr /n "^"') do (
set "line=%%I" & set "line=!line:*:=!"
echo(!line!
)
:: If all you need is to output the clipboard text to the console without
:: any processing, then remove the above "for /f" loop and uncomment the
:: following line:
:: %getclip%
:: Clean up the mess
del "%temp%\getclip.exe" 2>NUL
goto :EOF
Slimming it down (on a new enough version of Windows):
set _getclip=powershell "Add-Type -Assembly PresentationCore;[Windows.Clipboard]::GetText()"
for /f "eol=; tokens=*" %I in ('%_getclip%') do set CLIPBOARD_TEXT=%I
First line declares a powershell commandlet.
Second line runs and captures the console output of this commandlet into the CLIPBOARD_TEXT enviroment variable (cmd.exe's closest way to do bash style backtick ` capture)
Update 2017-12-04:
Thanks to #Saintali for pointing out that PowerShell 5.0 adds Get-Clipboard as a top level cmdlets, so this now works as a one liner:
for /f "eol=; tokens=*" %I in ('powershell Get-Clipboard') do set CLIPBOARD_TEXT=%I
The clip command is good to pipe text to the clipboard, but it can't read from the clipboard. There is a way in vbscript / javascript to read / write the clipboard but it uses automation and an invisible instance if Internet Explorer to do it so its pretty fat.
The best tool I've found for working the clipboard from script is Nirsoft's free NirCmd tool.
http://www.nirsoft.net/utils/nircmd.html
Its like a swiss army knife of batch commands all in one small .exe file. For clipboard commands you would say someting like
nircmd clipboard [Action] [Parameter]
Plus you can directly refer to clipboard contents in any of its commands using its ~$clipboard$ variable as an argument. Nircmd also has commands in it to run other programs or commands from so it is possible to use it to pass the clipboard contents as an argument to other batch commands this way.
Clipboard actions:
set - set the specified text into the clipboard.
readfile - set the content of the specified text file into the clipboard.
clear - clear the clipboard.
writefile - write the content of the clipboard to a file. (text only)
addfile - add the content of the clipboard to a file. (text only)
saveimage - Save the current image in the clipboard into a file.
copyimage - Copy the content of the specified image file to the clipboard.
saveclp - Save the current clipboard data into Windows .clp file.
loadclp - Load Windows .clp file into the clipboard.
Note that most programs will always write a plain text copy to the clipboard even when they are writing a special RTF or HTML copy to the clipboard but those are written as content using a different clipboard format type so you may not be able to access those formats unless your program explicitly requests that type of data from the clipboard.
Best way I know, is by using a standalone tool called WINCLIP .
You can get it from here: Outwit
Usage:
Save clipboard to file: winclip -p file.txt
Copy stdout to clipboard: winclip -c Ex: Sed 's/find/replace/' file | winclip -c
Pipe clipboard to sed: winclip -p | Sed 's/find/replace/'
Use winclip output (clipboard) as an argument of another command:
FOR /F "tokens=* usebackq" %%G in ('winclip -p') Do (YOUR_Command %%G ) Note that if you have multiple lines in your clipboard, this command will parse them one by one.
You might also want to take a look at getclip & putclip tools: CygUtils for Windows but winclip is better in my opinion.
With Vista or higher, it's built in. Just pipe output to the "clip" program.
Here's a writeup (by me):
http://www.clipboardextender.com/general-clipboard-use/command-window-output-to-clipboard-in-vista
The article also contains a link to a free utility (written by Me, I think) called Dos2Clip, which can be used on XP.
EDIT: I see that I've gotten the question backwards, my solution OUTPUTS to the clipboard, doesn't read it. sorry!
Update: Along with Dos2Clip, is Clip2Dos (in the same zip), which will send the clipboard text to stdout. So this should work for you. Pascal source is included in the zip.
To retrive clipboard content from your batch script: there is no "pure" batch solution.
If you want an embed 100% batch solution, you will need to generate the other language file from your batch.
Here is a short and batch embed solution which generate a VB file (Usually installed on most windows)
Since all answers are confusing, here my code without delays or extra windows to open stream link copied from clipboard:
#ECHO OFF
//Name of TEMP TXT Files
SET TXTNAME=CLIP.TXT
//VBA SCRIPT
:: VBS SCRIPT
ECHO.Set Shell = CreateObject("WScript.Shell")>_TEMP.VBS
ECHO.Set HTML = CreateObject("htmlfile")>>_TEMP.VBS
ECHO.TXTPATH = "%TXTNAME%">>_TEMP.VBS
ECHO.Set FileSystem = CreateObject("Scripting.FileSystemObject")>>_TEMP.VBS
ECHO.Set File = FileSystem.OpenTextFile(TXTPATH, 2, true)>>_TEMP.VBS
ECHO.File.WriteLine HTML.ParentWindow.ClipboardData.GetData("text")>>_TEMP.VBS
ECHO.File.Close>>_TEMP.VBS
cscript//nologo _TEMP.VBS
:: VBS CLEAN UP
DEL _TEMP.VBS
SET /p streamURL=<%TXTNAME%
DEL %TXTNAME%
:: 1) The location of Player
SET mvpEXE="D:\Tools\Programs\MVP\mpv.com"
:: Open stream to video player
%mvpEXE% %streamURL%
#ECHO ON
Piping output to the clipboard is provided by clip, as others have said. To read input from the clipboard, use the pclip tool in this bundle. And there's tons of other good stuff in there.
So for example, you're going through an online tutorial and you want to create a file with the contents of the clipboard...
c:\>pclip > MyNewFile.txt
or you want to execute a copied command...
c:\>pclip | cmd
This might not be the exact answer, but it will be helpful for your Quest.
Original post:
Visit https://groups.google.com/d/msg/alt.msdos.batch/0n8icUar5AM/60uEZFn9IfAJ
Asked by Roger Hunt
Answered by William Allen
Much Cleaner Steps:
Step 1) create a 'bat' file named Copy.bat in desktop using any text editors and copy and past below code and save it.
#ECHO OFF
SET FN=%1
IF ()==(%1) SET FN=H:\CLIP.TXT
:: Open a blank new file
REM New file>%FN%
ECHO.set sh=WScript.CreateObject("WScript.Shell")>_TEMP.VBS
ECHO.sh.Run("Notepad.exe %FN%")>>_TEMP.VBS
ECHO.WScript.Sleep(200)>>_TEMP.VBS
ECHO.sh.SendKeys("^+{end}^{v}%%{F4}{enter}{enter}")>>_TEMP.VBS
cscript//nologo _TEMP.VBS
ECHO. The clipboard contents are:
TYPE %FN%
:: Clean up
DEL _TEMP.VBS
SET FN=
Step 2) create a Blank text file (in my case 'CLIP.txt' in H Drive) or anywhere, make sure you update the path in Copy.bat file under 'FN=H:\CLIP.txt' with your destination file path.
That's it.
So, basically when you copy any text from anywhere and run Copy.bat file from desktop, it updates CLIP.txt file with the Clipboard contents in it and saves it.
Uses:
I use it to transfer data from remotely connected machines where copy/paste is disabled between different connections; where shared drive (H:) is common to all Connections.
Multiple lines
The problem is resolved, but disappointment remains.
I was forced to split one command into two.
First of them well understands the text and service characters, but does not understand the backspace.
The second understands backspace, but does not understand many service characters.
Can anyone unite them?
Notepad ++, in the place where it should open, is commented out because sometimes the window does not get access to enter characters and therefore you need to make sure that it is active.
Of course, it is better to enter characters using the PID of the notebook process, but ...
The request from wmic opens for a long time, so do not close the notepad window until the bat file is closed.
#echo off
set "like=Microsoft Visual C++"
set "flag=0"
start /max C:\"Program Files\Notepad++\notepad++.exe" -nosession -multiInst
( set LF=^
%= NEWLINE =%
)
set ^"NL=^^^%LF%%LF%^%LF%%LF%^^"
::------------------
setlocal enabledelayedexpansion
for /f "usebackq delims=" %%i in ( `wmic /node:"papa" product where "Name like '%%%like%%%'" get * ^| findstr /r /v "^$"`) do (
for /f tokens^=1^ delims^=^" %%a in ("%%i") do set str=%%a
if "!flag!"=="0" (
::start /max C:\"Program Files\Notepad++\notepad++.exe" -nosession -multiInst& set "flag=1"
for /f "delims=" %%i in ('mshta "javascript:new ActiveXObject('WScript.Shell').SendKeys('{BS}{BS}{BS}{BS}');close(new ActiveXObject('Scripting.FileSystemObject'));"') do set
set flag=1
)
#set /P "_=%%str%%"<NUL|clip
for /f "delims=" %%i in ('mshta "javascript:new ActiveXObject('WScript.Shell').SendKeys('^v');close(new ActiveXObject('Scripting.FileSystemObject'));"') do set
(echo %%NL%%)|clip
for /f "delims=" %%i in ('mshta "javascript:new ActiveXObject('WScript.Shell').SendKeys('^v');close(new ActiveXObject('Scripting.FileSystemObject'));"') do set
)
setlocal disabledelayedexpansion
Here's one way with mshta:
#echo off
:printClip
for /f "usebackq tokens=* delims=" %%i in (
`mshta "javascript:Code(close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(clipboardData.getData('Text'))));"`
) do (
echo cntent of the clipboard:
echo %%i
)
the same thing for accessing it directly from console:
for /f "usebackq tokens=* delims=" %i in (`mshta "javascript:Code(close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(clipboardData.getData('Text'))));"`) do #echo %i

Resources