Format of filenames passed to user commands

Discussion & Support for xplorer² professional

Moderators: fgagnon, nikos, Site Mods

diz
Member
Member
Posts: 10
Joined: 2016 Aug 31, 17:02

Format of filenames passed to user commands

Post by diz »

Long-time x2 user running 3.2.0.2 x64 Unicode on Win7-64.

In a user command, I want to pass selected files/directories to a Java program. I am familiar with user commands, but this one is problematic.

the command is
>cmd /k java [JAVA_CMD_OPTIONS_HERE] $A

When a file or directory contains certain non-ASCII (Unicode) characters, the Java program is passed an altered filename.

E.g., if a filename contains the character : [ U+FF1A Fullwidth colon], which is a legal Windows file character, the Java program is passed the filename with the fullwidth colon replaced by a regular colon, which of course isn't a legal Windows filename character.

With other legal unicode characters, the character is substituted or omitted entirely.

If I run the same program from the CMD prompt, e.g.,
java [JAVA_CMD_OPTIONS_HERE] m*

where the wildcard m* includes files containing unicode characters, the Java program is passed the correct filenames.

When filenames are passed to user commands via $F, $A, etc., are unicode characters altered in any way?
Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: Format of filenames passed to user commands

Post by Kilmatead »

diz wrote:When filenames are passed to user commands via $F, $A, etc., are unicode characters altered in any way?
Not as far as I have experienced. I cannot speak for the unicode-integrity of the java pipeline itself, but a quick test with a user-command of:

> cmd /k notepad $A

and passing a file with a specifically embedded wide-colon character in its path works fine for me (Win7 x64). Probably not related to this issue, but defining a user-command as "> cmd <prog>" is somewhat redundant as "$ <prog>" will execute via cmd directly. :shrug:

Try passing the same files (via user-commands) through another programme (notepad, et al), and see if their path-integrity is preserved (as mine all are), which would, if nothing else, rule out x2 as suspect.

For clarity: Also note that x2 uses the standard Windows UTF-16 (2 byte) encoding, whereas (I believe) Java defaults to UTF-8 (2 or more bytes [anything above U+007F]), so if something in the java chain is re-interpreting the text, that may be pertinent. But that's just a guess.
diz
Member
Member
Posts: 10
Joined: 2016 Aug 31, 17:02

Re: Format of filenames passed to user commands

Post by diz »

Kilmatead wrote: defining a user-command as "> cmd <prog>" is somewhat redundant as "$ <prog>" will execute via cmd directly. :shrug:
cmd /k is necessary in this case: I want to examine the Alternate Data Streams of selected files and keep the result window open for inspection.

Perhaps a simpler example: say I want to easily mark a file as read-only. I create the following user command

Code: Select all

>attrib +R $F
In a test directory I create the following empty text files:
simpleTestFile.txt
:*?“” ‘’.txt
The Naked Gun 33⅓ Final Insult (1994) 720p x264.txt

All filenames contain legal Windows filename characters. Run the attrib +R user command on each. In my case, it worked only for the first, despite the fact that the others are composed of legal Windows filename characters.
Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: Format of filenames passed to user commands

Post by Kilmatead »

You're confusing the user-command tokens. $F will supply only a single filename, regardless of how many are selected - also, it does not automatically cover spaces in the pathnames, so $F must always be surrounded by quotes ("$F") when used in a user command. (The multi-name $A token automatically does this for each selection, so must never be surrounded by quotes itself - but can't be used in this instance as attrib does not accept multiple consecutive filenames on a line.)

In other words, your command did not fail because of unicode:

If you want a user-command to iterate for multiple selections (one "cmd" each), use ">>" instead of ">".

In your example, considering some of those names contain spaces, were you to add quotes to the $F token and use it individually on each file, it will work fine, or just use: >> attrib +R "$F"

And yes, I tested this on your given examples, verbatim.

Off topic: ":*?“” ‘’.txt" - fantastic filename. :D
Last edited by Kilmatead on 2016 Aug 31, 22:10, edited 1 time in total.
diz
Member
Member
Posts: 10
Joined: 2016 Aug 31, 17:02

Re: Format of filenames passed to user commands

Post by diz »

Good catch RE quoting $F.

Back to the drawing board RE the underlying cause of this problem. Will post any follow-ups as they arise.
User avatar
nikos
Site Admin
Site Admin
Posts: 16402
Joined: 2002 Feb 07, 15:57
Location: UK

Re: Format of filenames passed to user commands

Post by nikos »

cmd isn't Unicode and so funny characters may get altered if you use cmd. If you must use CMD, then instead of $A use $a that will pass the short 8.3 version of the filename
Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: Format of filenames passed to user commands

Post by Kilmatead »

Not true... CMD console is unicode-compatible out of the box these days (Win7+), though older installs (XP/Vista, or possibly US-EN installs) may still have trouble displaying the character set initially and require the traditional playing with codepage/font settings first. Of course inputting unicode is just as annoying as ever, but throughput processing is supported.
diz
Member
Member
Posts: 10
Joined: 2016 Aug 31, 17:02

Re: Format of filenames passed to user commands

Post by diz »

Thank you all for the suggestions. Replacing "$F" with "$f" helped in another user command.

If I want to make all selected files/directories read-only, I can use

Code: Select all

>>attrib +R "$F"
But a window per file/directory briefly opens/closes in the background during execution. A bit unsightly. Using NirCmd's execmd option, the operation is executed without opening a cmd window in the background.

Code: Select all

>>C:\apps\x64\NirSoft\nircmd.exe execmd attrib +R "$F"
This works fine for nearly all files, but it chokes on some of the example txt files mentioned earlier. However, substituting "$f" allows it to process all files without a hitch.

Code: Select all

>>C:\apps\x64\NirSoft\nircmd.exe execmd attrib +R "$f"
On the subject of user commands: I often find myself navigating to Custom... User Commands... Organize... and finding that I want to 1) add a new user command, and/or 2) duplicate an existing command and modify it slightly for testing.

In the Custom Color Coding dialog one can modify an existing color coding scheme or add a new one. In User Commands... Organize it would be nice to likewise be able to add a new command without having to close the window and navigate to User Commands... Add new. It's a tiny annoyance, but those of us who work with user commands a lot would benefit from easier command management.
User avatar
nikos
Site Admin
Site Admin
Posts: 16402
Joined: 2002 Feb 07, 15:57
Location: UK

Re: Format of filenames passed to user commands

Post by nikos »

do you know that xplorer2 can set attributes too? press SHIFT+F12 on the selection
diz
Member
Member
Posts: 10
Joined: 2016 Aug 31, 17:02

Re: Format of filenames passed to user commands

Post by diz »

nikos wrote:do you know that xplorer2 can set attributes too? press SHIFT+F12 on the selection
Yes, I do, and it's a wonderful feature. But it still requires interaction with a dialog box (checking, clicking, etc.)

For operations like this I prefer to toggle an attribute on multiple files by selecting them and clicking a user command on the toolbar.
Kilmatead
Platinum Member
Platinum Member
Posts: 4879
Joined: 2008 Sep 30, 06:52
Location: Baile Átha Cliath

Re: Format of filenames passed to user commands

Post by Kilmatead »

diz wrote:For operations like this I prefer to toggle an attribute on multiple files by selecting them and clicking a user command on the toolbar.
Maybe I should add command-line attribute settings to this thing and I'd have more fans. :D Unfortunately for you, it's still just a dialog box, but could be extended easily enough to hide that.

Useful (for now) on the odd chance you would like to retain a detailed log of successful/failed/before/after attributes on up to thousands of individual objects. Some people really like logs of stuff on operations like that. :wink:

And unlike some people, I'm always open to user-suggestions. :lol:
diz
Member
Member
Posts: 10
Joined: 2016 Aug 31, 17:02

Re: Format of filenames passed to user commands

Post by diz »

My Java Alternate Data Stream (ADS) viewer is working. In the unlikely event that other Java geeks are trying to pass files/directories with funky Unicode characters to Java from an x2 user command, as mentioned earlier, use, e.g., $a instead of $A to pass the paths as old-school 8.3 Windows filenames.

To resolve the 8.3 filename to the complete path, convert it as follows

Code: Select all

// sample: Java code to resolve full path from Win 8.3 path
public static void main(String[] args) {
  for (String s: args) {
    Path p83 = Paths.get(s); // path with Win 8.3 filename
    Path fullPath = p83.toRealPath(); // resolve 8.3 to complete path with Unicode chars, etc.
    if (Files.isDirectory(fullPath))
      // walk dir tree recursively
    else // process file
  }
}
diz
Member
Member
Posts: 10
Joined: 2016 Aug 31, 17:02

Re: Format of filenames passed to user commands

Post by diz »

Just ran into a problem. I have a directory named "21 & 22 Jump Street 1080p", with an 8.3 format name of "21&22J~1".

The presence of the ampersand led to the Java program being passed a truncated filename.

The solution was to change the 8.3 format name, replacing the ampersand with an underscore, to "21_22J~1".

Should you ever need to change an existing 8.3 format filename, open a cmd window and type

Code: Select all

fsutil file setshortname <PathName> <shortname>