How to detect when the external programm closes the file?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ana

    How to detect when the external programm closes the file?

    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 WaitForSingleOb ject 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.Manageme nt..ManagementC lass 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.GetRel ated("CIM_DataF ile")).

    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.
  • Ignacio Machin \( .NET/ C#  MVP \)

    #2
    Re: How to detect when the external programm closes the file?

    Hi,

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


    Cheers,

    --
    Ignacio Machin,
    ignacio.machin AT dot.state.fl.us
    Florida Department Of Transportation


    "Ana" <Ana@discussion s.microsoft.com > wrote in message
    news:E3AB9D11-88EF-4798-A511-EC1983831B93@mi crosoft.com...[color=blue]
    > Hi!
    > I have problems with the following scenario:
    > My application is developed using C# under .NET. It must run on all[/color]
    Windows[color=blue]
    > 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[/color]
    Picture[color=blue]
    > viewer,... ) and be notified when this programs closes the document.
    > I have tried using various algorithms described on the newsgroups, like
    > using WaitForSingleOb ject 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[/color]
    by[color=blue]
    > default. Opening a MS Word document from inside my app does not start a[/color]
    new[color=blue]
    > winword.exe process. Instead it just opens my document in a new Word[/color]
    window.[color=blue]
    > 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[/color]
    or[color=blue]
    > do something similar.
    > I also tried enumerating the running processes, using
    > System.Manageme nt..ManagementC lass methods, but I can't get the[/color]
    information[color=blue]
    > about the files that a program has opened, just about it's related DLLs[/color]
    and[color=blue]
    > EXEs (process.GetRel ated("CIM_DataF ile")).
    >
    > 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.[/color]


    Comment

    • Nicholas Paldino [.NET/C# MVP]

      #3
      Re: How to detect when the external programm closes the file?

      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]
      - mvp@spam.guard. caspershouse.co m

      "Ana" <Ana@discussion s.microsoft.com > wrote in message
      news:E3AB9D11-88EF-4798-A511-EC1983831B93@mi crosoft.com...[color=blue]
      > 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 WaitForSingleOb ject 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.Manageme nt..ManagementC lass 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.GetRel ated("CIM_DataF ile")).
      >
      > 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.[/color]


      Comment

      • Ana

        #4
        Re: How to detect when the external programm closes the file?

        Hi!
        Thanks for the answer.
        I already tried to find the solution by searching through the public code
        that can be downloaded from sysinternals.co m, 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.

        "Ignacio Machin ( .NET/ C# MVP )" wrote:
        [color=blue]
        > Hi,
        >
        > I believe there is someway to know which application has a file opened,
        > take a look at sysinternals.co m's utilities, they have one that does this
        > ,it shows you the file opened ni the system and what program is using them.
        >
        >
        > Cheers,
        >
        > --
        > Ignacio Machin,
        > ignacio.machin AT dot.state.fl.us
        > Florida Department Of Transportation
        >
        >
        > "Ana" <Ana@discussion s.microsoft.com > wrote in message
        > news:E3AB9D11-88EF-4798-A511-EC1983831B93@mi crosoft.com...[color=green]
        > > Hi!
        > > I have problems with the following scenario:
        > > My application is developed using C# under .NET. It must run on all[/color]
        > Windows[color=green]
        > > 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[/color]
        > Picture[color=green]
        > > viewer,... ) and be notified when this programs closes the document.
        > > I have tried using various algorithms described on the newsgroups, like
        > > using WaitForSingleOb ject 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[/color]
        > by[color=green]
        > > default. Opening a MS Word document from inside my app does not start a[/color]
        > new[color=green]
        > > winword.exe process. Instead it just opens my document in a new Word[/color]
        > window.[color=green]
        > > 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[/color]
        > or[color=green]
        > > do something similar.
        > > I also tried enumerating the running processes, using
        > > System.Manageme nt..ManagementC lass methods, but I can't get the[/color]
        > information[color=green]
        > > about the files that a program has opened, just about it's related DLLs[/color]
        > and[color=green]
        > > EXEs (process.GetRel ated("CIM_DataF ile")).
        > >
        > > 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.[/color]
        >
        >
        >[/color]

        Comment

        • Alberto Salvati

          #5
          Re: How to detect when the external programm closes the file?

          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



          --
          Alberto Salvati
          An italian delphi developer that are studing c# & .Net

          Comment

          • Ana

            #6
            Re: How to detect when the external programm closes the file?

            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
            “transactiona l” 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 [.NET/C# MVP]" wrote:
            [color=blue]
            > 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]
            > - mvp@spam.guard. caspershouse.co m
            >
            > "Ana" <Ana@discussion s.microsoft.com > wrote in message
            > news:E3AB9D11-88EF-4798-A511-EC1983831B93@mi crosoft.com...[color=green]
            > > 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 WaitForSingleOb ject 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.Manageme nt..ManagementC lass 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.GetRel ated("CIM_DataF ile")).
            > >
            > > 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.[/color]
            >
            >
            >[/color]

            Comment

            • Bonj

              #7
              Re: How to detect when the external programm closes the file?

              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.ReadW rite. 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" <Ana@discussion s.microsoft.com > wrote in message
              news:A8EA6184-AD7C-4BEA-8D56-36D901740F4D@mi crosoft.com...[color=blue]
              > 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 "notificati on 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
              > "transactio nal" 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 [.NET/C# MVP]" wrote:
              >[color=green]
              >> 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]
              >> - mvp@spam.guard. caspershouse.co m
              >>
              >> "Ana" <Ana@discussion s.microsoft.com > wrote in message
              >> news:E3AB9D11-88EF-4798-A511-EC1983831B93@mi crosoft.com...[color=darkred]
              >> > 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 WaitForSingleOb ject 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.Manageme nt..ManagementC lass 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.GetRel ated("CIM_DataF ile")).
              >> >
              >> > 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.[/color]
              >>
              >>
              >>[/color][/color]


              Comment

              Working...