How to eliminate NUL (0x00) characters from file or from a string.

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

How to eliminate NUL (0x00) characters from file or from a string.

Post by MigrationUser »

21 Feb 2021 02:18
nomad


My dilemma starts with the output of WMIC command.
I am trying to get the whole command line of a PID with this command :

Code: Select all

wmic process where processID=12345 get commandLine > command.txt
and the output I get looks something like this:

Code: Select all

 _C o m m a n d L i n e
 n o t e p a d     q . b a t
everything that shows like white-space is actually a null character (0x00) in the file, when I examine the file with a hex editor.

Purpose of the batch file I want to write is to kill PIDs which are of notepad and the file opened by it matches a certain pattern. Say I am running 20 notepad sessions and 8 of them are like this :

notepad JOHNoutput0123
...
notepad MARYoutput2385453

so I want to kill any notepad session with the string "output" in it.
If I can collapse the command.txt file, with no spaces between characters, I can make a string comparison and if it isnotepad editing something with output in its name, I can kill the session.

I am all ears for a better solution I am not aware of it yet as well.

Thanks

----------------------------

#2 21 Feb 2021 03:36
Shadow Thief


Notepad is nice enough to put the filename in the window title, and taskkill accepts wildcards, so you can just do

Code: Select all

taskkill /fi "imagename eq notepad.exe" /fi "windowtitle eq *output*"
----------------------------

#3 21 Feb 2021 05:09
nomad
Shadow Thief wrote:

Notepad is nice enough to put the filename in the window title, and taskkill accepts wildcards, so you can just do

Code: Select all

    taskkill /fi "imagename eq notepad.exe" /fi "windowtitle eq *output*"
Notepad was an example. The command I am dealing with is very esoteric. It is something I have to do for work. Every job runs under a command prompt and unless the process gets killed, the command window stays open. With 25+ cmd windows on the desktop, it is hard to find which one was running what. So, my only option is to get this command line arguments is from WMIC, as I do not want to venture into PowerShell at this time.

----------------------------

#4 21 Feb 2021 06:37
Shadow Thief


Since you've already got the PIDs, just pass them to taskkill.

Code: Select all

taskkill /PID 12345 /T
or whatever the PID is instead of 12345

Last edited by Shadow Thief (21 Feb 2021 06:37)

----------------------------

#5 22 Feb 2021 05:32
nomad
Shadow Thief wrote:

Since you've already got the PIDs, just pass them to taskkill.

Code: Select all

    taskkill /PID 12345 /T
or whatever the PID is instead of 12345
Wish it would be that simple.
Going with the notepad example, say I have 25 different notepad sessions open but only 8 of them are editing documents that I do not care about and want them gone. I want the remaining 17 notepad sessions to stay running. 25 sessions count here is a hypothetical number. My application can launch less or more number of instances.

I could not find a better way to determine the command line arguments other than WMIC command I mentioned in my original question, output of which is not optimal.

Going back to my original question, is there a way to remove nul (0x00) characters from a file or from a string value assigned to a variable ?

----------------------------

#6 22 Feb 2021 10:10
ArtMouse


They aren't null characters but HIBYTEs of UTF-16LE. So it seems you're looking for a way to either a) make wmic output ANSI text or b) convert UTF-16LE text to ANSI text.
a) would be using pipe:

Code: Select all

C:\>wmic process where processID=16352 get commandLine | findstr /r /c:"[A-Z]output[0-9]"
notepad  JOHNoutput0123
b) would be type'ing and redirecting:

Code: Select all

Z:\>wmic process where processID=16352 get commandLine > command.txt

Z:\>type command.txt > command-ansi.txt

Z:\>findstr /r /c:"[A-Z]output[0-9]" command.txt

Z:\>findstr /r /c:"[A-Z]output[0-9]" command-ansi.txt
notepad  JOHNoutput0123
Both may have a risk of losing some extended characters.

----------------------------

#7 22 Feb 2021 23:38
nomad
ArtMouse wrote:

They aren't null characters but HIBYTEs of UTF-16LE. So it seems you're looking for a way to either a) make wmic output ANSI text or b) convert UTF-16LE text to ANSI text.
a) would be using pipe:

Code: Select all

    C:\>wmic process where processID=16352 get commandLine | findstr /r /c:"[A-Z]output[0-9]"
    notepad  JOHNoutput0123
b) would be type'ing and redirecting:

Code: Select all

    Z:\>wmic process where processID=16352 get commandLine > command.txt

    Z:\>type command.txt > command-ansi.txt

    Z:\>findstr /r /c:"[A-Z]output[0-9]" command.txt

    Z:\>findstr /r /c:"[A-Z]output[0-9]" command-ansi.txt
    notepad  JOHNoutput0123
Both may have a risk of losing some extended characters.
Unfortunately it still is not working. The pattern your commands include as

Code: Select all

[A-Z]output[0-9]"
actually comes as

Code: Select all

[A-Z]o u t p u t[0-9]"
and I am willing to go with that but

a. the string output is not fixed an all runs. Today it might be "output", tomorrow I could be looking into something like "progress" or any random word.
b. The characters between the letters of "output" are not actually blanks as I typed here. They show as hex 00 on the hex editor, whereas space is 0x20 in ANSI notation.

----------------------------

#8 23 Feb 2021 06:29
ArtMouse
nomad wrote:

a. the string output is not fixed an all runs. Today it might be "output", tomorrow I could be looking into something like "progress" or any random word.
Then why don't you search for whatever ANSI text you want?

Code: Select all

C:\test>notepad whatever

C:\test>tasklist /fi "imagename eq notepad.exe"

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
notepad.exe                   3364 31C5CE94259D4006           2     16,972 K

C:\test>rem Using pipe makes wmic output ANSI text

C:\test>wmic process where processID=3364 get commandLine | findstr /l /c:"whatever"
notepad  whatever

C:\test>rem Redirecting to a file makes wmic output UTF-16LE text

C:\test>wmic process where processID=3364 get commandLine > command.txt

C:\test>rem but then type'ing and redirecting it can convert it to ANSI text

C:\test>type command.txt > command-ansi.txt

C:\test>findstr /l /c:"whatever" command-ansi.txt
notepad  whatever
nomad wrote:

b. The characters between the letters of "output" are not actually blanks as I typed here. They show as hex 00 on the hex editor, whereas space is 0x20 in ANSI notation.
0x00 in your case is not a null character but a high byte of some UTF-16LE characters. 0x20 in ANSI is "0x20 followed by 0x00" in UTF-16LE. The true null character in UTF-16LE is "0x00 followed by 0x00".

Last edited by ArtMouse (23 Feb 2021 06:30)

----------------------------

#9 18 Mar 2021 11:24
Manna5


If you want to kill all instances of notepad, you even do not have to know PIDs, just use /im option:

Code: Select all

taskkill /f /im notepad.exe
The /f will be used to target all instances, because it tries to repeat killing notepad while there is at least one instance.

----------------------------

#10 30 Mar 2021 09:41
Hackoo


Hi smile
I recommend you to take a look at this ==> Combine Batch/WMIC + ANSI/UNICODE Output formatting
Post Reply