Direct command and using bat file difference? - batch-file

I can get image size with this code if I run direct cmd:
identify -format "%wx%h" E:\Image.jpg
(the result = 640x480)
However, if I put this code in a bat file,
#echo off
identify -format "%wx%h" E:\Image.jpg
it doesn't work.
so, (the result = h) ??
How can I do this. Thanks...

Switch % to %% in a Batchfile.
Your code should be something like: identify -format "%wx%h" E:\Image.jpg

Related

how to concatenate two variables when one has spaces in it in AzureDevops batch file

I have this input in my ps script. I am passing $(Build.ArtifactStagingDirectory) system variable to get the path in the input %1. The path has spaces i.e. E:\Build Agents\Agent2\_work\15\a. I need to concatenate this with other path but I am not able to do so.
set BuildDrop=%1
set Directory=%BuildDrop% + "\adapters\bin"
This is my output, which is incorrect as Directory should be something like E:\Build Agents\Agent2\_work\15\a\adapters\bin. How to solve this?
set BuildDrop="E:\Build Agents\Agent2\_work\15\a"
set Directory="E:\Build Agents\Agent2\_work\15\a" + "\adapters\bin"
My task is like this in my build pipeline
Task : Batch script
Description : Run a Windows command or batch script and optionally allow it to change the environment
Version : 1.1.10
I found the solution for this. Since my %1 had space I needed to remove apostrohphe before assigning. I did it using ~ variable. working code looks like this.
set "BuildDrop=%~1"
set "Directory=%BuildDrop%\adapters\bin"
You could try this :
set BuildDrop=%1
set Directory= %BuildDrop%\adapters\bin
echo %Directory%
Sample Output
This is the concatenation code.
%BuildDrop%\adapters\bin
In my above sample I am trying to concatenate C:\Users\svijay\Desktop & \adapters\bin using the batch script
And the output : C:\Users\svijay\Desktop\adapters\bin
UPDATE :
#echo off
set BuildDrop=%1
set Directory= %BuildDrop%\adapters\bin
set Directory= %Directory:"=%
echo %Directory%
If you have space, you could provide the "" to provide input.
In your code you could remove the double quotes.
%Directory:"=% - Removes the Double quotes from the string literal.
Sample output :
You may use this to create Azure DevOps variable containing your path
powershell: |
$directory = $(Build.ArtifactStagingDirectory)
$newDirectory = $directory + "\adapters\bin"
Write-Host "##vso[task.setvariable variable=testvar]$newDirectory "
and if you need set variable in powershell script
$BuildDrop=$args[0]
$Directory=$BuildDrop + "\adapters\bin"
Here you have an article how to use parameters in powershell.
We can use powershell task in the Azure DevOps to concatenate two variables.
Sample:
Write-Host "Build.ArtifactStagingDirectory is $(Build.ArtifactStagingDirectory)"
Write-Host "Build.ArtifactStagingDirectory is $(Build.ArtifactStagingDirectory)\adapters\bin"
Result:
In addition, I found a similar issue, please also check it.
Update1
Use power shell script in the Azure DevOps pipeline
$testpath1 = "E:\Build Agents\Agent2\_work\15\a"
$testpath2 = "\adapters\bin"
Write-Host "path is $($testpath1)$($testpath2)"
Result:
Use local power shell
Result:
Update2
.bat file
set testpath1=E:\Build Agents\Agent2\_work\15\a
set testpath2=\adapters\bin
set newpath=%testpath1%%testpath2%
echo %newpath%
Pipeline result:

Running Powershell command in a command line/batch file

I am creating a batch file which involves converting a SID to local/domain username. Since we can not achieve this using the command prompt I am planning to use powershell and I have the PS command as well. I am able to run it in powershell console without any issue, but not sure how to use it in command prompt as a SINGLE LINE(to use it in batch file). I have already tried the below.
Powershell command which works perfectly in PS console -
([System.Security.Principal.SecurityIdentifier]("S-1-5-32-544")).Translate([System.Security.Principal.NTAccount]).Value
Command lines which I have already tried but with no success -
powershell -command ([System.Security.Principal.SecurityIdentifier]("S-1-5-32-544")).Translate([System.Security.Principal.NTAccount]).Value
powershell -command {([System.Security.Principal.SecurityIdentifier]("S-1-5-32-544")).Translate([System.Security.Principal.NTAccount]).Value}
What am I doing wrong? Is it due to any escape characters or am I missing any powershell command parameters? Any help is greatly appreciated.
powershell -command "([System.Security.Principal.SecurityIdentifier]('S-1-5-32-544')).Translate([System.Security.Principal.NTAccount]).Value"
worked for me. Just a question of changing the innermost double-quotes to singles around the SID.
Alternatively, escape them with a backslash
powershell -command "([System.Security.Principal.SecurityIdentifier](\"S-1-5-32-544\")).Translate([System.Security.Principal.NTAccount]).Value"
Here is a short VBScript script that uses WMI to do the conversion for you:
Dim SID
SID = WScript.Arguments.Item(0)
Dim SWbemServices, SWbemObject
Set SWbemServices = GetObject("winmgmts:root/CIMV2")
Set SWbemObject = SWbemServices.Get("Win32_SID.SID='" & SID & "'")
WScript.Echo SWbemObject.ReferencedDomainName & "\" & SWbemObject.AccountName
You would of course need to capture this script's output from your shell script (batch file).
You're actually really close. What you want to do is this:
powershell -command "& {([System.Security.Principal.SecurityIdentifier]('S-1-5-32-544')).Translate([System.Security.Principal.NTAccount]).Value}"
I tested this using the Get-WmiObject cmdlet. In a standard, but elevated cmd shell I entered:
powershell -command "& {get-wmiobject win32_operatingsystem}"
At that point the wmi object data as returned by powershell was written to the console. You can also load the command into a variable like so:
set wmi=powershell -command "& {get-wmiobject win32_operatingsystem}"
If you call the variable %wmi% there's a delay before it prints. The command itself is in the variable so everytime you call the variable it'll execute the powershell code and return the result.
An alternative answer is to use a base64 encodedcommand switch.
#ECHO OFF
powershell -encodedcommand "KABbAFMAeQBzAHQAZQBtAC4AUwBlAGMAdQByAGkAdAB5AC4AUAByAGkAbgBjAGkAcABhAGwALgBTAGUAYwB1AHIAaQB0AHkASQBkAGUAbgB0AGkAZgBpAGUAcgBdACgAIgBTAC0AMQAtADUALQAzADIALQA1ADQANAAiACkAKQAuAFQAcgBhAG4AcwBsAGEAdABlACgAWwBTAHkAcwB0AGUAbQAuAFMAZQBjAHUAcgBpAHQAeQAuAFAAcgBpAG4AYwBpAHAAYQBsAC4ATgBUAEEAYwBjAG8AdQBuAHQAXQApAC4AVgBhAGwAdQBlAA=="
PAUSE
When decoded, you'll see it's the OP's original snippet (with the double quotes preserved). Maybe overkill for the OP, but useful for dev's with larger scripts. Plus my original answer was identical to someone elses, so I had to edit.
powershell.exe -EncodedCommand
Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.

invoking an executable on powershell and then type commands

I am trying to call a executable file as follows
.\test_use.exe
then I press the return key to get a interface like
"Enter a value between 1 and 5"
I type 4 and get some details. Is there a way to automate it via powershell. I tried passing
.\test_use.exe 4
But it does not work. I also tried
$input = "4"
Invoke-command ".\test_use.exe" -InputObject $input
I get the following error
Invoke-command: Parameter cannot be resolved using the specified named characters
Does anyone have any pointers ??
Will it be easier to do this in batch file and store the output in a text file?
In batch you might be able to do the following:
(echo 4) | test_use.exe
See this question - how to pass input to .exe in batch file?

Programmatically send key strokes to a window program in Groovy or bat script

Backstory: I need to programmatically find the differences between two files. I want to use WinMerge to generate a report (Tools -> Generate Report) that I can parse to get the differences between two files. I need this done using either a Groovy script or a bat script.
I was hoping that WinMerge would offer command line options to generate the report and then I could just use a Groovy Process object to execute WinMergeU.exe with the arguments. No such luck according to the command options I've found for WinMerge.
Next, I was hoping to be able to start WinMerge and send keystrokes to step through the menus to generate the report(Alt+T, R, Diff.html, [Enter]). I don't see a way to do that from a Groovy Process and I haven't found a way to do this in a bat script. I'm looking for something similar to WshShell.Sendkeys in VB. Is this a wild-goose chase?
UPDATE/Answer with PowerShell in a bat file:
I was intrigued by Knuckle-Dragger's comment about using a PowerShell script in a bat file.
$folder = "C:\DevTools\WinMerge\WinMergeU.exe"
ii $folder
Start-Sleep -m 1000
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
[Microsoft.VisualBasic.Interaction]::AppActivate("WinMerge")
Start-Sleep -m 100
[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
Start-Sleep -m 100
[System.Windows.Forms.SendKeys]::SendWait("%F")
[System.Windows.Forms.SendKeys]::SendWait("o")
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
[System.Windows.Forms.SendKeys]::SendWait("%T")
[System.Windows.Forms.SendKeys]::SendWait("r")
Start-Sleep -m 1000
[Microsoft.VisualBasic.Interaction]::AppActivate("Save As")
Start-Sleep -m 1000
[System.Windows.Forms.SendKeys]::SendWait("Diff.txt")
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
To encapsulate this in a command window, save it to a file PowerShellScript.ps1:
start /b /wait powershell.exe -nologo -WindowStyle Hidden -sta *PowerShellScript.ps1*
Here is a powershell example to activate winmerge and send some keys.
EDIT: Reduced copy pasta with some .NET variables. $SK = Sendkeys $AA = AppActivate $LRA = Reflect .NET.
$startapp = "C:\DevTools\WinMerge\WinMergeU.exe"
ii $startapp
$SK = "[System.Windows.Forms.SendKeys]::SendWait"
$AA = "[Microsoft.VisualBasic.Interaction]::AppActivate"
$LRA = "[void][System.Reflection.Assembly]::LoadWithPartialName"
Start-Sleep 1
$LRA+'("Microsoft.VisualBasic")'
$AA+'("WinMerge")'
Start-Sleep -m 100
$LRA+'("System.Windows.Forms")'
Start-Sleep -m 100
$SK+'("%F")'
$SK+'("o")'
$SK+'("{ENTER}")'
$SK+'("%T")'
$SK+'("r")'
Start-Sleep 1
$AA+'("Save As")'
Start-Sleep 1
$SK+'("Diff.txt")'
$SK+'("{ENTER}")'
To encapsulate this in a command window, save it to a file PowerShellScript.ps1: Note, changed the command syntax a bit, should work if you use the & {.\dot\source\path}
start /b /wait powershell.exe -nologo -WindowStyle Hidden -sta -Command "& {.\PowerShellScript.ps1}"
This is something that I threw together without testing, and I don't have WinMerge so testing isn't really an option.
RunMe.bat
start "" "C:\Path\WinMerge.exe" "file1" "file2"
GenerateDiffFile.vbs
GenerateDiffFile.vbs
Set s = CreateObject("WScript.Shell")
wscript.sleep(1000) ' Sleep for 1 second to allow time for WinMerge to finish loading and merge the files
s.SendKeys("%tr")
wscript.sleep(250) ' Give time for dialog box to appear
s.SendKeys("Diff.html{Enter}")
This is completely untested, but I think it is very close to what you need... You can see that the batch-file runs WinMerge, passing the two files to merge on the command line. Then it launches the VBS script, which pauses long enough to allow the launched WinMerge to be able to accept keyboard input. I used this page from Microsoft to know what keys to send.
I've been sending keys to programs for years. It works very reliably, as long as the program you want to send keys to keeps focus.
All I do is this:
echo y | "Batchfile needing the keystroke"

batch rename files on date

I rendered 140000 frames to create a movie of them.
However, it starts at 1.png where it would be better if it had started at 000001.png in order to keep the order good when importing it in final cut express.
I used to have a program r-name but that was based on power-pc so it doesn't work anymore.
Also the program was quite shit with even a batch of 300 files for example so i guess it would be better to use the terminal for that.
I have seen examples for renaming but most where for changing the extention for example or change a prefix.
Could someone help me with the right terminal script? I need to finish this project asap, else i would have re-rendered it but it takes 15 hours to do.
Not very efficient, but since you need to run it only once:
for i in `seq 1 140000`; do
mv $i.png `printf %06d $i`.png
done
EDIT: I assumed (maybe wrongly) that you were using Linux. This won't work on Windows.
EDIT: Yes, this should work in Mac OS X. Instead of typing these lines into the prompt, you can save it to a file. Usually, you would save such a file with a name like rename.sh. Then You can run it on the terminal like this:
sh rename.sh
If you are unsure, you can change the mv line into:
echo mv $i.png `printf %06d $i`.png
This will print out on the screen the commands that would be executed. Then if everything looks ok, you change it back to the original and run it again.
If the number of files is different, just replace 140000 with the number of the last file.
for i in *.png
do
name=${i%.png}
[[ $name =~ ^[0-9]+$ ]] && mv $i "$(printf '%06d' $name).png"
done
If you are using Windows
#echo off
setlocal enableDelayedExpansion
for %%F in (*.png) do (
set "name=00000%%~nF"
ren "%%F" "!name:~-6!.png"
)

Resources