Jump to content

how to determine is a file is open by another program


Dana
 Share

Recommended Posts

This one has me stumped.

I'm working on a routine that, among other things, exports a .pdf file from KeyCreator (a CAD package). I can do that part no problem, but I've been unable to determine when the pdf export process is done.

I use Send to start the pdf export, WinWaitActive to wait for the "Save As" dialog, stuff the desired filename into the dialog, click OK, etc., but then I need to wait until the export is complete before continuing. Unfortunately, once the "save as" dialog closes, there is nothing in the main KeyCreator window that's visible to indicate that the export process is still running or complete (there is a visible text on the screen, but the AutoIt window info doesn't see it; presumably it's a non standard window).

The next step is to open the pdf file in Acrobat reader or other program, using ShellExecute with the pdf filename. However, ShellExecute returns 1 whether or not the file opens. Same for Run. I'm guessing that the returned 1 is coming from Foxit Reader (which I'm using in place of Acrobat Reader) since the reader opened successfully, but Foxit reports "file not found".

I've tried looking at the output file itself. FileExists doesn't work because it's created as soon as the export process starts. I tried "Open" in binary mode, but it always returns an error even if the export is complete.

At this point the only way I can get the program to work is to use a message box for the operator to close after he sees the export process is done. Then everything works, but it's not a good solution.

What I need is a way for AutoIt to determine if another program has a file open, but I can't find it. Any suggestions

Link to comment
Share on other sites

  • Moderators

Dana,

A quick Search (the facility is at top right of the page :P ) threw up this. I hope it is of some use. :x

M23

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

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

; FileInUse with Info using WMI

; example one with process
Local $proc = "AutoIt3.exe"
Local $rtn = FileInUseInfo($proc, 1)
If (Not @error) And $rtn Then MsgBox(0, 'FileInUseInfo(' & $proc & ', 1)', $rtn)

; example two with file
Local $file = @ScriptName
Local $rtn = FileInUseInfo($file, 2)
If (Not @error) And $rtn Then MsgBox(0, 'FileInUseInfo(' & $file & ', 2)', $rtn)


;##############################################################################################
; FileInUseInfo - Modify it for your needs
;
; example $mode = 1; FileInUseInfo("AutoIt3.exe", 1) ;returns file(s) used by process
;
; example $mode = 2; FileInUseInfo("SomeFile.txt", 2) ;returns process(s) using file
;##############################################################################################
Func FileInUseInfo($sInput, $mode = 1, $strComputer = "localhost")
    Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    If @error Then Return SetError(-1)
    Local $output = '', $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", 0x10 + 0x20)
    If Not IsObj($colItems) Then Return SetError(-2)
    For $objItem In $colItems
        If $objItem.CommandLine = '' Or StringLeft($objItem.CommandLine, 1) = '\' Then ContinueLoop
        If $mode = 1 And $objItem.Name = $sInput Then
        ElseIf $mode = 2 And StringInStr($objItem.CommandLine, $sInput) Then
        Else
            ContinueLoop
        EndIf
        $output &= "PID: " & $objItem.ProcessId & @CRLF
        $output &= "CommandLine: " & $objItem.CommandLine & @CRLF & @CRLF
    Next
    Return $output
EndFunc

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

  • 9 years later...

Ya, this is an old topic, but the closest one i could find that matches my problem.

How can I tell if a file is being used by another application.

Melba's link is dead. 

Ripdad's code looked promising, but failed.

When i used Ripdad's code as is, it worked, but when i changed the $file from @Scriptname, to a .txt file that was also open in autoit (same directory), it not only did not detect the file was open, it took about 22 seconds to quietly quit.

Surely the OS must know if a file is open, and autoit surely must have a way of asking :)

Link to comment
Share on other sites

I think this is because text files don't have a file lock on them. You can edit and delete text files even when they are open in other applications. Try doing this with a different type of file, surely your final goal isn't to determine if a text file is open, right?

All my code provided is Public Domain... but it may not work. ;) Use it, change it, break it, whatever you want.

Spoiler

My Humble Contributions:
Personal Function Documentation - A personal HelpFile for your functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager
InputBoxes - Simple Input boxes for various variable types

Link to comment
Share on other sites

Actually it is, a bunch of data packed into a Single String, i'm using FileGetTime to detect when a file changes, but i was unsure if the file was flushed, or being written to when i read the file.  I'm getting weird results sometimes, and what appears to data that is not different as expected.

I guess i'll have to find some strategy, like read it twice over a few seconds to compare it. It's not big.

Edited by LeCarre
Link to comment
Share on other sites

WaitForFileReady('c:\test.txt')
MsgBox(0, 'OK', 'now file is ready ...')

Func WaitForFileReady($filename, $sleeptime = 300)
    While 1
        $file = FileOpen($filename, 1)
        If $file <> -1 Then 
            FileClose($file)
            ExitLoop
        EndIf
        Sleep($sleeptime)
    WEnd
EndFunc

 

Link to comment
Share on other sites

40 minutes ago, LeCarre said:

read it twice over a few seconds to compare it

That doesn't prevent the situations where another process either isn't finished writing the file or reopens the file once you've read it twice (your mods will be flushed when the other process rewrites the file).

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

i put this is a script and compiled it...

$file=FileOpen("test.tmp",1)
$x=0

while($file)


    FileWrite($file,Random(1,9999999,1))
    $x+=1
    sleep(10)

    if $x=999 then ExitLoop


WEnd


FileClose($file)

MsgBox('','','done',10)

then i put this into a different script and ran them both at the same time....

#include <WinAPIProc.au3>
#include <WinAPI.au3>

$file=FileOpen("test.tmp",1)
$x=0

$mutex=_WinAPI_CreateMutex($file,false)

_WinAPI_WaitForSingleObject($mutex,-1)

while($file)


    FileWrite($file,"abcd")
    $x+=1
    sleep(10)

    if $x=999 then ExitLoop

WEnd

_WinAPI_CloseHandle($mutex)
FileClose($file)

It waited until the first file was finished to start writing.  Not sure if the program you're using that is competing would react the same way but for this basic test it works just fine.  

edit i even tested it with the first program not doing anything just sleeping with the file open and it the mutex still opened and wrote to the file. I have one more thing i want to test

edit: Ya even if i try to force the created mutex to take initial ownership of the object it still waits for the other to finish writing b4 proceeding.  Pretty nifty.

Edited by markyrocks
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...