Link to home
Start Free TrialLog in
Avatar of jazzIIIlove
jazzIIIloveFlag for Sweden

asked on

I need to check whether some files in 1 folder is locked or not and I want to log the locking situation in a time frame. How to?

Hi there;

I need to check whether some files in 1 folder is locked or not and I want to log the locking situation in a time frame. How to?

C, C# or Java are the options, I just need a simple program that logs the locks of the files in a folder. Any example codes?

Kind regards.
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

You don't mention your OS. That is key. On Windows, Java file locking is only advisory. Other processes can and do ignore a file lock got through Java
Avatar of jazzIIIlove

ASKER

Windows 7-64 bit.
You'd probably be better using C# interop then
sure any example code?

Regards.
So, you basically want a 'snapshot' information regarding if these files are locked at a certain moment? If so, try to lock them - if that fails, they are already locked.
Yes, good way jkr:

>>So, you basically want a 'snapshot' information regarding if these files are locked at a certain moment? >>If so, try to lock them - if that fails, they are already locked.

Ok, but how frequent can I do the checking? Can you provide me a code?

Regards.
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi there,

This is working but I couldn't find a way to adapt the code to check for lock for the files in every second.

Kind regards.
In fact, this is what I got for the file;

Cannot determine lock status

Btw, I am passing the directory path as an input parameter, is it OK?

Kind regards.
Yes, that should be OK, can you change that to the following and post the output?
if (INVALID_HANDLE_VALUE == hFile)
         {
            _tprintf(TEXT("\nCannot determine lock status of %s - reason: %d\n\n"), acFullPath, GetLastError());
            continue;
         }

Open in new window

What about 5000 ms. interval for the check?

and the crucial question; when I check for the lock, am i creating a lock for the file?

Kind regards.
The output is as
reason 32
That's better than I thought - 32 is

  ERROR_SHARING_VIOLATION
# The process cannot access the file because it is being used
# by another process.

So that means 'openened exclusively', but not locked. This can be take care of by using
HANDLE hFile = CreateFile(acFullPath,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

         if (INVALID_HANDLE_VALUE == hFile)
         {
            if ( ERROR_SHARING_VIOLATION == GetLastError()) _tprintf(TEXT("\n%s is opened exclusively by another process\n\n"), acFullPath);
            continue;
         }

         if (INVALID_HANDLE_VALUE == hFile)
         {
            _tprintf(TEXT("\nCannot determine lock status of %s\n\n"), acFullPath);
            continue;
         }

Open in new window

Ooops, make that
HANDLE hFile = CreateFile(acFullPath,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

         if (INVALID_HANDLE_VALUE == hFile)
         {
            if ( ERROR_SHARING_VIOLATION == GetLastError())
            { 
              _tprintf(TEXT("\n%s is opened exclusively by another process\n\n"), acFullPath);
              continue;
            }
             
            _tprintf(TEXT("\nCannot determine lock status of %s\n\n"), acFullPath);
            continue;
         }

Open in new window

Sorry, missed that part:

>>What about 5000 ms. interval for the check?

Sounds OK Just call that function every 5s

>>and the crucial question; when I check for the lock, am i creating a lock for
>>the file?

Not if it is opened exclusively as above - that is different to locking.
ok, that's OK

>># The process cannot access the file because it is being used
Meaning read or write?

time interval? I try to surround with while(true) that the application should run continuously to check but failed.

>>What about 5000 ms. interval for the check?

>>and the crucial question; when I check for the lock, am i creating a lock for the file?

Apparently, in C# version of this question I am locking the file itself, but I can loop it in that

Kind regards.


You mean LockFile in if (!LockFile(hFile,0,0,dwLow,dwHi))?

Kind regards.
'LockFile()' won't even be reached if the file is opened exclusively.

You can achieve the 5000ms interval by using
while(1) {

  CheckLocks("c:\\path");

  Sleep(5000);
}

Open in new window

Ah you will be mad;

but I couldn't find where to put the infiinte loop, moreover what should I put to the checkLocks file?

Should I take the main content to that checkLocks file?

Regards.
>>Should I take the main content to that checkLocks file?

Yes, that would be the idea, e.g.
#include <windows.h>
#include <tchar.h> 
#include <stdio.h>
#include <strsafe.h>
#pragma comment(lib, "User32.lib")

void DisplayErrorBox(LPTSTR lpszFunction);

int CheckLocks(TCHAR* pPath )
{
   WIN32_FIND_DATA ffd;
   LARGE_INTEGER filesize;
   TCHAR szDir[MAX_PATH];
   size_t length_of_arg;
   HANDLE hFind = INVALID_HANDLE_VALUE;
   DWORD dwError=0;
   

   // Check that the input path plus 3 is not longer than MAX_PATH.
   // Three characters are for the "\*" plus NULL appended below.

   StringCchLength(pPath, MAX_PATH, &length_of_arg);

   if (length_of_arg > (MAX_PATH - 3))
   {
      _tprintf(TEXT("\nDirectory path is too long.\n"));
      return (-1);
   }

   _tprintf(TEXT("\nTarget directory is %s\n\n"), pPath);

   // Prepare string for use with FindFile functions.  First, copy the
   // string to a buffer, then append '\*' to the directory name.

   StringCchCopy(szDir, MAX_PATH, pPath);
   StringCchCat(szDir, MAX_PATH, TEXT("\\*"));

   // Find the first file in the directory.

   hFind = FindFirstFile(szDir, &ffd);

   if (INVALID_HANDLE_VALUE == hFind) 
   {
      DisplayErrorBox(TEXT("FindFirstFile"));
      return dwError;
   } 
   
   // List all the files in the directory with some info about them.

   do
   {
      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
         continue; // skip directories
      }
      else
      {
         TCHAR acFullPath[MAX_PATH];

         // build full path

         StringCchCopy(acFullPath, MAX_PATH, pPath);
         StringCchCat(acFullPath, MAX_PATH, TEXT("\\"));
         StringCchCat(acFullPath, MAX_PATH, ffd.cFileName);

         HANDLE hFile = CreateFile(acFullPath,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

         if (INVALID_HANDLE_VALUE == hFile)
         {
            if ( ERROR_SHARING_VIOLATION == GetLastError())
            { 
              _tprintf(TEXT("\n%s is opened exclusively by another process\n\n"), acFullPath);
              continue;
            }
             
            _tprintf(TEXT("\nCannot determine lock status of %s\n\n"), acFullPath);
            continue;
         }

         DWORD dwHi,dwLow;

         dwLow = GetFileSize(hFile,&dwHi);

         if (!LockFile(hFile,0,0,dwLow,dwHi))
         {
           if (ERROR_LOCK_VIOLATION == GetLastError())
             _tprintf(TEXT("\nCannot fully lock %s, file is locked by another process\n\n"), acFullPath);
            else _tprintf(TEXT("\nCannot fully lock %s, file seems to have a lock on it\n\n"), acFullPath);
         }
         else
         {
            _tprintf(TEXT("\n%s is not locked\n\n"), acFullPath);

            UnockFile(hFile,0,0,dwLow,dwHi);
         }

         CloseHandle(hFile);
      }
   }
   while (FindNextFile(hFind, &ffd) != 0);
 
   dwError = GetLastError();
   if (dwError != ERROR_NO_MORE_FILES) 
   {
      DisplayErrorBox(TEXT("FindFirstFile"));
   }

   FindClose(hFind);
   return dwError;
}


void DisplayErrorBox(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and clean up

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}

Open in new window

So opened exclusively doesn't mean locking, right?

then, what does it mean?

Kind regards.
You can lock a whole file or just a portion of a file. That's locking. Opening a file exclusively means *not* even specifying 'FILE_SHARE_READ' when opening it, indicating 'exclusive access'.
Ok, what is exclusive access? Can you give with an example?

Kind regards.
Well, as I wrote above: Opening a file exclusively means *not* even specifying 'FILE_SHARE_READ' when opening it. This will not allow any other process to access the file while you have it open.
>>Opening a file exclusively means *not* even specifying 'FILE_SHARE_READ' when opening it
Ok but then what? I mean not READ but what?

Regards.

P.S. too many questions I know, sorry but you are a good expert, it's good to ask when I grab you in this question :D
I mean definitely another process ?reachs? to the file, that's the reason the file is in use. But by which means? read/write/execute?

Regards.
No, it just means "has opened the file without any sharing options". It does not matter whether the process reads the file, writes to the file or des nothing else with it other than having it open.
Ok but the code u provide finds out the file out of files which have been accessed, operated by an another executable and that exe is operating on all files and your code checks for that files and for the other files which are used by that exe, your code gives no file in use whereas for one particular file gives the output as the file in use. I wonder how that one is in use, i mean the other exe is in C++ and i used your code to find out that culprit file.

So, what can be the reason for that file to be opened as such w.r.t. your code logic?

Regards.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ah, I am illiterate but I think I understand the issue;

https://www.experts-exchange.com/questions/27413769/Checking-a-particular-files-locking-status-in-C.html

Same question but C#, so what you say is that you cover already the last comment in the above question in Idle_Mind's comment in your code.

True?

Regards.
Yes, pretty much true ;o)