Solved

Monitor File usage

Posted on 1997-03-27
23
202 Views
Last Modified: 2010-04-06
How do I tell / monitor what files are open / closed
- regardless of the application that opened / closed them ?

If I use FileOpen, I get horrid windows sharing violation
messages.  i.e. How do I gather data similar to
CleanSweep's File Usage Monitor ?

I need to know what (user selected files) are being accessed, and how long they were accessed.

The files being monitored could be WORD documents, EXCEL
files or anything else !!

At the moment, I am using Delphi v1.0.
0
Comment
Question by:moose032797
  • 9
  • 8
  • 5
  • +1
23 Comments
 

Expert Comment

by:luoxiao
Comment Utility
This is an advanced question.  
You have to use Windows-Hook in order to monitor the message
transformation between programms.

You should check for API function SetWindowHook, and SetWindowHookEx for Detailed information.

Another good article -- "An Window API example" is
available at WWW.BORLAND.COM/DELPHI/PAPERS/

0
 

Author Comment

by:moose032797
Comment Utility
This is an advanced question.
You have to use Windows-Hook in order to monitor the
message  transformation between programms.

>You should check for API function SetWindowHook,
>and SetWindowHookEx for Detailed information.

Thanks.  I checked these in Win API help, but was unsure
about whether to use a TASK or SYSTEM Hook, and what type of
Hook I needed - there are many.

BTW, it is SetWindowsHook SetWindowsHookEx (you were missing
an S) - no matter.

>Another good article -- "An Window API example" is
>available at WWW.BORLAND.COM/DELPHI/PAPERS/

Borland must have moved the article - the link doesn't seem
to exist now.

Can you provide more information / example on using
SetWindowsHookEx ?

0
 
LVL 3

Expert Comment

by:sperling
Comment Utility
This can not be done using hooks.


AFAIK, You'll need to use DPMI and some undocumented DOS interrupts. Never tried though.

Regards,

Erik.



0
 

Author Comment

by:moose032797
Comment Utility
OK, so are we back where we started ?

Can anybody help me solve this problem ?

CleanSweep does something similar, so it must be possible.

All help and suggestions, much appreciated.

Moose
0
 
LVL 3

Expert Comment

by:sperling
Comment Utility
I could give it a try.

But, I'm not sure I understand what you wan't?

1) You have a filename, and need to know if you can access the file

2) You have nothing and need a list of all open files

1 is simple, 2 is a lot of work.


I'll need to know a few things if you wan't option 2.

On which OS'es do you intend to run this app? 3.1/95/NT
Will it stay 16-bit?


Regards,

Erik.
0
 

Author Comment

by:moose032797
Comment Utility
I need to know if a user selected file is currently
open or being used and monitor how long it was open / used.

Without giving away too much about the great new application I am writing, I want to be able to monitor user selected files
and log how long these (user slected) files were being used / accessed / opened.

I don't need an answer accurate to the nearest milli-second - the nearest few seconds would be OK.

The way I envisage it working is this :
- my program calls or hooks something in windows and checks all program acceses or requests to open / read files.
- if it is a file I am monitoring, start a stop watch for that file.
- when the file is closed by the application or it is no longer being read / accessed, then stop the stop watch and write an entry to a log file tp record the date, times and length of time that the file was accessed.

That is exactly what I need to do in a nutshell.

I hope you can help.

Moose
0
 
LVL 3

Expert Comment

by:sperling
Comment Utility
The method I'm thinking of would (if it works) make you able to at any given time obtain a list of all open files. According to docs it should work, but as it'll rely on "unofficial" dos calls there's no guarantee they are supported under windows.

It would *not* work on Windows NT, and it *might* work on 95.

You would ofcourse have to obtain this list e.g. every few seconds, and then compare it with the previous list to find out what's changed.

I'll give this a try during the next few days... I'll have to deliver my current project first, though.


Regards,

Erik.
0
 

Author Comment

by:moose032797
Comment Utility
Thanks for your help Erik !!

What do you say on this luoxiao ??

If possible, I would like to stay in Windows 3.x land and be compatible with WIn 95 and Win NT.

However, this might not be possible.

Does anybody know how CleanSweep monitors what files are being accessed ??

I thought that this would be the key to doing this under Windows.

Ah, well .....

Seeing this problem is so difficult, I have tried to up the points to 1000 !!

All help much appreciated !!

Moose
0
 

Author Comment

by:moose032797
Comment Utility
In the original Email I got about this question, it said that if I wanted more help from luoxiao, that I should rate the answer as 'F'.

I didn't like to do this because I didn't want to offend luoxiao - 'F' is far too harsh.

But, I do know if luoxiao is still helping on this question or whether Eric has taken over now.

So, I have added the suggested 'F' rating to see what is happening.

Moose
0
 
LVL 3

Expert Comment

by:sperling
Comment Utility
If you wan't to stay compatible with all windows versions, there is a much simpler approach... I can write you a simple function to which you pass a path and filename, and then the return value indicates whether it is opened or not.

This would mean that you have to go through the list of files at regular intervals, though.

Such a function ain't worth more than 100pts. If you wan't this, then just reduce points and let me know. If you wan't the "Get list of open files" function, which I've just verified doesn't work with NT, you'll have to give me a few days...

>Does anybody know how CleanSweep monitors what files are being accessed ??
>I thought that this would be the key to doing this under Windows.

I suspect they use a driver/VxD.... And then we're not in Delphi anymore...

Regards,

Erik.
0
 
LVL 3

Expert Comment

by:mheacock
Comment Utility
I don't think it is possible to reduce points...if it is, I'd like to know how...I've tred before.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 3

Expert Comment

by:sperling
Comment Utility
It ain't? I haven't tried... What happens if you delete a question? Do you lose points?

Anyway, I'll try writing both approaches in the next few days.

Erik.
0
 
LVL 3

Expert Comment

by:mheacock
Comment Utility
You can't get rid of your questions once they are asked either.  Supposedly there is code being tested right now that will remove unanswered questions after a period of time.

This is totally of topic...sorry.
0
 

Author Comment

by:moose032797
Comment Utility
>If you wan't to stay compatible with all windows versions, there >is a much simpler approach... I can write
>                       you a simple function to which you pass a >path and filename, and then the return value indicates
>                       whether it is opened or not.
>
>                       This would mean that you have to go
through the list of files at regular intervals, though.

This sounds excellent !!

This will certainly do for what I want right now.

I definetely wantm to stay compatible with all versions of Windows.

Can you please forward source code and anything else (doco, help, etc) that can help me understand how you did it.

And, ofcourse your name / Email so I can give you full credit
for your work in my program's readme !!  ;)

I tried to reduced points to 100 as requested - but I got a
"Sorry you cannot reduce points" error message.

Thanks very much for your help everyone !!

Moose
0
 
LVL 3

Expert Comment

by:mheacock
Comment Utility
They don't allow you to reduce points or remove questions.  It would lead to major abuse by some folks.  They could post a 300 pt question, you could give an awesome answer, they could then reduce to 10 pts, then grade you.  Same goes for removing a question, except now you'd get no points for your answer.
0
 
LVL 3

Accepted Solution

by:
sperling earned 250 total points
Comment Utility
const
  FILEUSAGE_NOTINUSE  = 0;
  FILEUSAGE_NOTFOUND  = 1;
  FILEUSAGE_INUSE     = 2;
  FILEUSAGE_ERROR     = 3;

function GetFileUsage (AFile : STRING) : INTEGER;
var
  pcFileName      : ARRAY [0..255] OF CHAR;
  hFile           : WORD;
  OpenFileStruct  : TOFStruct;
  PrevErrorMode   : WORD;

begin
  { Tell Windows not to display any error dialogs, but rather
    return the errors to the app }
  PrevErrorMode := SetErrorMode (SEM_FAILCRITICALERRORS);

  { Assume that file exists and are not in use }
  Result := FILEUSAGE_NOTINUSE;

  { Create a PChar of the filename, and try to open exclusively}
  StrPCopy(pcFileName, AFile);
  hFile := OpenFile (pcFileName, OpenFileStruct, OF_READWRITE or OF_SHARE_EXCLUSIVE);

  { If we got an invalid handle in return, check the error codes}
  if hFile = $FFFF then begin
    case OpenFileStruct.nErrCode of
      $2,   { File not found  }
      $3,   { Path not found  }
      $15,  { Drive not ready }
      $1A,  { Not MS-DOS disk }
      $1B:  { Sector not found }
        Result := FILEUSAGE_NOTFOUND;

      $20,  {Sharing violation}
      $21:  {Lock violation}
        Result := FILEUSAGE_INUSE;
        { Here, one could try to open using OF_SHARE_DENY_WRITE,
        OF_SHARE_DENY_READ and OF_SHARE_DENY_NONE and detect how
        the file is locked }

    else
      { Unrecognized error.
        These should preferably be written to some log file,
        along with the file name and nErrCode, to allow for
        later addition of a proper return value for the
        given nErrCode }
      Result := FILEUSAGE_ERROR;
    end;
  end;

  { If the handle is not invalid, we better close the file }
  if (hFile <> $FFFF) then _lclose(hFile);

  { Restore the error mode }
  SetErrorMode (PrevErrorMode);
end;


--

I still don't think this is worth 255 points, therefore I suggest  that you offer 1 point on your next question, and I'll answer it if I can. OK?

Regards,

Erik.
0
 

Author Comment

by:moose032797
Comment Utility
Thanks loads Eric !!

I am off to give this a try and I will report back tomorrow !

Thanks for all your time !!

Moose
0
 

Author Comment

by:moose032797
Comment Utility
Sorry for the delay in reporting back.

The above code works fine - for applications that lock files while you are working on them - such as WOrd, Excel, Powerpoint, WOrdPerfect, Lotus 1-2-3, etc.

However, it doesn't work for programs that do not lock their files - such as Notepad, Wordpad, Paint Shop, Delphi, etc.

I think something more complex will be required for these other apps.

Any ideas ?

Moose
0
 
LVL 3

Expert Comment

by:sperling
Comment Utility
>However, it doesn't work for programs that do not lock their
>files - such as Notepad, Wordpad, Paint Shop, Delphi, etc.

That's because they open the file, read its contents and close it. When you save, they reopen, writes back and closes again.

Consider this: If you write a small program that opens a text-file, reads it into a memo and then closes the file, there is no way for anything besides your program to know whether you are still using the contents of the file, or if you have discarded all changes and cleared the memo...

In short, what you seem to want is one of the very few things I'd dare say cannot be done.

Regards,

Erik.

0
 
LVL 3

Expert Comment

by:mheacock
Comment Utility
Actually, Quarterdeck's Cleansweep can register these kinds
of accesses.  But they certainly didn't do it in Delphi.
I'd gather they used a VxD, as per Sperling's previous comment.
I'm guessing they have inserted hooks into the file system.
0
 
LVL 3

Expert Comment

by:sperling
Comment Utility
By using a driver/VxD trapping all access to the file system, it is possible to trap every single file open, close, read, write, delete and so on.

But, if you open a file in e.g. notepad, and then closes it, only the "open file" and "read file" ever gets to the file system. Hard for any program to know that the user actually has closed the file, and that it logically ain't in use anymore.

Regards,

Erik.


0
 
LVL 3

Expert Comment

by:mheacock
Comment Utility
Cleansweep doesn't need to register file closes.  It only needs
 to register file opens, as it simply catalogues a list of files
and when they were last used...that way you can remove files that haven't been used for a long period of time.

Cleansweep also monitors entire installs...it records where
every file was written, it records every change to any .INI
file, it records all changes to the registry.

It's a pretty good product.  I'm amazed it does all that it is
does.  It even registers the number of files that have been
accessed sice you installed the program and per session.
I've tested it a number of ways...even with the notepad thing
above...it catches it...as of now I've:
    1 252 385 files used since Sept. 17 1996
        6 503 files used since Apr.  23 1997 11:45 AM
   
0
 
LVL 3

Expert Comment

by:sperling
Comment Utility
Aha... Then I follow. (I've never seen CleanSweep) That is ofcourse possible, and in fact not very technical difficult to accomplish using a few drivers.

What I wouldn't believe, and still doesn't, was that it is possible for anything to know that I've just cleared the memo and thus logically discarded the file (from my example in some other comment).

If one added tracking of process shutdowns to CleanSweep, it would be possible to keep an approximate if not exact list of files that are physically and logically in use.

This seems like something that would be fun to write... But then, most of it already exists, so why bother...

Anyway, as far as I can see there's no way this can be done without a driver intercepting file system calls. Might ofcourse be some obscure API to get notifications of file access, but I doubt it.

And, I ain't going to write such a driver for anything but cash ;)


Regards,

Erik.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now