Run a command line tool on every files and (sub)folders even those containing spaces

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 02:52

Hello,

I would like that to use the shell version of 3-Heights PDF Analysis & Repair (https://www.pdf-tools.com/pdf20/en/prod ... is-repair/) in windows 8.1 64.
I succeed in running it using this command line in DOS ("Command Prompt") :

Code: Select all

for /R "J:\test\PB_006\" %i in (*.pdf) do pdrepair "%i" %~pi%~ni_repared.pdf
Alas this does not work if filenames or foldernames have one or several spaces !
(I was helped by its manual page 10 : https://www.pdf-tools.com/public/downlo ... s/reps.pdf and the FAQ question "How can I use Shell tools to include subdirectories?"
https://www.pdf-tools.com/pdf20/en/supp ... questions/ )

I thought that I bypass the space problem using an autohotkey script. The goal is to select a source folder and a destination folder (usually the same) and run the exe command on every PDF files contained in every folders and subfolders (and optionally adds "_repared.pdf" to the filename. I have tried to modify an old one which gives me this :

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
		ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
		ExitApp

Loop,%SourcePath%\*.*,2,0
{
	FolderSize = 0
	Loop, %A_LoopFileFullPath%\*.pdf, , 1
		FolderSize += %A_LoopFileSize%
	If FolderSize >0
		RunWait,c:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe  "%TargetPath%\%A_LoopFileName%_repared.pdf" "%A_LoopFileFullPath%\*.pdf"
}
		

Alas it loads and close the DOS window very fast and no files are modified or created.

I also tried this with the same result (without "_repared.pdf") :

Code: Select all

		RunWait,c:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe  "%TargetPath%\%A_LoopFileName%_repared.pdf" "%A_LoopFileFullPath%\*.pdf"
Many thanks in advance ;)
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 03:35

Maybe try with quotes around c:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe as well?
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 03:37

Hi deplosm try this

Code: Select all

	If (FolderSize >0) {
	   pCmd := """"  TargetPath "\"  A_LoopFileName "_repared.pdf" """"
	   Run , % "C:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe " pCmd
	}
Donec Perficiam
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 03:50

Hi wolf_II and jmeneses,

Many thanks for your help. I have tried your ideas but alas it doesn't work (it loads and close the DOS window very fast and no files are modified or created.).

Thanks in advance ;)
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 03:55

Put comspec and "/c" or "/k"

Code: Select all

	If (FolderSize >0) {
	   pCmd := """"  TargetPath "\"  A_LoopFileName "_repared.pdf" """"
	   Run % comspec " /c C:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe " pCmd
	}
Donec Perficiam
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 04:22

Thanks jmeneses. ;)
Using /k finally pauses the dos window and gave me this error :
`C:\Program` is not recognized as an internal or external command, operable program or hatch file.
If I try to add a log to my first test :

Code: Select all

If FolderSize >0
		RunWait,c:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe -l J:\test\log.txt "%TargetPath%\%A_LoopFileName%_repared.pdf" "%A_LoopFileFullPath%\*.pdf"
I have this error in the log :
0x00000002 - E - The system cannot find the file specified.
- File: J:\test\PB_ 006\New folder_repared.pdf
I have tried to implement "-l J:\test\log.txt" to your code like this. I may not be too far but it doesn't work, neither create a log file !

Code: Select all

	If (FolderSize >0) {
	   Run , % "C:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe -l J:\test\log.txt " pCmd
	   pCmd := """"  TargetPath "\"  A_LoopFileName "_repared.pdf" """"
	}
Thanks in advance ;)
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 07:17

:headwall: :headwall: :headwall:
I tried to install pdrepair but it asks for license :thumbdown: .
I have several scrpipts with Run comspec for example pdftotext or pdftohtml with parameters directories with spaces

Try putting the parameter "workingdir"

Code: Select all

 Run % comspec " /c"  "pdrepair.exe " pCmd , % "C:\Program Files (x86)\PDF Tools AG\bin"
Donec Perficiam
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 07:52

>pdrepair licence.
Indeed I had to register in order to get a 30 days trial license (registration and download).
https://www.pdf-tools.com/pdf20/en/prod ... is-repair/
Then when you have the choice to download the zip file for your system 32 or 64 bits, the first choice above is a file containing your licence.
Then you have to follow the help file (page 4 of the manual https://www.pdf-tools.com/public/downlo ... s/reps.pdf) in order to configure the "How to set the Environment Variable “Path"".

I have tried your last idea without success :

Code: Select all

	FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
		ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
		ExitApp

Loop,%SourcePath%\*.*,2,0
{
	FolderSize = 0
	Loop, %A_LoopFileFullPath%\*.pdf, , 1
		FolderSize += %A_LoopFileSize%
	If (FolderSize >0) {
	   pCmd := """"  TargetPath "\"  A_LoopFileName "_repared.pdf" """"
	 Run % comspec " /c"  "pdrepair.exe " pCmd , % "C:\Program Files (x86)\PDF Tools AG\bin"
	}
}
	
Thanks in advance ;)
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 08:37

Using MsgBox I found a logical error, I think:
A_LoopFileName refers to the folder's name, not to the file's name. The inner Loop might need braces? I can't really test this, as I have not got pdrepair.exe.

Notice the MsgBox in place of RunWait (for testing).
I marked the spot where I think braces are needed.
I added quotes for the exe file as previously suggested.
I don't know if WorkingDir is still needed after these changes.

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
		ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
		ExitApp

Loop,%SourcePath%\*.*,2,0
{
	FolderSize = 0
	Loop, %A_LoopFileFullPath%\*.pdf, , 1
; <<<< add an opening brace here >>>>
		FolderSize += %A_LoopFileSize%
	If FolderSize >0
		MsgBox, "c:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe" "%TargetPath%\%A_LoopFileName%_repared.pdf" "%A_LoopFileFullPath%\*.pdf"
; <<<< add a closing brace here >>>>
}
I hope that helps.

PS: Is FolderSize needed? Maybe you can get rid of one loop entirely, to make the code easier to follow.
Try this (untested):

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
		ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
		ExitApp

Loop, Files, %SourcePath%\*.pdf, R
		MsgBox, "c:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe" "%TargetPath%\%A_LoopFileName%_repared.pdf" "%A_LoopFileFullPath%"
I hope that helps.
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 08:59

Hi,

Many thanks. ;)

I have tested with or without braces. Please see this image for the error code :
Image

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
		ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
		ExitApp

Loop,%SourcePath%\*.*,2,0
{
	FolderSize = 0
	Loop, %A_LoopFileFullPath%\*.pdf, , 1
{
		FolderSize += %A_LoopFileSize%
	If FolderSize >0
		MsgBox, "c:\Program Files (x86)\PDF Tools AG\bin\pdrepair.exe" "%TargetPath%\%A_LoopFileName%_repared.pdf" "%A_LoopFileFullPath%\*.pdf"
}
}

Many thanks in advance ;)
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 09:18

Try

Code: Select all


WorKingDir := "c:\Program Files (x86)\PDF Tools AG\bin"	      
pdParams := "pdrepair.exe -a "
FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
		ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
		ExitApp

If (SourcePath==TargetPath){
	  Msgbox 0x40000,, % "SourcePath and TargetPath cant be the same "    TargetPath
	 ExitApp
}

Loop, Files, %SourcePath%\*.pdf, R
   {
	 SplitPath, A_LoopFileName, , , , OutNameNoExt
	 pCmd := pdParams """"  SourcePath "\" A_LoopFileName """"  " " """" TargetPath "\" OutNameNoExt "_repared." A_LoopFileExt """"   
	 Run % comspec " /c " pCmd , % WorKingDir
   }
ExitApp

Source and target would not have to be in the same parent directory :facepalm:
Donec Perficiam
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 09:42

Many thanks. ;)

When I test the "PS" part from Hi wolf_II : I have this error (I have removed "_repaired.pdf" for testing as it displayed files with "filename.pdf_repaired.pdf" instead of "filename_repaired.pdf") :
Image


And when I try jmeneses' idea :

Code: Select all

WorKingDir := "c:\Program Files (x86)\PDF Tools AG\bin"	      
pdParams := "pdrepair.exe -l J:\test\log.txt "
FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
		ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
		ExitApp

If (SourcePath==TargetPath){
	  Msgbox 0x40000,, % "SourcePath and TargetPath cant be the same "    TargetPath
	 ExitApp
}

Loop, Files, %SourcePath%\*.pdf, R
   {
	 SplitPath, A_LoopFileName, , , , OutNameNoExt
	 pCmd := pdParams """"  SourcePath "\" A_LoopFileName """"  " " """" TargetPath "\" OutNameNoExt "_repared." A_LoopFileExt """"   
	 Run % comspec " /c " pCmd , % WorKingDir
   }
ExitApp
I have suceeded in creating a repaired pdf file. :bravo: ;) But only the one in the root folder (from J:\test\02.pdf to J:\test_destination_folder\02_repared.pdf)

For the second pdf file I have this error in my log.txt file :
0x00000002 - E - The system cannot find the file specified.
- File: J:\test\8.pdf
I assume this is because the file is in fact inside a folder with space :
J:\test\New Folder\8.pdf

Edit: I just tested jmeneses' idea with 2 different files inside the root folder J:\test\ and only the new one was repaired. If I add RunWait instead of Run, it works fine for both files in the root. ;) The one inside the subfolder with a space doesn't work.

Many thanks in advance ;)
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 10:14

Code: Select all

Loop, Files, %SourcePath%\*.pdf, R
   {
	 SplitPath, A_LoopFileFullPath, , , , OutNameNoExt
	 pCmd := pdParams """"  A_LoopFileFullPath """"  " " """" TargetPath "\" OutNameNoExt "_repared." A_LoopFileExt """"   
	 Run % comspec " /c " pCmd , % WorKingDir
   }

Donec Perficiam
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

13 Jan 2017, 10:37

Many thanks jmeneses. ;)

When I add RunWait instead of Run in your code it repaired all files (even those with filenames containing spaces) :bravo: ;)
Otherwise I can see very fast, I guess as many DOS windows as I have pdf files, appear and disappear. Then it creates only one pdf repared file.

The only thing is that the file contained inside the subfolder was put in the destination root.
Source list of files :
J:\test\02.pdf
J:\test\New Folder\8.pdf

Destination results :
J:\test2\02_repared.pdf
J:\test2\8_repared.pdf (instead of J:\test\New Folder\8.pdf)

(I don't know if this helps but it appears to me that the log.txt is created several times upon itself. It doesn't append each new file repared one after the other, it just list the result of the last file repared)

Thank you so much by advance ;)
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: Run a command line tool on every files and (sub)folders even those containing spaces

16 Jan 2017, 03:37

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
	   ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
	   ExitApp

If (SourcePath==TargetPath){
	Msgbox 0x40000,, % "SourcePath and TargetPath cant be the same "    TargetPath
	ExitApp
}

pdParams := "pdrepair.exe -l " """" TargetPath "\LOG.txt" """"   
WorKingDir := "c:\Program Files (x86)\PDF Tools AG\bin"	      
RunWait % comspec " /c xCopy """ SourcePath A_loopField """ """ TargetPath A_loopField """ /s /i /y",, Hide 
FileDelete, % A_Temp "\LOG_pdrepair.txt"   

Loop, Files, % TargetPath "\*.pdf" , R
   {        
   SplitPath, A_LoopFileFullPath, name, dir, ext, name_no_ext
   outPDF_repared :=  dir "\" name_no_ext "_repared" "."  ext
   pCmd := pdParams " " """"  A_LoopFileFullPath """"  " " """" outPDF_repared """"   
   RunWait % comspec " /c " pCmd , % WorKingDir , Hide
   FileAppend, % "Result pdrepair`n" outPDF_repared "`n", % A_Temp "\LOG_pdrepair.txt"
   FileRead, outLOG, % TargetPath "\LOG.txt"
   FileAppend, % outLOG "`n" , % A_Temp "\LOG_pdrepair.txt"
   FileDelete, % A_LoopFileFullPath
   }                              

Msgbox 0x40000,, % "END!",1                                            
Run %  A_Temp "\LOG_pdrepair.txt"
ExitApp
Donec Perficiam
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

16 Jan 2017, 05:50

Wow jmeneses ! Many thanks ! ;) It works great. :bravo: I much appreciated. ;)

Just in case, I have tried to adapt your great code so it doesn't create a log.

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
	   ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
	   ExitApp

If (SourcePath==TargetPath){
	Msgbox 0x40000,, % "SourcePath and TargetPath cant be the same "    TargetPath
	ExitApp
}

pdParams := "pdrepair.exe -l " """" TargetPath """"   
WorKingDir := "c:\Program Files (x86)\PDF Tools AG\bin"	      
RunWait % comspec " /c xCopy """ SourcePath A_loopField """ """ TargetPath A_loopField """ /s /i /y",, Hide 
FileDelete, "   

Loop, Files, % TargetPath "\*.pdf" , R
   {        
   SplitPath, A_LoopFileFullPath, name, dir, ext, name_no_ext
   outPDF_repared :=  dir "\" name_no_ext "_repared" "."  ext
   pCmd := pdParams " " """"  A_LoopFileFullPath """"  " " """" outPDF_repared """"   
   RunWait % comspec " /c " pCmd , % WorKingDir , Hide
   FileDelete, % A_LoopFileFullPath
   }                              

ExitApp
Obviously I did something wrong! No problem if you can't. I am so very happy already. ;)

Thank you again sooo much. ;)
User avatar
jmeneses
Posts: 524
Joined: 28 Oct 2014, 11:09
Location: Catalan Republic

Re: Run a command line tool on every files and (sub)folders even those containing spaces

16 Jan 2017, 06:02

delete this line

Code: Select all

FileDelete, "   
Donec Perficiam
deplos
Posts: 9
Joined: 13 Jan 2017, 02:34

Re: Run a command line tool on every files and (sub)folders even those containing spaces

16 Jan 2017, 08:14

Many thanks again jmeneses. :clap: I much appreciated your great help. ;)

As a summary, here are the final codes :

1)
It works for files and folders which contains spaces. It also copy correctly the folder structure of the source inside the destination. And it displays at the end a log file of what has been done. ;)

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
	   ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
	   ExitApp

If (SourcePath==TargetPath){
	Msgbox 0x40000,, % "SourcePath and TargetPath cant be the same "    TargetPath
	ExitApp
}

pdParams := "pdrepair.exe -l " """" TargetPath "\LOG.txt" """"   
WorKingDir := "c:\Program Files (x86)\PDF Tools AG\bin"	      
RunWait % comspec " /c xCopy """ SourcePath A_loopField """ """ TargetPath A_loopField """ /s /i /y",, Hide 
FileDelete, % A_Temp "\LOG_pdrepair.txt"   

Loop, Files, % TargetPath "\*.pdf" , R
   {        
   SplitPath, A_LoopFileFullPath, name, dir, ext, name_no_ext
   outPDF_repared :=  dir "\" name_no_ext "_repared" "."  ext
   pCmd := pdParams " " """"  A_LoopFileFullPath """"  " " """" outPDF_repared """"   
   RunWait % comspec " /c " pCmd , % WorKingDir , Hide
   FileAppend, % "Result pdrepair`n" outPDF_repared "`n", % A_Temp "\LOG_pdrepair.txt"
   FileRead, outLOG, % TargetPath "\LOG.txt"
   FileAppend, % outLOG "`n" , % A_Temp "\LOG_pdrepair.txt"
   FileDelete, % A_LoopFileFullPath
   }                              

Msgbox 0x40000,, % "END!",1                                            
Run %  A_Temp "\LOG_pdrepair.txt"
ExitApp
2) same version than above but without the log file.

Code: Select all

FileSelectFolder,SourcePath,,0,Select Source Folder
	If SourcePath =
	   ExitApp

FileSelectFolder,TargetPath,*%SourcePath%,0,Select Target Folder
	If TargetPath =
	   ExitApp

If (SourcePath==TargetPath){
	Msgbox 0x40000,, % "SourcePath and TargetPath cant be the same "    TargetPath
	ExitApp
}

pdParams := "pdrepair.exe "  
WorKingDir := "c:\Program Files (x86)\PDF Tools AG\bin"	      
RunWait % comspec " /c xCopy """ SourcePath A_loopField """ """ TargetPath A_loopField """ /s /i /y",, Hide 
 

Loop, Files, % TargetPath "\*.pdf" , R
   {        
   SplitPath, A_LoopFileFullPath, name, dir, ext, name_no_ext
   outPDF_repared :=  dir "\" name_no_ext "_repared" "."  ext
   pCmd := pdParams " " """"  A_LoopFileFullPath """"  " " """" outPDF_repared """"   
   RunWait % comspec " /c " pCmd , % WorKingDir , Hide
   FileAppend, % "Result pdrepair`n" outPDF_repared "`n", % A_Temp "\LOG_pdrepair.txt"
   FileRead, outLOG, % TargetPath "\LOG.txt"
   FileAppend, % outLOG "`n" , % A_Temp "\LOG_pdrepair.txt"
   FileDelete, % A_LoopFileFullPath
   }                              

Msgbox 0x40000,, % "END!",1                                            

ExitApp
Thank you again. ;)

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: marypoppins_1, OrangeCat, RussF and 131 guests