News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

check if a file exists [better way]

Started by x64Core, November 15, 2012, 08:56:14 PM

Previous topic - Next topic

x64Core

Hi Guys, I would like to know your opinions please,
I want to do a loop which will check if a file exists, for example, doing a timer call-back function , Create a thread and use Sleep ( to avoid the increase of the CPU ). opinions? please, thanks!  :biggrin:

jj2007

No extra thread needed, just use SetTimer wisely. Here is a little test - performance depends strongly on whether you use Sleep 1 or Sleep 0...

include \masm32\MasmBasic\MasmBasic.inc   ; download
   Init
   xor ebx, ebx
   MsgBox 0, "Open Task Manager and watch the CPU usage. Press Shift to start the second test", "Hi", MB_OK
   NanoTimer()
   .Repeat
      invoke Sleep, 1
      .if !Exist("\Masm32\include\Windows.inc")
         MsgBox 0, "No WinInc", "Hi", MB_OK
      .endif
      invoke GetKeyState, VK_SHIFT
      inc ebx
   .Until ebx>100000 || sword ptr ax<0
   MsgBox 0, Cat$(Str$("Sleep 1: %i tests took ", ebx)+Str$("%i ms", NanoTimer(ms))), "Hi", MB_OK

   xor ebx, ebx
   NanoTimer()
   .Repeat
      invoke Sleep, 0
      .if !Exist("\Masm32\include\Windows.inc")
         MsgBox 0, "No WinInc", "Hi", MB_OK
      .endif
      invoke GetKeyState, VK_SHIFT
      inc ebx
   .Until ebx>100000 || sword ptr ax<0
   MsgBox 0, Cat$(Str$("Sleep 0: %i tests took ", ebx)+Str$("%i ms", NanoTimer(ms))), "Hi", MB_OK
   Exit
end start

hutch--

Sleep or SleepEx is not the right function to use here, a timer in the message loop (WndProc) is more efficient and does not lock the thread for the sleep duration.

jj2007

Quote from: hutch-- on November 15, 2012, 10:22:31 PM
Sleep or SleepEx is not the right function to use here, a timer in the message loop (WndProc) is more efficient and does not lock the thread for the sleep duration.

Of course. I chose a console example to avoid posting a full-fledged win app, but the logic is the same:
SetTimer handle, ID, 0, 0 is a lot different from
SetTimer handle, ID, 1, 0

dedndave

depending on what you are doing, you can use FindFirstFile/FindNextFile/FindClose

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364413%28v=vs.85%29.aspx

you can use FindFirstFileEx/FindNextFile/FindClose to specify certain attributes

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364419%28v=vs.85%29.aspx

in some cases, you can use GetFileAttributesEx, instead - depends on what you're after
works great if you are looking for one specific file
it can be used to tell you if the file exists, attributes, and size

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364946%28v=vs.85%29.aspx

i try to use the later if possible, as it is fast and efficient
if it won't do the job, however, you can use one of the other methods   :P

CommonTater

You can also try the shlwapi commands...

PathFileExists() to discover if a single file or folder exists (no wildcards).
PathIsDirectory()  to discover if a patname is a directory (again no wildcards).
and
PathIsDirectoryEmpty() to discover if a folder has files in it or not (still no wildcards)

There's a whole mess of these... listed HERE .
I find them very handy when you're just doing quick checks.


jj2007

Quote from: CommonTater on November 16, 2012, 03:42:18 AM
There's a whole mess of these... listed HERE.

Hi Tater,

For an assembly coder, there are some highlights on that page ;-)

QuotePathAddBackslash

Adds a backslash to the end of a string to create the correct syntax for a path. If the source path already has a trailing backslash, no backslash will be added.

Note  Misuse of this function can lead to a buffer overrun. We recommend the use of the safer PathCchAddBackslash or PathCchAddBackslashEx function in its place.

x64Core

Thanks guys Really I appreciate your help!  :biggrin:

ADD: guys, a question, How to could I to implement to SetTimerProc? any idea please.

jj2007

Quote from: RHL on November 16, 2012, 05:13:54 AM
How to could I to implement to SetTimerProc?

Simple and straightforward, just follow the SetTimer documentation. If you post your current proc here, we might comment on it.

CommonTater

Quote from: jj2007 on November 16, 2012, 04:56:32 AM
For an assembly coder, there are some highlights on that page ;-)

:biggrin:  Glad I could help.


jj2007

Quote from: CommonTater on November 16, 2012, 07:20:54 AM
:biggrin:  Glad I could help.

Lol. Here is one "highlight":

QuoteHRESULT PathCchAddBackslashEx(
  _Inout_    PWSTR pszPath,
  _In_       size_t cchPath,
  _Out_opt_  PWSTR *ppszEnd,
  _Out_opt_  size_t *pcchRemaining
);

pszPath [in, out]

    A pointer to the path string. When this function returns successfully, the buffer contains the string with the appended backslash. This value should not be NULL.

[Mom, why should the pointer not be NULL?]

Then the final sentence that explains it all: Minimum supported client Windows 8

Win8 users, prepare for the worst :greensml:

CommonTater

#11
Quote from: jj2007 on November 16, 2012, 07:49:36 AM
[Mom, why should the pointer not be NULL?]

The input path can't be NULL because it's going to search for the zero (null) at the end of the string then add a backslash and new null on the end...  That would amount to an access violation at address 0.

The PathAddBackslash function is functionally equivalent to...

if (szString[strlen(szString) - 1] != '\\')
   strcat(szString, "\")

... in fact it probably uses strcat().

FWIW... I'm doing my level best to ignore Windows 8.

jj2007

 ;)

include \masm32\include\masm32rt.inc

.data
ThePath   db "C:\Masm32\include", 0

.code

start:   mov edi, offset ThePath
   xor eax, eax
   or ecx, -1
   repnz scasb
   .if byte ptr [edi-1]!="\"
      mov byte ptr [edi-1], "\"
      stosb
   .endif
   inkey offset ThePath
   exit

end start


x64Core

hi, here it is my code, it's simple:


.386
.model flat,stdcall
include masm32rt.inc


MyTimer PROTO :HWND,:UINT,:UINT,:DWORD

.data
nmsg db "the file doesn't exist",0
Myfile db "C:\Test.txt",0
msg MSG <>
.code
start:

invoke SetTimer,0,11,8000,MyTimer


.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
invoke ExitProcess,0



MyTimer proc hWnd:HWND,uMsg:UINT,idEvent:UINT,dwTime:DWORD

invoke CreateFile,addr Myfile,GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
.if eax == INVALID_HANDLE_VALUE
invoke MessageBox,hWnd,addr nmsg,addr nmsg,MB_OK
.endif
ret

MyTimer endp

end start


But now my problem is, How to can I pass parameters/information to Timer procedure? My aim is, don't to use  global variables lol
wft? yeah if I don't want to use global variables how can I pass information to timer procedure, for example I want to use a string from
my timer procedure but without global variables, my rustic method was this:

put my string in a textbox control, then in the timer procedure get the control handle ( the control ID is constant, so it doesn't matter )
then use sendMessage to get the string from my timerproc without global variable :P but it's very rustic :( so I think it's impossible or
Is there any way to do this? or maybe how to could I implement a timer procedure ( which i can pass information ).
well any idea thanks guys!




qWord

Quote from: RHL on November 16, 2012, 06:03:18 PMif I don't want to use global variables how can I pass information to timer procedure, for example I want to use a string from
one way is to associate the data with the window (-handle)

  • use WNDCLASSEX.cbWndExtra + Get/SetWindwoLong
  • use Get/SetWindowLong with GWL_USERDATA
  • use properties (Set/GetProp)
MREAL macros - when you need floating point arithmetic while assembling!