Simpel

[Solved] FileCopy + PDFtk takes very long time

8 posts in this topic

#1 ·  Posted (edited)

Hi,

I do recognize bad behaviour at this snippet:

#include <AutoItConstants.au3>
Global $g_sSD = @ScriptDir & "\"
Global $g_sBurstPath = $g_sSD & "Burst\"
DirCreate($g_sBurstPath)
Local $sFileName = "Test_mit_3_Seiten.pdf" ; any PDF with more than 1 page inside @ScriptDir

FileCopy($g_sSD & $sFileName, $g_sBurstPath & $sFileName, 1)
;~ Sleep(13000)
Local $hTimer = TimerInit()

ConsoleWrite("Start" & @CRLF)
_Burst($g_sBurstPath & $sFileName) ; bursts PDF into single pages
;~ While _FileInUse($g_sBurstPath & $sFileName)
;~  WEnd
ConsoleWrite("End: " & Round(TimerDiff($hTimer)) & "ms" & @CRLF)

Exit

Func _quotePath($sPath) ; because of possible "spaces" inside pathes
    $sPath = '"' & $sPath & '"'
    Return $sPath
EndFunc

Func _Burst($sFile)
    Local $sPDFtk = $g_sSD & "pdftk.exe" ; path to pdftk.exe (and libiconv2.dll)
    Local $sCurrWorkingDir = @WorkingDir
    FileChangeDir($g_sBurstPath) ; it has to change for reasons
    Local $iPID = Run(_quotePath($sPDFtk) & ' ' & _quotePath($sFile) & ' burst', "", @SW_SHOW, $STDOUT_CHILD + $STDERR_CHILD) ; @SW_SHOW just to see "PDFtk is working"
    Local $sOutput, $sError
    While 1
        $sOutput &= StdoutRead($iPID)
        $sError &= StderrRead($iPID)
        If @error Then ExitLoop
        Sleep(10)
    WEnd
    FileChangeDir($sCurrWorkingDir) ; back to normal
EndFunc

Func _FileInUse($sFilename) ; by Siao
    Local $aRet, $hFile
    $aRet = DllCall("Kernel32.dll", "hwnd", "CreateFile", _
                                    "str", $sFilename, _ ;lpFileName
                                    "dword", 0x80000000, _ ;dwDesiredAccess = GENERIC_READ
                                    "dword", 0, _ ;dwShareMode = DO NOT SHARE
                                    "dword", 0, _ ;lpSecurityAttributes = NULL
                                    "dword", 3, _ ;dwCreationDisposition = OPEN_EXISTING
                                    "dword", 128, _ ;dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL
                                    "hwnd", 0) ;hTemplateFile = NULL
    $hFile = $aRet[0]
    If $hFile = -1 Then ;INVALID_HANDLE_VALUE = -1
        $aRet = DllCall("Kernel32.dll", "int", "GetLastError")
        SetError($aRet[0])
        Return 1 ; file in use (@error contains system error code)
    Else
        ;close file handle
        DllCall("Kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
        Return 0 ; file not in use
    EndIf
EndFunc

This bursting took about 15000ms. If I activate line 8 "Sleep(13000)" then the bursting itself never needed more than 1000ms. Round about 13000ms delay is needed until bursting is acting very fast, otherwise needing about 15000ms.

Then I tested _FileInUse() instead of _Burst() w/o Sleep(13000). This runs in 3ms. It seemes to me that FileCopy() and Burst() are interacting in a way I can't see.

Any ideas? Regards, Conrad

P.S. You need pdftk.exe and libiconv2.dll at @ScriptDir. This you can get free here: https://www.pdflabs.com/tools/pdftk-server/ (I'm not sure whether I'm allowed to attach it here).

 

Edited by Simpel
english remarks at code + [Solved]

SciTE = 3.6.2.0/full   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win7Pro SP1   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE   H:\...\AutoIt3   H:\...\AutoIt3\Include   H: = Network Drive

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Share this post


Link to post
Share on other sites



#2 ·  Posted

Hi,

instead of FileCopy() I tested:

_WinAPI_CopyFileEx($g_sSD & $sFileName, $g_sBurstPath & $sFileName)

Same result. What is disturbing burst()?

Regards, Conrad


SciTE = 3.6.2.0/full   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win7Pro SP1   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE   H:\...\AutoIt3   H:\...\AutoIt3\Include   H: = Network Drive

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Share this post


Link to post
Share on other sites

#3 ·  Posted

Puh,

this is only happening on network drives. I copied all files for testing to local c: and it works fast as it should.

But I have no chance to let run this script in real life on a local disk.

Conrad


SciTE = 3.6.2.0/full   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win7Pro SP1   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE   H:\...\AutoIt3   H:\...\AutoIt3\Include   H: = Network Drive

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Share this post


Link to post
Share on other sites

#4 ·  Posted

Hello. I've tested with many pdfs and everything is working right about 250 ms for a 10 page pdf file. 

 

Saludos

Share this post


Link to post
Share on other sites

#5 ·  Posted

Hi,

even starting the script from an external usb drive is fast. So it seems to be bad only on network drives.

@Danyfirex: Did you try it at a network drive?

Conrad


SciTE = 3.6.2.0/full   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win7Pro SP1   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE   H:\...\AutoIt3   H:\...\AutoIt3\Include   H: = Network Drive

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Share this post


Link to post
Share on other sites

#6 ·  Posted

No just in my local drive.

Saludos

Share this post


Link to post
Share on other sites

#7 ·  Posted

Issue seems to be related to UNC paths. But I'm have no time to check deeply. Consider to do something like this.


 
;~ #RequireAdmin

;My paths
Local $sFileName="10page.pdf"
Local $sTempDir=@TempDir & "\TempPDFTK\"
Local $sPDFTKPath=@ScriptDir & "\pdftk.exe"
Local $sDirBurst=@ScriptDir & "\Busrt\"

;just for delete all
DirRemove($sDirBurst) ;delete  the burst out files path
DirRemove($sTempDir)  ;delete the temp folder

;Create Directories
If not FileExists($sTempDir) Then DirCreate($sTempDir)
If not FileExists($sDirBurst) Then DirCreate($sDirBurst)

;build path and run PDFTk.exe
Local $sFileFromPath=@ScriptDir & "\" & $sFileName
Local $sFileToPath=$sTempDir & $sFileName
FileCopy($sFileFromPath,$sFileToPath,1)
Local $iExitCode=RunWait(_quotePath($sPDFTKPath) & " " & _quotePath($sFileToPath) & ' burst',$sTempDir,@SW_SHOW)
FileMove($sTempDir & "*.*",$sDirBurst,1) ;move temp files to my burst directory
DirRemove($sTempDir) ;delete temp folder
Exit

Saludos

1 person likes this

Share this post


Link to post
Share on other sites

#8 ·  Posted

Hi.

Now I could implement the idea of @Danyfirex and use the @TempDir. That leads to a local drive.

Thanks for helping and regards, Conrad


SciTE = 3.6.2.0/full   AutoIt = 3.3.14.2   AutoItX64 = 0   OS = Win7Pro SP1   OSArch = X64   Language = 0407/german
H:\...\AutoIt3\SciTE   H:\...\AutoIt3   H:\...\AutoIt3\Include   H: = Network Drive

   88x31.png  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • fopetesl
      By fopetesl
      Struggling to get Filecopy() working
      MsgBox(0,"Moving file: ", $fLine) ; C:\AlmeterS3\AI74_No2.csv FileCopy( $fLine, "C:\AlmeterS3\S3_Database\") ; FileCopy( $fLine, $BatchDir & "\S3_Database\") If @error Then MsgBox($MB_SYSTEMMODAL, "ERROR!", "database write error " & @error) EndIf FileDelete( $fLine) doesn't copy only creates a file "C:\AlmeterS3\S3_Database" (actually AI74_No2.csv)
      Again my typo I should have added
      $FC_OVERWRITE + $FC_CREATEPATH since folder didn't actually exist.
    • LOWLIFE
      By LOWLIFE
      This is a personal project to log into several facebook accounts and send a message to a specific person on their birthday. I need to stop a script in a few different ways for several different reasons. For example, it might start sending the email to the wrong account, it might do something other than send a message, it might fail to logout of one account, etc. 
      1) Pause the script at it's exact location with a resume feature in case I need to put it on hold while I do another task. 
      2) Pause the script at it's current location with the option to start over or execute another part of the script (example in GUI with multiple buttons). 
      Also, is there a way to interact with menus? If I log into facebook how can I force it to go straight to sending a message to the proper person? I tried automating a mouseclick but the window opens in different places. I also tried searching for specific text and I couldn't get any information from the windows info tool on the facebook page. 
      Also, how do I get my code in here to show like it does in my editor? (scite)
      Thanks for looking at it, and any help/suggestions I sgreatly appreciated!
      <snip>
    • joseLB
      By joseLB
      Suppose you want from time to time to update a destination folder  with new files that where created at a origin folder.
      It´s a kind of synchronization, where new files in origin must be "added" to destination. No worry about files that changed, just the new ones.
      The natural way:   FileCopy  ($originFolder  &  "\*.*"   ,   $destinationFolder  , $FC_NOOVERWRITE)
      After many tests, where I have 300 .jpg files in origin and no subfolders:
      If there is nothing at destination => OK, copy  is done. Now destination has 300 files. If I erase at destination 10 files in the middle (explorer, shift del)  and then filecopy =>  the 10 deleted files are NOT copied !! If I erase at destination 10 files "at the beginning"* (explorer, shift del)  and then filecopy =>  the 10 deleted files are copied !! = OK !! * "at beginning" = sorted by name, ascending, erase the 10 first ones.
      ** I tried $originFolder  &  "\*.*" , $originFolder&"\"  ,  $originFolder , and many other variants. The same for destination.
      So, what´s seems to me is that  when FileCopy finds the first file from origin  that exists at destination it stops to search.  That´s expected behavior?
      Best Regards
      Jose
    • Xulong
      By Xulong
      I have a script which is copying one file (the latest file among a bunch of structured folders) from one network device to another network device.
      The weird thing is the file copied successfully to the destination folder right after the FileCopy command ran but the script is hanging for another few minutes until it return with exit code 0.
      Below is my script:
      #include <MsgBoxConstants.au3> #include <File.au3> #include <Array.au3> #include <FileConstants.au3> copyfile() Func copyfile() Local $testLogFile = FileOpen(@ScriptDir & "\CopyMSI", 1) Local $BuildArtifacts = "\\vm-build\BuildArtifacts" Local $dServer = "\\VM-DEV\c$\Users\Administrator\Desktop" Send("#r") WinWaitActive("Run") ControlSend("Run", "", 1001, $BuildArtifacts) ControlClick("Run", "OK", 1) _FileWriteLog($testLogFile, "Opened Builds folder") ;trying to get the latest build folder and grab the latest msi file for copying WinWaitActive("BuildArtifacts") Local $FolderList = _FileListToArray($BuildArtifacts, "Grand-4.*") _ArraySort($FolderList, 1) Local $latestSEbuild = $FolderList[0] Sleep (5000) WinClose("BuildArtifacts") Local $sServer = $BuildArtifacts & '\' & $latestSEbuild & '\G4.msi' ; start copying file from build to destination folder FileCopy($sServer, $dServer, $FC_OVERWRITE) _FileWriteLog($testLogFile, "Copied MSI") EndFunc  
    • PINTO1927
      By PINTO1927
      Hello guys,
      I'm working on this script:
      Case $BTN Global $URL = FileOpenDialog("IMPORT FILE", $DESKTOP, "ALL FORMAT (*)", 4) $DIR_DEST = "C:\DIR-WORK\list\IMPORT_DOC\" DirCreate($DIR_DEST) Local $LINE For $t = 1 To $URL[0] _FileReadToArray($URL[$t], $LINE) For $u = 1 To $LINE[0] FileCopy($URL[$u], $DIR_DEST) Next Next the selected files via OpenFileDialog must be copied to the folder $DIR_DEST.