1

i'm trying to find the most generic way to understand if a file is being "used" by any application.

this is true also for applications like notepad/onenote/notepad++ (which don't lock the file).

i'm handling the opening of the files through my app (using Process.Start), and i need to delete the file when the user finishes working on it.

what i managed to come up until now is the following:

  • "MSWord like applications" - which has a lock on the file constantly, thus - i know that it's currently being used - and the delete will fail.
  • "Notepad/MSPaint like application" - which opens a file in a distinct process, and have a lock on the hosting folder - i can check who's locking the folder, and compare the PID to the PID i received when opening the file
  • "OneNote" like applications - which is problematic as when i open the file - i get different PID (i guess that the process opens, and then it sends the file to the single main onenote process). BUT - i can then check it by name and not PID (not the best, but ok) - as i found out onenote also has some kind of lock on the directory. the only issue here is that i'll have to wait until the process is closed, then delete the file.

i'm totally lost about "Notepad++" applications or similar to them. notepad++ doesn't have any lock on the file or folder, and it uses single process. i 'm not sure how to handle this scenario, when doing Process.Start i don't even have a name of the process. (i can check the registry maybe to see who's the default app that opens the file)...

so, any other directions?

thanks!

== EDIT ==

well, currently i've decided about the following logic, unless there's a flaw in it:

  1. When opening an appliction (Process.Start) - save the PID and the application path. then wait 1 second (or something else i'll think about) - try to get the process by PID - if it exists, this is indeed the PID i want to wait on. if not, then i'll go by process path/name
  2. check if the file is locked by regular lock (by any application) - if so, then don't delete the file yet.
  3. if the file is not locked, check who's locking the folder - then compare it to the PID i have. if the PID doesn't exist (and it's indeed the PID i want to wait on) - then delete the file. if it exists - don't delete the file.
  4. If when starting the process after 1 second the PID doesn't exist, and no lock on the folder/file - i'll just wait until the process ends

that's the idea i think

ArielB
  • 1,184
  • 2
  • 11
  • 36
  • Possible duplicate of [Is there a way to check if a file is in use?](http://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a-file-is-in-use) – MakePeaceGreatAgain Jan 14 '16 at 12:27
  • @HimBromBeere No, because my issue is with files that the hosting process does NOT lock. – ArielB Jan 14 '16 at 12:28
  • Why do you want to do that? Why not just putting those files in some temp folder and attempt to clean it upon exit or start (or even [windows start](http://stackoverflow.com/q/6077869/1997232))? Does files contain sensitive information or what? User may decide to exit your application prior he is done with editing file in another one. – Sinatr Jan 14 '16 at 12:32
  • @Sinatr because when user opens a file through my application, i download the actual file from a remote place, and then open it up for him. after few minutes, i would like to delete the file if the user is done working with it - limitations are fine here. even if it will require to wait until the hosting process (notepad++) is closed. – ArielB Jan 14 '16 at 12:34
  • That criteria *after few minutes*, are you sure it's correct one? I would suggest you don't delete files. Download them into [temp](http://stackoverflow.com/q/944483/1997232) location or even better provide a way for user to define location. Still unclear what kind of data those files contains, but I think this approach is either too generalized (read - you can't cover all cases, so don't even try) or simply wrong. Why do you want to delete files? – Sinatr Jan 14 '16 at 12:41
  • @Sinatr my application "never exists". and i need the files to be in the machine for limited time (i know that the user can perform Save as and save it elsewhere - i dont care about that). also, i dont mind if user exits my application prior he's done. if the few minutes limit is met, the file will be deleted. the main reason is that i dont want to delete the file while his app is opened. – ArielB Jan 14 '16 at 12:42
  • @Sinatr yes the files are sensitive. and i hope to atleast cover most of the cases if its impossible to do all. generally, the files are downloaded "on demand" and should be deleted when user is done with them. Currently, we just delete the files after few minutes, and some applications dont like that (notepad++ prompt that the file was deleted, onenote just closes the view automatically). Notepad can be handled because it creates the file again when user saves. – ArielB Jan 14 '16 at 12:43
  • Notice, you want a bit different thing than the one you are asking about. You can monitor when process you run is [finished](http://stackoverflow.com/q/12273825/1997232). – Sinatr Jan 14 '16 at 12:45
  • @Sinatr barely, because some files that i open are not opened via the process i want to check. notepad++ opens a process and closes right away (as the main host process takes the file) – ArielB Jan 14 '16 at 12:47
  • There's no way to generically know "will some other process attempt to access a particular file in the future, and react badly if the file is no longer there", which seems to be the point you're trying to reach. There are just too many possible ways that programs can be structured. – Damien_The_Unbeliever Jan 15 '16 at 12:54
  • @Damien_The_Unbeliever i don't mind about the future. i mind about only the app that opened the file (and it was via my application). i want to try and find out the best solution, that fits most of the cases. – ArielB Jan 16 '16 at 12:36
  • But the point I was trying to make is that "the app", if you don't know what that app may be, can be structured in arbitrary ways. What you're looking for doesn't exist (a guarantee on how other programs behave), and whatever heuristics you come up with are going to get broken. There could be ways to do things *reliably*, with a different approach, but you'd be working at a far lower level (e.g. you could build something that extends filesystems and clears itself on each reboot, optionally using ephemeral keys so there's no disclosure risk, if that's what the aim is. Not in C# though) – Damien_The_Unbeliever Jan 16 '16 at 16:41
  • @Damien_The_Unbeliever yep i understand that. but i think the default behavior of "wait until process named X" is closed is fine. in the worst case, we'll do what we already do today - delete the file anyway. - it seems enough for the requirement although it's not perfect. thanks! – ArielB Jan 17 '16 at 10:47

1 Answers1

0

I am guessing you are trying to do this,

static void ShowFile(string fileToShow) {
    using (Process proc = new Process()) {
        ProcessStartInfo psi = new ProcessStartInfo(fileToShow);
        psi.UseShellExecute = true;
        proc.StartInfo = psi;
        proc.Start();
        proc.WaitForExit();
    }
}

But, maybe you should do this

static void ShowFile(string fileToShow) {
    using (Process proc = new Process()) {
        ProcessStartInfo psi = new ProcessStartInfo(@"C:\Program Files (x86)\Notepad++\notepad++.exe", "-multiInst " + fileToShow);
        psi.UseShellExecute = false;
        proc.StartInfo = psi;
        proc.Start();
        proc.WaitForExit();
    }
}

And then when your function returns, you can delete your temp file.

I understand that you might not know if the system already has notepad++ installed and its path, etc. In that case you can try to use the path for notepad.exe which comes with windows.

The thing is, there is no perfect solution to what you are looking. To put it in other words, no file viewer/editor is guaranteed to

  1. Use a specific locking mechanism
  2. Keep handle open to the file or directory containing it
  3. Not communicate using DDE, etc

You can find out the default application registered to open your file, but you don't know if it starts as a single instance or a multi-instance app or they communicate using DDE, etc

Vikhram
  • 4,294
  • 1
  • 20
  • 32
  • well, notepad++ is only an example, and i understand your claim, that there's no perfect solution. but there's a solution that can exist for alot of cases, for example - if all of the tests i conduct fail, then i'll rely on process name.. but wanted to know if there's something i havent thought about – ArielB Jan 16 '16 at 12:41