Jump to content

How to know if a file is being accessed by another process


Recommended Posts

Hello all,

LV ver in use: 8.2

1) I have a stand-alone app ("GETFILES.exe") that every X num of mins gets a bunch of files from a database, and copies them over to my machine -let's say to "folder Y"-

2) I'm writing an app that will look into "folder Y" every so often, and then will copy whatever files it finds to another location.

There is a potential case in the scenario from above on which my app could try to copy a file that it is not fully downloaded just yet: The "GETFILES.exe" is in the middle of downloading a file, and my app happens to be looking for files at that instance.

Before I copy the file over, I would like to make sure no other process is doing anything with it. Any suggestions as to how to accomplish this in LabVIEW?

Based on some reading I've done, they recommend I open the file first, and the claim is that I should get an error if the file is still being transferred. I've tried doing this, however, the OpenFile VI does not return any errors, even if the file is in the middle of the transfer.

Any pointers will be appreciated much.

Cheers,

edp

Link to comment

It depends, I think, on the type of lock the other program has on it. There are normal locks and there are exclusive locks. In the latter case, you should indeed get an error when trying to open an exclusively locked file. However, I don't believe many programs use these. Try doing a read and see what happens as well. Maybe even try writing something to filesize+1 and then deleting it back out if it works.

There's always mucking about in the Windows API - there's definitely a routine which will get you the information you want, as I've used several programs which enumerate the processes with a lock on a file. Of course, you could always try deleting it - if it works, you know for a fact it wasn't still being downloaded. :)

Link to comment

It's kind of lame, but you could check the file modification time, and not copy any file which is less than 5 seconds old. Of course if your network is flaky, that may not be enough time. If you wrote getfiles.exe, then I agree with Ton that you should modify that program to copy to a temporary file name and rename it when the download finishes.

Link to comment

Thank you for the suggestions; I've found a couple of ways that meet my needs:

1. Wrote a CVI function (compiled it as .dll then imported it into LabVIEW). The function tries to rename the file. If the file is being used I get an error msg "access denied". I've pasted the function below, in case anyone is curious.

2. If I use the VI "move file" while the transfer is in process, an error is generated by the VI.

/****************************************************************************

* CheckIfFileIsBeingUsed

* Checks to see if a file is being accessed by another application

*

*****************************************************************************/

int CheckIfFileIsBeingUsed (char FileName[], char TempFileName[], int *AccessDenied, char ErrMsg[])

{

int FileCode = 0;

FileCode = RenameFile (FileName, TempFileName);

switch (FileCode)

{

case 0: strcpy(ErrMsg, ""); RenameFile (TempFileName, FileName); //Success

break;

case -1: strcpy(ErrMsg, "File not found or directory in path not found");

break;

case -3: strcpy(ErrMsg, "General I/O error occurred");

break;

case -4: strcpy(ErrMsg, "Insufficient memory to complete the operation");

break;

case -5: strcpy(ErrMsg, "Invalid path, for either of the filenames");

break;

case -6: *AccessDenied = 1; strcpy(ErrMsg, "Access denied");

break;

case -7: strcpy(ErrMsg, "Specified existing path is a directory, not a file");

break;

case -8: strcpy(ErrMsg, "Disk is full");

break;

case -9: strcpy(ErrMsg, "New file already exists");

break;

default: strcpy(ErrMsg, "Error Undefined");

}

DeleteFile(TempFileName);

return FileCode;

}

Link to comment

QUOTE (nitulandia @ Apr 17 2009, 11:33 AM)

The function tries to rename the file. If the file is being used I get an error msg "access denied". I've pasted the function below, in case anyone is curious.

Oh, DUH. I don't know why I didn't think of this - back in text-based programming, I would always just rename a file to itself (whatever.zip -> whatever.zip). It would fail if the file was locked and if it succeeded, I had no extra cleanup to do.

Link to comment

QUOTE (asbo @ Apr 17 2009, 12:24 PM)

Oh, DUH. I don't know why I didn't think of this - back in text-based programming, I would always just rename a file to itself (whatever.zip -> whatever.zip). It would fail if the file was locked and if it succeeded, I had no extra cleanup to do.

I've attached 2 files: one is the .dll and the other one is the VI

Note: VI was created using LV 8.2

Link to comment

Are you sure you want to be dependent on a DLL? You can use the native Move node to implement exact same logic. I tried to move a file onto itself (as I mentioned before) but LabVIEW was ever so kind enough to inform me that the destination and target paths are the same. :thumbdown:

Conclusion: Windows needs a /dev/null/.

Link to comment

I just started transferring a huge file with drag and drop on the Windows explorer, and LabVIEW threw error 5 when I tried to open it. I tried the same thing with LabVIEW doing the copy (using the Copy File primitive), and got the same result. So I think the original advice was good, and maybe you should fix your GETFILES.exe to be more compliant with Windows.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.