How to detect when the external programm closes the file?

G

Guest

Hi!
I have problems with the following scenario:
My application is developed using C# under .NET. It must run on all Windows
versions starting from Windows 98.
The user must open different documents (txt, MS Office files, pdf,
pictures,…) from inside my app. It must start the file with the adequate
external program (Notepad, MS Office programs, Acrobat Reader, some Picture
viewer,... ) and be notified when this programs closes the document.
I have tried using various algorithms described on the newsgroups, like
using WaitForSingleObject and "Shell and Wait", but the problem is that it
does not work when the program being called is already started.
For example, when Outlook is started, the winword.exe process is running by
default. Opening a MS Word document from inside my app does not start a new
winword.exe process. Instead it just opens my document in a new Word window.
Because of that, starting winword.exe from my app, does not actually start
it, and I can't therefore wait for the process to end or check exit code or
do something similar.
I also tried enumerating the running processes, using
System.Management..ManagementClass methods, but I can’t get the information
about the files that a program has opened, just about it’s related DLLs and
EXEs (process.GetRelated("CIM_DataFile")).

I would like either to be notified when the file is closed or check, by
using some kind of a file handle, if my file is still opened.
Does anybody have a suggestion how to do it?

Thanx, ANA.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

I believe there is someway to know which application has a file opened,
take a look at sysinternals.com's utilities, they have one that does this
,it shows you the file opened ni the system and what program is using them.


Cheers,
 
N

Nicholas Paldino [.NET/C# MVP]

Ana,

The only way I can think of to do this would be to have a thread that
would constantly try and open the file without sharing it, and by not
allowing other processes to read it. You can do this by calling the
CreateFileEx API directly and checking the return value, or by trying to
create a FileStream which does the same thing and catch the exception that
is thrown when it can't be created. Then, you can fire an event from this
thread that constantly polls to try and do this.

Hope this helps.
 
G

Guest

Hi!
Thanks for the answer.
I already tried to find the solution by searching through the public code
that can be downloaded from sysinternals.com, but without success.
Their program “Processor Explorer†really shows for each running app which
files it has opened or is related to.
But there is no explanation, how they find this kind of info.
Ana.
 
A

Alberto Salvati

Hi, Ana.
In win32 exists a function (NetEnumFile) that can build a list of opened
files in a specified folder.

I' dont konw if fw include something like this function (like mutex and
critical section implementation..).

HTH

Alberto Salvati
 
G

Guest

Hi!
Thanks for the answer.

I thought about this solution, but it doesn’t suite the rest of the
application logic because of the following;

The documents being opened, must be decrypted and copied from a secure
location to some temporary folder, and opened from there. When the user
finishes working with a document, it must be encrypted, copied back to the
secure location, and the temporary copy must be naturally deleted.
I wanted to use this “notification when a file closes†to encrypt back the
file and delete it from the temporary folder. This was supposed to run in a
background thread, some kind of “garbage collectorâ€.

I am not sure if the solution You suggested can guarantee the
“transactional†sequence of operations. If I get the exclusive access to a
file in one moment (so in that moment nobody else is using the file), release
the file and try to delete it in the next moment, what is the guarantee that
somebody else will not try to open this document in the meantime.

For example, the user started opening a file, and this operation lasts for
some time. The file is still not blocked, my “garbage collector†sees that
and deletes the file. In the meantime the slow application decided that it
will finally open the file and it does not find it. What do You think about
such scenarios. Are they possible? Do I have to worry about such things?

The solution of deleting all files at application shutdown is also not good
enough, because the files are “secretâ€, and it would be much better to secure
them immediately after the user finishes using them.

Ana.



Nicholas Paldino said:
Ana,

The only way I can think of to do this would be to have a thread that
would constantly try and open the file without sharing it, and by not
allowing other processes to read it. You can do this by calling the
CreateFileEx API directly and checking the return value, or by trying to
create a FileStream which does the same thing and catch the exception that
is thrown when it can't be created. Then, you can fire an event from this
thread that constantly polls to try and do this.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ana said:
Hi!
I have problems with the following scenario:
My application is developed using C# under .NET. It must run on all
Windows
versions starting from Windows 98.
The user must open different documents (txt, MS Office files, pdf,
pictures,.) from inside my app. It must start the file with the adequate
external program (Notepad, MS Office programs, Acrobat Reader, some
Picture
viewer,... ) and be notified when this programs closes the document.
I have tried using various algorithms described on the newsgroups, like
using WaitForSingleObject and "Shell and Wait", but the problem is that it
does not work when the program being called is already started.
For example, when Outlook is started, the winword.exe process is running
by
default. Opening a MS Word document from inside my app does not start a
new
winword.exe process. Instead it just opens my document in a new Word
window.
Because of that, starting winword.exe from my app, does not actually start
it, and I can't therefore wait for the process to end or check exit code
or
do something similar.
I also tried enumerating the running processes, using
System.Management..ManagementClass methods, but I can't get the
information
about the files that a program has opened, just about it's related DLLs
and
EXEs (process.GetRelated("CIM_DataFile")).

I would like either to be notified when the file is closed or check, by
using some kind of a file handle, if my file is still opened.
Does anybody have a suggestion how to do it?

Thanx, ANA.
 
B

Bonj

When you open the file to decrypt it, you are obviously writing to it, so it
can't be deleted then. *Before* you close the handle of whatever is writing
to it, you open it with your garbage collector thread for read access, but
with FileShare.ReadWrite. It will fail if you try to use any other file
share mode, saying that it is being used by another process, which it is -
the decryptor, writing to it. It is fine for your garbage collector to have
a readonly handle to it as long as it has got the correct file share mode,
read write (this means it allows another process to write to it). But -
when your decryptor finishes writing to it and closes its handle, it still
can't be deleted, because your garbage collector's reading it. Then, when
you're ready to delete it, your deleter thread can come along and open it
for read write access, because the garbage collector's still only holding on
to it with read write share. You can then either set every byte in it to
zero, or just be content with closing the handle and then in the very next
call deleting it.


Ana said:
Hi!
Thanks for the answer.

I thought about this solution, but it doesn't suite the rest of the
application logic because of the following;

The documents being opened, must be decrypted and copied from a secure
location to some temporary folder, and opened from there. When the user
finishes working with a document, it must be encrypted, copied back to the
secure location, and the temporary copy must be naturally deleted.
I wanted to use this "notification when a file closes" to encrypt back the
file and delete it from the temporary folder. This was supposed to run in
a
background thread, some kind of "garbage collector".

I am not sure if the solution You suggested can guarantee the
"transactional" sequence of operations. If I get the exclusive access to a
file in one moment (so in that moment nobody else is using the file),
release
the file and try to delete it in the next moment, what is the guarantee
that
somebody else will not try to open this document in the meantime.

For example, the user started opening a file, and this operation lasts for
some time. The file is still not blocked, my "garbage collector" sees that
and deletes the file. In the meantime the slow application decided that it
will finally open the file and it does not find it. What do You think
about
such scenarios. Are they possible? Do I have to worry about such things?

The solution of deleting all files at application shutdown is also not
good
enough, because the files are "secret", and it would be much better to
secure
them immediately after the user finishes using them.

Ana.



Nicholas Paldino said:
Ana,

The only way I can think of to do this would be to have a thread that
would constantly try and open the file without sharing it, and by not
allowing other processes to read it. You can do this by calling the
CreateFileEx API directly and checking the return value, or by trying to
create a FileStream which does the same thing and catch the exception
that
is thrown when it can't be created. Then, you can fire an event from
this
thread that constantly polls to try and do this.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Ana said:
Hi!
I have problems with the following scenario:
My application is developed using C# under .NET. It must run on all
Windows
versions starting from Windows 98.
The user must open different documents (txt, MS Office files, pdf,
pictures,.) from inside my app. It must start the file with the
adequate
external program (Notepad, MS Office programs, Acrobat Reader, some
Picture
viewer,... ) and be notified when this programs closes the document.
I have tried using various algorithms described on the newsgroups, like
using WaitForSingleObject and "Shell and Wait", but the problem is that
it
does not work when the program being called is already started.
For example, when Outlook is started, the winword.exe process is
running
by
default. Opening a MS Word document from inside my app does not start a
new
winword.exe process. Instead it just opens my document in a new Word
window.
Because of that, starting winword.exe from my app, does not actually
start
it, and I can't therefore wait for the process to end or check exit
code
or
do something similar.
I also tried enumerating the running processes, using
System.Management..ManagementClass methods, but I can't get the
information
about the files that a program has opened, just about it's related DLLs
and
EXEs (process.GetRelated("CIM_DataFile")).

I would like either to be notified when the file is closed or check, by
using some kind of a file handle, if my file is still opened.
Does anybody have a suggestion how to do it?

Thanx, ANA.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top