Disclaimer: While i am offering a possible approach here, note that i strongly agree with Horst.Epp, and like to discourage you from utilizing such file names. But then again, it is not me who risks wallowing in pain when faced with other problems caused by such unusual file names down the road, so why should i care? And if you have no other choice than to work with such file names, well, you will have to endure...
It is also worth menitoning that i only address the issue of quoted items in the list file here. I haven't tested with file names starting with a white-space, so i can't say whether quoting such file names in the list file will make 7z work as desired. That's up to you to test and figure out...
Unless you are running a very old Windows OS, you can utilize a Powershell script to preprocess the file list and surround the items within it with double quotes. Here the "pure", readable PS script:
Code: Select all
$l = Get-Content <PathToListFile>
$l | ForEach-Object {$_ -replace '^"?|(?<!")$', '"'} | Set-Content <PathToListFile>
& <PathTo7z.exe> a <PathArchiveFile> @<PathToListFile>
(The arguments with <...> are just placeholders for the actual values that have to be inserted there)
The script is rather straight-forward. It reads the content of the list file into a variable ($l). Then it goes through the items of the list, doing some regex replacement (which there is a particular reason of why it looks that way; explanation below) to make sure each item is being surrounded by double-quotes and writes the items back into the same list file (overwriting it). Finally, it starts the 7z process.
Now, you either can turn this into a script file. Or, if you don't like having a separate script file lying around, you can pass these script commands as part of Powershell.exe's command line and thus encapsulating the whole shebang within the parameter field of a TC button.
I am going to do the latter and encapsulate the script in the parameter field of a TC button. Not because it is fun, but because of Windows' mildy flustercucked command line processor (which it is since decades, and everyone has to deal with it).
The button should be setup like this:
Command:
Parameters:
Code: Select all
-Command "&{$l = Get-Content '%UL'; $l | ForEach-Object {$_ -replace '^\"?\"?|(?<!\")$', '\"'} | Set-Content '%UL'; & '<PathTo7z.exe>' a '<PathArchiveFile>' '@%UL'}"
Note me using TC's variable %UL in place of <PathToListFile>.
Don't forget to replace <PathArchiveFile> with the path of the target archive to create/to be updated, and <PathTo7z.exe> with the real path to your 7z.exe. If the path contains spaces,
do not use double-quotes here. Instead, keep the single-quotes i have already there in the script. (Powershell itself will recognize the single-quoted string containing spaces correctly. And by using single-quotes you don't risk upsetting the command-line processor.)
You might also want to modify the arguments for the 7z.ex invocation according to your needs. If you need to quote some argument because it contains a space, just use single-quotes within the script, not double-quotes. Not only do single-quotes not interfere with the command line processor, but in Powershell a single-quoted string is different from a double-quoted string. A double-quoted string in Powershell will also do variable expansion. Variables in PS begin with a "$" character. So, if by chance any of your arguments happen to contain a "$" character, double-quoting such an argument will trigger an variable expansion attempt, and thus quite likely changing the argument in unforeseen ways.
Okay. That doesn't look as tidy as the pure script above. It looks rather messy. Well, that's life. If you are interested in some explanations, read on. If not, you can tune out now, just use what i wrote above, and pray that i didn't make any mistake.
You are still here? Alright... To pass the script to Powershell.exe, i'll use this argument syntax:
Code: Select all
powershell.exe -Command "&{Script}"
The obvious problem of passing the script as part of the command line for Powershell is two-fold here with my script. It uses double-quote, circumflex (^) and pipe (|) and redirection (<) characters that normally are processed as part of the command line handling outside of double-quoted argument strings. Additionally, if you count the double-quotes in the script, you will notice the odd/uneven count. This imbalance can and will screw up the command line processing if not addressed. (Oh, and for whatever reason you will need to escape the double-quotes within the script with backslashes when passing the script via command line, otherwise Powershell will protest. Don't ask me why, i have no enthusiasm to figure out the reasons behind this
)
To balance the double-quotes, i will abuse the regex '^"?|(?<!")$' in my script (that is actually the "sneaky" reason why i employed a regex). This regex pattern simply matches the beginning of the string including an optional double-quote directly at the beginning of the string, or it matches the end of the string if the last character in the string is not a double-quote. Together with the replacement you can see in the script, this will result in a string always having a double-quote at the beginning and end. Now, we can keep this regex replacement essentially working the same by just expanding the regex pattern to match a (pointless) second optional double-quote at the beginning of the string: '^"?"?|(?<!")$'. Slightly stupid, but it adds a double-quote character to the script, and now the script features an even number of double-quote characters. Yay, the command line processor is happy now. (Dear reader, would you like an Aspirin?)
On to the circumflex and the pipe characters. Luckily, we get lucky here. If you follow the sequence of opening double-quotes to the next closing double-quote and so on, you'll notice that both the circumflex and the pipe characters are enclosed within double-quoted blocks as far as the command line processor is concerned. This will make the command line processor happy and we don't need to escape the circumflex and the pipe characters. Phew, dodged a bullet there...