I tried to automate archiving folders inside a directory with Winrar through Windows 10 command line either by Python or VBA codes. Considering that there might be spaces, I enclosed all paths in quotations.
However I ran in to the same error in both Python or VBA;
" 'C:/Program' is not recognized as an internal or external command, operable program or batch file."
Here is a sample uncompleted Python code attempt;
def folders_2_Winrar(source_path:str, archive_path:str, password:str='', winrar_path:str='"C:/Program Files/WinRAR/winrar.exe"')->None:
import os
folder_list = path_entries(source_path)['folders'] ## separate function that returns a list of folders in a directory
for f in folder_list:
rar = '"' archive_path os.path.basename(f) '.rar' '"'
f = r'"' f '\*.*"'
cmd = winrar_path ' a -hp' password ' -ep1 ' rar ' ' f
os.system(cmd)
# test the function
folders_2_Winrar("E:/Test/Source", "E:/Test\\Archive/","123")
what's the problem I could not grasp??!!
CodePudding user response:
Short answer: Use a shorthanded version of the full path: "C:/Progra~1/WinRAR/winrar.exe"
Longer answer: Command prompts don't like space in between paths. Usually within the prompt itself you will need to use quotation marks to signify the full path that contains space, or use a shorthand convention of the ~1 (tilde notation).
Here is a web archived Microsoft knowledge base that I dug up, which I'll include here as a copy in case it goes down:
Windows generates short file names from long file names in the following manner:
Windows deletes any invalid characters and spaces from the file name. Invalid characters include:
. " / \ [ ] : ; = ,
Because short file names can contain only one period (
.
), Windows removes additional periods from the file name if valid, non-space characters follow the final period in the file name.For example, Windows generates the short file name
Thisis~1.txt
from the long file nameThis is a really long filename.123.456.789.txt
Otherwise, Windows ignores the final period and uses the next to the last period. For example, Windows generates the short file name
Thisis~1.789
from the long file nameThis is a really long filename.123.456.789.
Windows truncates the file name, if necessary, to six characters and appends a tilde (
~
) and a digit. For example, each unique file name created ends with "~1
." Duplicate file names end with "~2
," "~3
," and so on.Windows truncates the file name extension to three characters or less.
Windows translates all characters in the file name and extension to uppercase.
Note that if a folder or file name contains a space, but less than eight characters, Windows still creates a short file name. This behavior may cause problems if you attempt to access such a file or folder over a network. To work around this situation, substitute a valid character, such as an underscore (
_
), for the space. If you do so, Windows does not create a different short file nameFor example, "
Afile~1.doc
" is generated from "A file.doc
" because the long file name contains a space.No short file name is generated from "
A_file.doc
" because the file name contains less than eight characters and does not contain a space.The short file name "
Alongf~1.txt
" is generated from the long file name "A long filename.txt" because the long file name contains more than eight characters.
Alternative answer: you can try adding quotes in the cmd
that you intend to run:
# using f-strings for Python 3.6
cmd = f'"{winrar_path}" a -hp {password} -ep1 {rar} {f}'
# or using good ol' format:
cmd = '"{path}" a -hp {pw} -ep1 {file} {fl}'.format(path=winrar_path, pw=password, file=rar, fl=f)
CodePudding user response:
Dont have the full answer. But i can get it to run by just removing the quotations in the for loop. Seems like the string path must be encapsulated with quotations when it has spaces. And not when it does not.
def folders_2_Winrar(source_path:str, archive_path:str, password:str='', winrar_path:str='"C:\Program Files\WinRAR\winrar.exe"')->None:
import os
folder_list = path_entries(source_path)['folders'] ## separate function that returns a list of folders in a directory
for f in folder_list:
rar = archive_path os.path.basename(f) '.rar'
f = f '\*.*'
cmd = winrar_path ' a -hp' password ' -ep1 ' rar ' ' f
os.system(cmd)
# test the function
folders_2_Winrar("E:/Test/Source", "E:/Test\\Archive/","123")