How do I get the parent command in Windows command line? - windows

In a Unix shell, I can get the parent command using ps -ocommand= -p $PPID. How can I do the same from the Windows shell?
I need this for a Git pre-commit hook that detects whether the commit was initiated with the --amend flag.

A crude way of doing this is by looking up current PID using a title query.
title ABC
for /f "tokens=2" %%P in ('tasklist /V ^| findstr "ABC"') do set CurrentPid=%%P
for /f "tokens=2 skip=1" %%P in ('wmic process where ProcessId^=%CurrentPid% get Caption^,ParentProcessId^,ProcessId') do set ParentProcessId=%%P
wmic process where ProcessId=%ParentProcessId% get CommandLine
There is a lot that can be optimized there.

Related

Command output set as variable

I've been trying to make a script that installs the current nvidia driver, I've gone pretty far but there's one thing missing
I'm trying to use nvidia-smi to find the driver version and here's the command output
C:\>nvidia-smi --query-gpu=driver_version --format=csv
driver_version
457.30
I've been trying to set 457.30 in %driver% here's what I got so far
FOR /F "tokens=* skip=1" %%g IN ('nvidia-smi --query-gpu=driver_version --format=csv') do (SET "driver=%%g")
I also tried a combination with findstr but that ended up being a disaster
for /F "tokens=* skip=1" %%g in ('nvidia-smi --query-gpu=driver_version --format=csv ^| findstr "."') do set driver=%%g
In any case, %%g and %driver% return as empty.
echo %driver%
returns
C:\>echo
ECHO is on.
Any ideas?
Thank you for your cooperation.
Your variable isn't getting set because right now your nvidia-smi command is throwing an error (to stdout, curiously) but skip=1 is skipping over it so there's nothing left to set the variable to.
= is one of the default delimiters for strings and so both of the = symbols in your command need to be escaped for your query to be executed correctly.
#echo off
for /F "delims=" %%g IN ('nvidia-smi --query-gpu^=driver_version --format^=csv ^| find "."') do set "driver=%%g"
echo %driver%

WMIC: how to use "process call create" with the current working directory

I want to use wmic Process call create to open a CMD at current working directory. But when I add "%~dp0" to specify directory the following command output nothing.
for /F "tokens=2 delims==; " %%I in ('wmic Process call create "cmd.exe"^,"%~dp0" ^| find "ProcessId"') do echo PID = %%I
As I know %~dp0 will end with \, so %~dp0 will be like C:\Users\.
If I remove \ It will works. E.g: The following command will work.
for /F "tokens=2 delims==; " %%I in ('wmic Process call create "cmd.exe"^,"C:\Users" ^| find "ProcessId"') do echo PID = %%I
How can I use wmic Process call create with dynamic working directory?
I found the solution. I have to add a trailing dot (.).
%~dp0 to %~dp0.
for /F "tokens=2 delims==; " %%I in ('wmic Process call create "cmd.exe"^,"%~dp0." ^| find "ProcessId"') do echo PID = %%I
Read more: How to get the path of a batch script without the trailing backslash in a single command?

Script to get Windows version and send it by email

I want to monitor version of Windows on all computers in a domain. So I want to create a .bat file that get the local Windows version and if possible send it via email using telnet command.
I never wrote a script in Windows. So it's difficult for me to start in this area. So any help will be appreciated.
for /f "skip=3 delims=\" %%A in ('net view ^| findstr /v /C:"The command completed successfully"') do Echo %%A
Will give you a list of computernames. Put it in a file.
for /f "skip=3 delims=\" %%A in ('net view ^| findstr /v /C:"The command completed successfully"') do Echo %%A >> Computername.txt
Then type to do turned on computers
wmic /node:#"Computername.txt" os get version /format:csv

Manage a process inside a cmd file

I would like to manage a process inside a cmd file. My cmd will launch an other cmd file and i would like the update status, ... For example, i would like to write the date when the other process is closed.
So, i tried :
rem %process% is the path to my cmd file
start "Process" %process%
Is there any way to manage the started process ?
I tried to use :
for /F "TOKENS=1,2,*" %%a in ('tasklist /FI "IMAGENAME eq %process%"') do (
set MyPID=%%b
)
The problem is that the process is a cmd file so the IMAGENAME will be "cmd.exe".
Any solutions ?
it will be easier for you to get the pid when you are starting the process.
You can do this with WMIC command (though it's a little bit cumbersome):
#echo off
for /f "skip=5 tokens=* delims=" %%a in ('WMIC process call create "notepad.exe"^,"c:\"') do (
for /f "tokens=2 delims=;= " %%# in ("%%a") do if not defined pid set "pid=%%#"
)
echo %pid%
You can use also this ready to use script which can spare you some work (hope the help message is descriptive enough)
instead of IMAGENAME look for WINDOWTITLE (you defined that as a parameter to start):
tasklist /fi "windowtitle eq "Process"
use this in your existing for loop.
you can add /v to tasklist to get a verbose output, but you don't really need it for this task.

cmd batch file for/f closes, comspec is already set

so ive been searching for the solution to this problem for awhile now, everywhere i look everyone just says "set the compsec to point to cmd"...which is super helpful cause no one actually even says how to do that.
but when i open cmd, and type "Set" and hit ENTER, it shows ComSpec=C:\Windows\system32\cmd.exe
I checked there and sure enough, cmd.exe is in there, it works just fine. But for/f still closes before performing any operation.
How do I fix this?
#echo off
for /f "tokens=2*" %%a in ('dir /b /s findstr "Find Me Testing"') do set "AppPath=%%~b"
set "AppPath=%AppPath%"
echo %AppPath%
for /f "tokens=2*" %%a in ('dir /b /s /a-d ^| findstr "Find Me Testing"') do set "AppPath=%%~b"
set "AppPath=%AppPath%"
echo %AppPath%
pause
for /f "usebackq" %a in ('dir /b /s /a-d ^| findstr "To Be Deleted.me"') do set fileLocation=%~pa
echo %fileLocation%
pause
pause
stop
pause
wait 50
As you can see I've been testing various methods of doing what I want.
I lay good odds that your problem is with the cmd.exe autorun feature.
If you open a command session and enter cmd /?, then at about the 5th paragraph you will see the following:
If /D was NOT specified on the command line, then when CMD.EXE starts, it
looks for the following REG_SZ/REG_EXPAND_SZ registry variables, and if
either or both are present, they are executed first.
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
and/or
HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
I'd be willing to bet that one of those two registry settings is set to a command or script that is causing your problem. Edit your registry and remove those settings, and your problem should go away.
You can see a similar story about a user having trouble with FOR /F at https://blogs.msdn.microsoft.com/oldnewthing/20071121-00/?p=24433.
The FOR /F command executes your commands within your IN('....') clause via a new cmd.exe process, and that process will always run any autorun setting that may be present. Unfortunately it is impossible to disable this FOR /F "feature" - I think this is a horrible design flaw.
Windows pipes also use child cmd.exe processes - one for each side of the pipe. But the pipe instantiation of cmd.exe includes the /D option, so autorun is disabled. You can see this by running the following command from the command line:
echo %^cmdcmdline% | findstr "^"
On my machine it produces the following:
C:\WINDOWS\system32\cmd.exe /S /D /c" echo %cmdcmdline% "
Now do the equivalent with FOR /F (on a healthy machine)
for /f "delims=" %a in ('echo %^cmdcmdline%') do #echo %a
My machine produces:
C:\WINDOWS\system32\cmd.exe /c echo %cmdcmdline%
No /D option :(

Resources