check if a file is locked, without locking it

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

check if a file is locked, without locking it

01 Feb 2017, 10:39

I want to be able to check if a file is locked, without locking it.
I tested the following 3 functions on Notepad (Windows 7)
and MS Paint (Windows XP version copied to Windows 7),
to check if saving is in progress, however, sometimes
the functions seemed to impede saving.

Notepad error message:
The process cannot access the file because it is being used by another process.

MS Paint error message:
A sharing violation occurred while accessing C:\MyImage.png.

Warning: be careful when using FileOpen,
because you could overwrite a file's data,
thus use a test file rather than an important file.

Code: Select all

q::
vPath = C:\MyImage.png.
Loop
{
if JEE_FileGetIsLocked(vPath)
MsgBox % "file is locked"

if (A_Index = 500000)
break
}
MsgBox % "done"
Return

;==================================================

JEE_FileGetIsLocked(vPath)
{
oFile := FileOpen(vPath, "r -w")
if IsObject(oFile)
Return 0, oFile.Close() ;unlocked
else
Return 1 ;locked

Return
}

;==================================================

JEE_FileGetIsLocked3(vPath)
{
if !(oFile := FileOpen(vPath, "r-rwd"))
Return 1 ;locked
else
Return 0, oFile.Close() ;unlocked

Return
}

;==================================================

JEE_FileGetIsLocked2(vPath)
{
static GENERIC_WRITE:=1073741824,GENERIC_READ:=2147483648,FILE_SHARE_WRITE:=2,OPEN_EXISTING:=3,FILE_ATTRIBUTE_NORMAL:=128,INVALID_HANDLE_VALUE:=-1

;GENERIC_WRITE := 1073741824
;GENERIC_READ := 2147483648
;FILE_SHARE_WRITE := 2
;OPEN_EXISTING := 3
;FILE_ATTRIBUTE_NORMAL := 128
;INVALID_HANDLE_VALUE := -1

;GENERIC_ACCESS := 268435456
;EXCLUSIVE_ACCESS := 0
;OPEN_EXISTING := 3

;both versions work
hFile := DllCall("CreateFile", Str,vPath, UInt,GENERIC_WRITE, UInt,FILE_SHARE_WRITE ,Ptr,0, UInt,OPEN_EXISTING, UInt,FILE_ATTRIBUTE_NORMAL, Ptr,0, Ptr)
;hFile := DllCall("CreateFile", Str,vPath, UInt,GENERIC_READ, UInt,EXCLUSIVE_ACCESS, Ptr,0, UInt,OPEN_EXISTING, Uint,0, Ptr,0, Ptr)

if (hFile < 0)
Return 1
else
Return 0, DllCall("CloseHandle", Ptr,hFile)

Return
}

;==================================================
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
qwerty12
Posts: 468
Joined: 04 Mar 2016, 04:33
GitHub: qwerty12

Re: check if a file is locked, without locking it

01 Feb 2017, 12:14

Seeing what handles to files are already open might be something that works, to varying amounts of success: https://forum.sysinternals.com/howto-en ... 18892.html

EDIT:
jeeswg wrote:Great response, much appreciated!
No problem, I hope you find a suitable solution to your problem :-)
Last edited by qwerty12 on 01 Feb 2017, 13:47, edited 1 time in total.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: check if a file is locked, without locking it

01 Feb 2017, 13:10

Great response, much appreciated!
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lexikos
Posts: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: check if a file is locked, without locking it

01 Feb 2017, 19:33

Of course it would impede saving, because -w means lock for writing. I would think that opening the file with rw would ensure it hasn't been locked for read or write, while omitting -rwd will prevent FileOpen from locking the file.

I thought it might bump the modified date, but that doesn't appear to be the case.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: check if a file is locked, without locking it

02 Feb 2017, 12:51

Warning (again): be careful when using FileOpen,
because you could overwrite a file's data,
thus use a test file rather than an important file.

I tried again using "rw" and "r":

Code: Select all

JEE_FileGetIsLocked4(vPath)
{
if (oFile := FileOpen(vPath, "rw")) ;impedes Notepad/Paint saving sometimes
;if (oFile := FileOpen(vPath, "r")) ;never detects that Notepad/Paint saving is taking place
Return 0, oFile.Close() ;unlocked
else
Return 1 ;locked
}
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lexikos
Posts: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: check if a file is locked, without locking it

03 Feb 2017, 04:31

I think that any attempt to open and lock the file will fail if the file is already open, and that's probably what Notepad does. So I suppose the only way around it is to avoid opening the file at all.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: check if a file is locked, without locking it

04 Feb 2017, 13:38

Thank you Lexikos.

==================================================

I tried using this function: NtQuerySystemInformation(),
to try and get started on enumerating file handles,
but it caused an 'Out of Memory' error.
The size value returned was 4294967280,
16 bytes below 4 GB: 4294967296-4294967280=16.

NtQuerySystemInformation() function from:
Autohotkey新版编译不正常,使用旧版本编译正常,求助help me~! - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?t=17892

Anyhow, listing file handles via AutoHotkey,
is definitely worth pursuing,
whether or not there are other methods for
checking if a file is locked.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
hasantr
Posts: 747
Joined: 05 Apr 2016, 14:18
Location: İstanbul

Re: check if a file is locked, without locking it

24 Nov 2020, 03:14

jeeswg wrote:
02 Feb 2017, 12:51
Warning (again): be careful when using FileOpen,
because you could overwrite a file's data,
thus use a test file rather than an important file.

I tried again using "rw" and "r":

Code: Select all

JEE_FileGetIsLocked4(vPath)
{
if (oFile := FileOpen(vPath, "rw")) ;impedes Notepad/Paint saving sometimes
;if (oFile := FileOpen(vPath, "r")) ;never detects that Notepad/Paint saving is taking place
Return 0, oFile.Close() ;unlocked
else
Return 1 ;locked
}
When running with a loop, it sometimes returns 0 on locked files. But it works right most of the time. Is there a safer way?
Thank you.

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], henriquehassi, JoeWinograd, mikeyww, Ram and 63 guests