SaveFileDialog locks the file?

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

    SaveFileDialog locks the file?

    I searched using Google, on the web and in the newsgroups, and found nothing
    on this topic. Hopefully that means I just don't understand what I'm
    supposed to be doing here. :)

    The problem:

    I am trying to use the SaveFileDialog class to get a filename, which is
    subsequently opened for writing (write access, read sharing, but using
    read/write sharing doesn't make the problem go away anyway). Sometimes, on
    the statement where I actually open the file (using the FileName string from
    the SaveFileDialog instance) I get an IOException complaining that the file
    is in use by another process (says it can't open "...because it is being
    used by another process").

    Because this error occurs more often the more quickly I click through the
    UI, it suggested strongly that there was some uncollected resource somewhere
    causing problems. However, I have been unable to fix the problem using the
    mechanisms I know of for addressing those issues ("using" or calling
    GC.Collect(), for example).

    I have narrowed the problem down to the SaveFileDialog itself. That is, if
    I instead hard-code the filename as a string and repeatedly run the save
    command, I never get the error, no matter how quickly I resave the file over
    and over. If, however, I include the SaveFileDialog, the error occurs quite
    often, sometimes even on the very first access of the file during a given
    program execution.

    Not that I think this sort of thing should be necessary, but I've tried two
    different possible work-arounds, neither of which fixed the problem:

    string szFile = null;

    using (SaveFileDialog sfd = new SaveFileDialog( ))
    {
    if (sfd.ShowDialog (this) == DialogResult.OK )
    {
    szFile = sfd.FileName;
    }
    }

    if (szFile != null)
    {
    // open file here...this is where the exception occurs
    }

    And, alternatively:

    SaveFileDialog sfd = new SaveFileDialog( );

    if (sfd.ShowDialog (this) == DialogResult.OK )
    {
    string szFile = sfd.FileName;

    sfd = null;
    GC.Collect();

    // open file here...this is where the exception occurs
    }

    So, any ideas? Has anyone seen this before? As I mentioned, if I don't use
    the SaveFileDialog and instead just set the filename variable directly in
    code, the problem completely disappears. It seems obvious to me that the
    SaveFileDialog is somehow keeping the file open, but I don't understand why,
    nor do I understand how I can get it to release the file so that I can open
    it myself.

    Much thanks,
    Pete


  • Ben Voigt

    #2
    Re: SaveFileDialog locks the file?


    "Peter Duniho" <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote in message
    news:12ge71uimg b538@corp.super news.com...
    >I searched using Google, on the web and in the newsgroups, and found
    >nothing on this topic. Hopefully that means I just don't understand what
    >I'm supposed to be doing here. :)
    >
    The problem:
    >
    I am trying to use the SaveFileDialog class to get a filename, which is
    subsequently opened for writing (write access, read sharing, but using
    read/write sharing doesn't make the problem go away anyway). Sometimes,
    on the statement where I actually open the file (using the FileName string
    from the SaveFileDialog instance) I get an IOException complaining that
    the file is in use by another process (says it can't open "...because it
    is being used by another process").
    Tried using SaveFileDialog. OpenFile instead of the FileName property?


    Comment

    • Peter Duniho

      #3
      Re: SaveFileDialog locks the file?

      "Ben Voigt" <rbv@nospam.nos pamwrote in message
      news:e43r$Or1GH A.3752@TK2MSFTN GP02.phx.gbl...
      Tried using SaveFileDialog. OpenFile instead of the FileName property?
      I may look at that just to see whether it also has the problem, so I can
      provide a more complete bug report. But the OpenFile method doesn't provide
      any parameters for specifying file access, buffer size, etc. and so is
      unsuitable in my particular situation (ie, the default open behavior isn't
      sufficient). Even if it makes the problem go away, it's not a solution for
      this particular case. :(

      Thanks,
      Pete


      Comment

      • Emby

        #4
        Re: SaveFileDialog locks the file?

        Hi Pete,

        Sorry, I don't have a solution, but I will confirm that I've seen this
        behavior. I've not correlated it to the SF dialog; it has always seemed
        infrequent and inconsistent. I just figured it was yet another of VS8's many
        little bugs ... :(
        ... so where is that SP1??

        I'll try "clicking faster" and see what happens.

        Emby

        "Peter Duniho" <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote in message
        news:12ge71uimg b538@corp.super news.com...
        >I searched using Google, on the web and in the newsgroups, and found
        >nothing on this topic. Hopefully that means I just don't understand what
        >I'm supposed to be doing here. :)
        >
        The problem:
        >
        I am trying to use the SaveFileDialog class to get a filename, which is
        subsequently opened for writing (write access, read sharing, but using
        read/write sharing doesn't make the problem go away anyway). Sometimes,
        on the statement where I actually open the file (using the FileName string
        from the SaveFileDialog instance) I get an IOException complaining that
        the file is in use by another process (says it can't open "...because it
        is being used by another process").
        >
        Because this error occurs more often the more quickly I click through the
        UI, it suggested strongly that there was some uncollected resource
        somewhere causing problems. However, I have been unable to fix the
        problem using the mechanisms I know of for addressing those issues
        ("using" or calling GC.Collect(), for example).
        >
        I have narrowed the problem down to the SaveFileDialog itself. That is,
        if I instead hard-code the filename as a string and repeatedly run the
        save command, I never get the error, no matter how quickly I resave the
        file over and over. If, however, I include the SaveFileDialog, the error
        occurs quite often, sometimes even on the very first access of the file
        during a given program execution.
        >
        Not that I think this sort of thing should be necessary, but I've tried
        two different possible work-arounds, neither of which fixed the problem:
        >
        string szFile = null;
        >
        using (SaveFileDialog sfd = new SaveFileDialog( ))
        {
        if (sfd.ShowDialog (this) == DialogResult.OK )
        {
        szFile = sfd.FileName;
        }
        }
        >
        if (szFile != null)
        {
        // open file here...this is where the exception occurs
        }
        >
        And, alternatively:
        >
        SaveFileDialog sfd = new SaveFileDialog( );
        >
        if (sfd.ShowDialog (this) == DialogResult.OK )
        {
        string szFile = sfd.FileName;
        >
        sfd = null;
        GC.Collect();
        >
        // open file here...this is where the exception occurs
        }
        >
        So, any ideas? Has anyone seen this before? As I mentioned, if I don't
        use the SaveFileDialog and instead just set the filename variable directly
        in code, the problem completely disappears. It seems obvious to me that
        the SaveFileDialog is somehow keeping the file open, but I don't
        understand why, nor do I understand how I can get it to release the file
        so that I can open it myself.
        >
        Much thanks,
        Pete
        >

        Comment

        • Peter Duniho

          #5
          Re: SaveFileDialog locks the file?

          "Emby" <emby@blaisesof t-xxx.comwrote in message
          news:ujhKEAt1GH A.4748@TK2MSFTN GP04.phx.gbl...
          Hi Pete,
          >
          Sorry, I don't have a solution, but I will confirm that I've seen this
          behavior. I've not correlated it to the SF dialog; it has always seemed
          infrequent and inconsistent. I just figured it was yet another of VS8's
          many little bugs ... :(
          ... so where is that SP1??
          >
          I'll try "clicking faster" and see what happens.
          Well, I'm glad to hear I'm not entirely insane. :)

          I have been doing a little more investigation. I don't think I've come up
          with too much in the way of insight, but here's what new I've learned about
          the issue:

          * A suitable workaround appears to be to wrap a try/catch in a loop with
          a counter, and to repeatedly attempt to open the file. I call
          Thread.Sleep(10 00) for each failure, and only try five times. Doing this,
          about half the time it would take two tries to open the file, but never more
          than that. It's ugly, but it does work.

          * Another suitable workaround appears to be to write to a temp file
          first, and then move the file over. This is a common enough technique
          generally and one I was implementing for other reasons anyway, and it
          appears to allow for enough time for the file to become unlocked before you
          have to delete it (so that the rename/move can happen). Note: this doesn't
          really avoid the problem per se...it just shifts things around enough that
          it becomes a lot more rare (ie, this isn't a suitable workaround for those
          "must work absolutely 100% of the time" situations).

          On that second item, I will also note that I was in fact still able to
          reproduce a problem once. However, it occurred in an even more bizarre way:
          I got an "Access Denied" exception, but the target file (which I was
          overwriting) got deleted anyway, and the File.Move failed. For all I know,
          this was an entirely different race condition bug, in which the delete did
          occur but the OS didn't finish it in time for the File.Move call to succeed.

          I'm not doing any async i/o, so there *shouldn't* be any race conditions at
          all. But it does appear that even though I'm doing everything sequentially
          and synchronously, there is other stuff going on behind my back (maybe
          within .NET, and maybe just in Windows...I can't tell the difference with
          the information I have).

          Finally, one interesting tidbit:

          * The file that I'm working with for testing is a DivX AVI file. I've
          noticed that every time I run the SaveFileDialog, the little DivX notify
          icon shows up. I suspect this happens as the SaveFileDialog (or more
          likely, the built-in Windows common file dialog...it'd be kind of silly for
          ..NET to completely reinvent that wheel rather than just calling Windows to
          do it) generates thumbnails to present in the dialog. I have a suspicion
          that this is somehow related to whatever is causing the file to be locked.

          Of course, it is .NET that is calling the common dialog, and it is the
          common dialog that is running the multimedia code that calls DivX to
          generate a thumbnail. I have no doubt that a lot of finger-pointing may be
          in the offing when it comes to trying to actually *fix* the problem. But
          hopefully, the various teams involved can coordinate and come up with a
          solution.

          Thanks for your input,
          Pete


          Comment

          • Willy Denoyette [MVP]

            #6
            Re: SaveFileDialog locks the file?


            "Peter Duniho" <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote in message
            news:12ge71uimg b538@corp.super news.com...
            |I searched using Google, on the web and in the newsgroups, and found
            nothing
            | on this topic. Hopefully that means I just don't understand what I'm
            | supposed to be doing here. :)
            |
            | The problem:
            |
            | I am trying to use the SaveFileDialog class to get a filename, which is
            | subsequently opened for writing (write access, read sharing, but using
            | read/write sharing doesn't make the problem go away anyway). Sometimes,
            on
            | the statement where I actually open the file (using the FileName string
            from
            | the SaveFileDialog instance) I get an IOException complaining that the
            file
            | is in use by another process (says it can't open "...because it is being
            | used by another process").
            |
            | Because this error occurs more often the more quickly I click through the
            | UI, it suggested strongly that there was some uncollected resource
            somewhere
            | causing problems. However, I have been unable to fix the problem using
            the
            | mechanisms I know of for addressing those issues ("using" or calling
            | GC.Collect(), for example).
            |
            | I have narrowed the problem down to the SaveFileDialog itself. That is,
            if
            | I instead hard-code the filename as a string and repeatedly run the save
            | command, I never get the error, no matter how quickly I resave the file
            over
            | and over. If, however, I include the SaveFileDialog, the error occurs
            quite
            | often, sometimes even on the very first access of the file during a given
            | program execution.
            |
            | Not that I think this sort of thing should be necessary, but I've tried
            two
            | different possible work-arounds, neither of which fixed the problem:
            |
            | string szFile = null;
            |
            | using (SaveFileDialog sfd = new SaveFileDialog( ))
            | {
            | if (sfd.ShowDialog (this) == DialogResult.OK )
            | {
            | szFile = sfd.FileName;
            | }
            | }
            |
            | if (szFile != null)
            | {
            | // open file here...this is where the exception occurs
            | }
            |
            | And, alternatively:
            |
            | SaveFileDialog sfd = new SaveFileDialog( );
            |
            | if (sfd.ShowDialog (this) == DialogResult.OK )
            | {
            | string szFile = sfd.FileName;
            |
            | sfd = null;
            | GC.Collect();
            |
            | // open file here...this is where the exception occurs
            | }
            |
            | So, any ideas? Has anyone seen this before? As I mentioned, if I don't
            use
            | the SaveFileDialog and instead just set the filename variable directly in
            | code, the problem completely disappears. It seems obvious to me that the
            | SaveFileDialog is somehow keeping the file open, but I don't understand
            why,
            | nor do I understand how I can get it to release the file so that I can
            open
            | it myself.
            |
            | Much thanks,
            | Pete
            |

            The SaveFileDialog does not open the selected file unless you open the file
            by calling SaveFileDialog. OpenFile. Note that I don't quite understand why
            you are using SaveFileDialog instead of the OpenFileDialog, you aren't using
            any functionality of this class other than select a file.

            What version of the framework are you running?


            Willy.




            Comment

            • Emby

              #7
              Re: SaveFileDialog locks the file?

              Hi Willy,

              I am using framework v2 (I think Pete is as well).

              I won't speak for Pete, but I'm using the File Save Dialog because, well,
              the user is specifying a file to which they are saving data. This has a
              somewhat different action than the Open file dialog. For example, Open has
              props like "ShowReadOn ly" and "MultiSelec t", while Save has "CreateProm pt"
              and "OverwritePromp t".

              Both of the dialogs select files, but the FS dialog selects a file to write
              to, while the OF dialog selects a file to read from.

              Emby

              "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
              news:u6t2Uxw1GH A.3656@TK2MSFTN GP04.phx.gbl...
              >
              "Peter Duniho" <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote in message
              news:12ge71uimg b538@corp.super news.com...
              |I searched using Google, on the web and in the newsgroups, and found
              nothing
              | on this topic. Hopefully that means I just don't understand what I'm
              | supposed to be doing here. :)
              |
              | The problem:
              |
              | I am trying to use the SaveFileDialog class to get a filename, which is
              | subsequently opened for writing (write access, read sharing, but using
              | read/write sharing doesn't make the problem go away anyway). Sometimes,
              on
              | the statement where I actually open the file (using the FileName string
              from
              | the SaveFileDialog instance) I get an IOException complaining that the
              file
              | is in use by another process (says it can't open "...because it is being
              | used by another process").
              |
              | Because this error occurs more often the more quickly I click through
              the
              | UI, it suggested strongly that there was some uncollected resource
              somewhere
              | causing problems. However, I have been unable to fix the problem using
              the
              | mechanisms I know of for addressing those issues ("using" or calling
              | GC.Collect(), for example).
              |
              | I have narrowed the problem down to the SaveFileDialog itself. That is,
              if
              | I instead hard-code the filename as a string and repeatedly run the save
              | command, I never get the error, no matter how quickly I resave the file
              over
              | and over. If, however, I include the SaveFileDialog, the error occurs
              quite
              | often, sometimes even on the very first access of the file during a
              given
              | program execution.
              |
              | Not that I think this sort of thing should be necessary, but I've tried
              two
              | different possible work-arounds, neither of which fixed the problem:
              |
              | string szFile = null;
              |
              | using (SaveFileDialog sfd = new SaveFileDialog( ))
              | {
              | if (sfd.ShowDialog (this) == DialogResult.OK )
              | {
              | szFile = sfd.FileName;
              | }
              | }
              |
              | if (szFile != null)
              | {
              | // open file here...this is where the exception occurs
              | }
              |
              | And, alternatively:
              |
              | SaveFileDialog sfd = new SaveFileDialog( );
              |
              | if (sfd.ShowDialog (this) == DialogResult.OK )
              | {
              | string szFile = sfd.FileName;
              |
              | sfd = null;
              | GC.Collect();
              |
              | // open file here...this is where the exception occurs
              | }
              |
              | So, any ideas? Has anyone seen this before? As I mentioned, if I don't
              use
              | the SaveFileDialog and instead just set the filename variable directly
              in
              | code, the problem completely disappears. It seems obvious to me that
              the
              | SaveFileDialog is somehow keeping the file open, but I don't understand
              why,
              | nor do I understand how I can get it to release the file so that I can
              open
              | it myself.
              |
              | Much thanks,
              | Pete
              |
              >
              The SaveFileDialog does not open the selected file unless you open the
              file
              by calling SaveFileDialog. OpenFile. Note that I don't quite understand why
              you are using SaveFileDialog instead of the OpenFileDialog, you aren't
              using
              any functionality of this class other than select a file.
              >
              What version of the framework are you running?
              >
              >
              Willy.
              >
              >
              >
              >

              Comment

              • Peter Duniho

                #8
                Re: SaveFileDialog locks the file?

                "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                news:u6t2Uxw1GH A.3656@TK2MSFTN GP04.phx.gbl...
                The SaveFileDialog does not open the selected file unless you open the
                file
                by calling SaveFileDialog. OpenFile.
                It obviously does so. Whether it's the .NET portion of SaveFileDialog
                that's doing that or not, I can't say. For all I know, this is a general
                problem that exists in the regular Win32 common dialog implementations ,
                inhereted by .NET. But invoking the dialog results in the file being
                locked, that much I am sure.
                Note that I don't quite understand why
                you are using SaveFileDialog instead of the OpenFileDialog, you aren't
                using
                any functionality of this class other than select a file.
                Um, because I am prompting the user to *save* the file. It is simply not
                true that I am not "using any functionality of this class other than select
                a file". There are genuine and subtle differences between the way the Open
                and Save dialogs work, and it's important for an application to use the
                appropriate one in the appropriate situation to preserve these subtle
                differences.

                Is it your assertion that it's my fault the problem I am having because I'm
                using the SaveFileDialog instead of the OpenFileDialog? If not, I'm at a
                loss as to why you would even mention it anyway (even assuming it was a
                legitimate complaint of my code, when it's obviously not).
                What version of the framework are you running?
                ..NET 2.0.

                Pete


                Comment

                • Willy Denoyette [MVP]

                  #9
                  Re: SaveFileDialog locks the file?


                  "Emby" <emby@blaisesof t-xxx.comwrote in message
                  news:eVdby2z1GH A.4116@TK2MSFTN GP02.phx.gbl...
                  | Hi Willy,
                  |
                  | I am using framework v2 (I think Pete is as well).
                  |
                  | I won't speak for Pete, but I'm using the File Save Dialog because, well,
                  | the user is specifying a file to which they are saving data. This has a
                  | somewhat different action than the Open file dialog. For example, Open has
                  | props like "ShowReadOn ly" and "MultiSelec t", while Save has "CreateProm pt"
                  | and "OverwritePromp t".
                  |
                  | Both of the dialogs select files, but the FS dialog selects a file to
                  write
                  | to, while the OF dialog selects a file to read from.
                  |

                  Right, but you should know that the way you use this common control, you
                  opened a can of worms. The FileDialog is wrapping a native common control
                  (as you rightfully concluded yourself), which integrates with the shell
                  (explorer.exe), When selecting a file and accepting the selection (OK
                  DialogResult), explorer will be notified to query the file properties and
                  perform some housekeeping like updating the recent used documents list, for
                  this the explorer process needs to open the file (unfortunately non shared),
                  if you look at your code, this will mostly occur at the same time you try to
                  open the file for writing, which obvioulsly fails.
                  One thing you can try is to insert a Thread.Sleep(10 0); after the using
                  block, this should give sufficient time to explorer to execute it's task and
                  to close the file.

                  Willy.


                  Comment

                  • Willy Denoyette [MVP]

                    #10
                    Re: SaveFileDialog locks the file?


                    "Peter Duniho" <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote in message
                    news:12ggm49idg r858d@corp.supe rnews.com...
                    | "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                    | news:u6t2Uxw1GH A.3656@TK2MSFTN GP04.phx.gbl...
                    | The SaveFileDialog does not open the selected file unless you open the
                    | file
                    | by calling SaveFileDialog. OpenFile.
                    |
                    | It obviously does so. Whether it's the .NET portion of SaveFileDialog
                    | that's doing that or not, I can't say. For all I know, this is a general
                    | problem that exists in the regular Win32 common dialog implementations ,
                    | inhereted by .NET. But invoking the dialog results in the file being
                    | locked, that much I am sure.
                    |
                    No it's not the SaveFileDialog which locks the file (it doesn't even open
                    the file), it's the explorer.exe (the windwos shell) who opens the file.

                    | Note that I don't quite understand why
                    | you are using SaveFileDialog instead of the OpenFileDialog, you aren't
                    | using
                    | any functionality of this class other than select a file.
                    |
                    | Um, because I am prompting the user to *save* the file. It is simply not
                    | true that I am not "using any functionality of this class other than
                    select
                    | a file". There are genuine and subtle differences between the way the
                    Open
                    | and Save dialogs work, and it's important for an application to use the
                    | appropriate one in the appropriate situation to preserve these subtle
                    | differences.
                    |

                    This class is a simple solution for users to save file data using standard
                    Windows dialogs, you have to implement your own save logic, to do so you
                    should use the OpenFile method (which keeps a copy of the original file) and
                    attach it to a stream, which you can change or not and finaly save. Now ,you
                    don't use any of this, you don't use the class as it was intended to be
                    used.


                    | Is it your assertion that it's my fault the problem I am having because
                    I'm
                    | using the SaveFileDialog instead of the OpenFileDialog? If not, I'm at a
                    | loss as to why you would even mention it anyway (even assuming it was a
                    | legitimate complaint of my code, when it's obviously not).
                    |

                    No, it's not my assertion, both OpenFileDialog and SaveFileDialog may
                    introduce some (maybe different) side effects because both use a Common
                    Control which integrates with the shell (explorer.exe) by mean of an
                    explorer hook procedure, this is done to display the explorer-style dialog.
                    Also, a shell extention component can register a handler component (COM
                    shell extention) to perform specific actions based on file types, the
                    explorer will post an event to all registerd handlers whenever a registerd
                    filetype is opened, the handler is free to open the file. To find the link
                    between the file and the handler, explorer may have to read (that is, open,
                    read extended file information, read volume info, close) the file and that's
                    exactly what happens here when the user clicks 'Save'.
                    Note that in general there is no problem with this, explorer closes the file
                    before the Dialog result is returned to the caller, but a handler may well
                    customize the dialog by providing a hook procedure a template or both, and
                    here the handler could open the file in exclusive mode and you start a race.
                    I would suggest you to grab a copy of Sysinternals
                    http://www.sysinternals.com/ "filemon" and look who's having the file open
                    while your program tries to open the same file.

                    Willy.






                    Comment

                    • Peter Duniho

                      #11
                      Re: SaveFileDialog locks the file?

                      "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                      news:%23OAEJQ41 GHA.2196@TK2MSF TNGP06.phx.gbl. ..
                      No it's not the SaveFileDialog which locks the file (it doesn't even open
                      the file), it's the explorer.exe (the windwos shell) who opens the file.
                      You are making a semantic argument that is irrelevant. For the .NET
                      programmer, using only the .NET framework, any behavior or functionality
                      that framework offers is considered to be the framework itself. If the
                      framework inherets bad behavior from some component it uses, it is still the
                      framework that has the bad behavior.

                      Do I refrain from saying that my program locks the file when it wants to
                      write to it, just because it's not actually my code that does the actual
                      locking? I don't think so.

                      Beyond that, this is not a problem that I've seen with non-.NET programs. I
                      can't say for sure that it doesn't exist, but I've never had to work around
                      the common file dialogs locking files that I'm trying to write to after I
                      call the save file dialog from a regular Win32 application (and I've been
                      writing Windows software since *before* there was a Win32). So, it remains
                      to be shown that this problem is not unique to .NET. As far as I can tell,
                      it is.
                      This class is a simple solution for users to save file data using standard
                      Windows dialogs, you have to implement your own save logic, to do so you
                      should use the OpenFile method (which keeps a copy of the original file)
                      What do you mean by "keeps a copy of the original file"? There may not even
                      *be* an original file, and if there is, are you saying that a copy of the
                      original file is created somewhere and that's what's used in the stream?
                      and
                      attach it to a stream, which you can change or not and finaly save. Now
                      ,you
                      don't use any of this, you don't use the class as it was intended to be
                      used.
                      If Microsoft intends me to use the OpenFile method any time I use the
                      SaveFileDialog class, they need to provide an OpenFile overload that allows
                      for the same flags and options I get with the FileStream constructors.

                      Until such time (and IMHO even after such time), it is just plain silly to
                      claim that I am not using the dialog as intended, when I'm using the
                      documented functionality in the only way that addresses my specific need.
                      Given that the OpenFile method doesn't do what I want, what do you suggest I
                      do rather than using the SaveFileDialog? Why does the SaveFileDialog
                      include a FileName property if Microsoft intends for programmers to ONLY use
                      the OpenFile method to open a file specified through that dialog?
                      | Is it your assertion that it's my fault the problem I am having because
                      I'm
                      | using the SaveFileDialog instead of the OpenFileDialog? If not, I'm at
                      a
                      | loss as to why you would even mention it anyway (even assuming it was a
                      | legitimate complaint of my code, when it's obviously not).
                      |
                      >
                      No, it's not my assertion, both OpenFileDialog and SaveFileDialog may
                      introduce some (maybe different) side effects
                      Then why are you questioning my use of the SaveFileDialog versus the
                      OpenFileDialog? How is my use of the SaveFileDialog rather than the
                      OpenFileDialog relevant to this question at all?

                      Pete


                      Comment

                      • Willy Denoyette [MVP]

                        #12
                        Re: SaveFileDialog locks the file?


                        "Peter Duniho" <NpOeStPeAdM@Nn OwSlPiAnMk.comw rote in message
                        news:12ghe0l4im s1j49@corp.supe rnews.com...
                        | "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                        | news:%23OAEJQ41 GHA.2196@TK2MSF TNGP06.phx.gbl. ..
                        | No it's not the SaveFileDialog which locks the file (it doesn't even
                        open
                        | the file), it's the explorer.exe (the windwos shell) who opens the file.
                        |
                        | You are making a semantic argument that is irrelevant. For the .NET
                        | programmer, using only the .NET framework, any behavior or functionality
                        | that framework offers is considered to be the framework itself. If the
                        | framework inherets bad behavior from some component it uses, it is still
                        the
                        | framework that has the bad behavior.
                        |

                        You are talking like a naive developer, the one who doesn't look any further
                        than the small API set he's using. if something goes wrong it's the API.

                        | Do I refrain from saying that my program locks the file when it wants to
                        | write to it, just because it's not actually my code that does the actual
                        | locking? I don't think so.
                        |

                        I can't tell, you don't post that significant part of your code, I don't
                        know what you are doing in,

                        if (szFile != null)
                        {
                        // open file here...this is where the exception occurs
                        }
                        I have no idea how you do open the file, all I know is that there is a
                        sharing conflict. So please post your implementation, investigate who's
                        holding the file and in what mode it's been opened, else I will stop
                        replying.


                        | Beyond that, this is not a problem that I've seen with non-.NET programs.
                        I
                        | can't say for sure that it doesn't exist, but I've never had to work
                        around
                        | the common file dialogs locking files that I'm trying to write to after I
                        | call the save file dialog from a regular Win32 application (and I've been
                        | writing Windows software since *before* there was a Win32). So, it
                        remains
                        | to be shown that this problem is not unique to .NET. As far as I can
                        tell,
                        | it is.
                        |

                        It has nothing to do with .NET. But of course to you, everything is .NET
                        once you use the framework, right?

                        | This class is a simple solution for users to save file data using
                        standard
                        | Windows dialogs, you have to implement your own save logic, to do so you
                        | should use the OpenFile method (which keeps a copy of the original file)
                        |
                        | What do you mean by "keeps a copy of the original file"? There may not
                        even
                        | *be* an original file, and if there is, are you saying that a copy of the
                        | original file is created somewhere and that's what's used in the stream?
                        |
                        No, sorry, this is realy badly explained. Here's another try:
                        If the file doesn't exists, FileOpen creates the file with RW access and
                        returns the stream reference, as the file doesn't exists, it cannot be
                        opened by someone else, no problem here.
                        However, if the file exists, FileOpen returns a null stream reference, and
                        it's up to you to implement the file creation and Save logics. And here is
                        where the problem starts, if the file is opened by someone else, it's up to
                        you to handle this, say by creating a temporary file and copy this one to
                        the original file when done or wait until the file gets released. But before
                        you can do this you have to find out who's accessing the file and why, I say
                        it's the explorer and I also explained why, but I also said that you can
                        register a hook procedure (and/or a template hook) such that you can modify
                        the standard behavior of the common dialog control. So when you install a
                        third party product, it's possible that they register a shell hook, and
                        that's where it gets messy. So please try to investigate who's holding the
                        file and stop complaining about this tiny .NET wrapper class.



                        If the file doen exist, you have to implement your own save logig based on
                        File
                        | and
                        | attach it to a stream, which you can change or not and finaly save. Now
                        | ,you
                        | don't use any of this, you don't use the class as it was intended to be
                        | used.
                        |
                        | If Microsoft intends me to use the OpenFile method any time I use the
                        | SaveFileDialog class, they need to provide an OpenFile overload that
                        allows
                        | for the same flags and options I get with the FileStream constructors.
                        |

                        No, they don't, it's explained in the docs what the class is designed for,
                        if you don't like the behavior, you will have to design your own save
                        dialog.

                        | Until such time (and IMHO even after such time), it is just plain silly to
                        | claim that I am not using the dialog as intended, when I'm using the
                        | documented functionality in the only way that addresses my specific need.
                        | Given that the OpenFile method doesn't do what I want, what do you suggest
                        I
                        | do rather than using the SaveFileDialog? Why does the SaveFileDialog
                        | include a FileName property if Microsoft intends for programmers to ONLY
                        use
                        | the OpenFile method to open a file specified through that dialog?
                        |
                        Again the behavior is clearly explained in the docs, if it doesn't fit your
                        needs implement your own dialog, if you don't like to use the implementation
                        of the OpenFile method, that is create a new file using the selected
                        filename, implement your own behavior no problem.

                        | | Is it your assertion that it's my fault the problem I am having
                        because
                        | I'm
                        | | using the SaveFileDialog instead of the OpenFileDialog? If not, I'm
                        at
                        | a
                        | | loss as to why you would even mention it anyway (even assuming it was
                        a
                        | | legitimate complaint of my code, when it's obviously not).
                        | |
                        | >
                        | No, it's not my assertion, both OpenFileDialog and SaveFileDialog may
                        | introduce some (maybe different) side effects
                        |
                        | Then why are you questioning my use of the SaveFileDialog versus the
                        | OpenFileDialog? How is my use of the SaveFileDialog rather than the
                        | OpenFileDialog relevant to this question at all?

                        The side effects may be different as the explorer hook procedures may be
                        different.

                        Willy.


                        Comment

                        • Willy Denoyette [MVP]

                          #13
                          Re: SaveFileDialog locks the file?


                          "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                          news:%23ByyBu%2 31GHA.1548@TK2M SFTNGP02.phx.gb l...

                          |
                          | I can't tell, you don't post that significant part of your code, I don't
                          | know what you are doing in,
                          |
                          | if (szFile != null)
                          | {
                          | // open file here...this is where the exception occurs
                          | }

                          To illustrate this point, add the following to a Form...

                          private void SomeButton_Clic k(object sender, EventArgs e)
                          {
                          string szFile = null;
                          using (SaveFileDialog sfd = new SaveFileDialog( ))
                          {
                          sfd.OverwritePr ompt = false; // no overwrite prompt
                          if (sfd.ShowDialog () == DialogResult.OK )
                          {
                          szFile = sfd.FileName;
                          }
                          }
                          if (szFile != null)
                          {
                          string filePath = szFile;
                          try
                          {
                          // uncomment to get the exceptional behavior
                          FileStream fs = new FileStream(szFi le, FileMode.Create ,
                          FileAccess.Read Write /*, FileShare.ReadW rite*/);
                          }
                          finally
                          {
                          this.Text = szFile;
                          }
                          }
                          }

                          Run the program and select the SAME existing file twice in succession, an AV
                          will be thrown on you the second time. Uncomment the FileStream's FileShare
                          argument and run again, no exception will be thrown no matter the number of
                          times you select the same file.
                          The reason it succeeds the first time is because the explorer has to create
                          the recent used file links in the users profile (File system and registry),
                          the second time you select the same file explorer will use the cached link
                          (through the SaveFileDialog' s hook proc, other hooks my do different
                          things). Note also that File system indexers may have hooks installed which
                          may open the file when being notified of a change , same goes for virus
                          scanners or quota managers (and other filesystem filter drivers).
                          So, whether you consider this as bad behavior (in which case you should file
                          a bug) or not, you have to program defensively, be prepared that you may get
                          AV whenever you use the shell integrated stuff and program accordingly.
                          For instance, if you don't want to open the file for shared read/write, try
                          to open in Write mode first and handle the AV exception by opening the file
                          as shown above.

                          Willy.






                          Comment

                          • Willy Denoyette [MVP]

                            #14
                            Re: SaveFileDialog locks the file?


                            "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                            news:%23FZ9jCA2 GHA.1252@TK2MSF TNGP04.phx.gbl. ..
                            |
                            | "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                            | news:%23ByyBu%2 31GHA.1548@TK2M SFTNGP02.phx.gb l...
                            |
                            ||
                            || I can't tell, you don't post that significant part of your code, I don't
                            || know what you are doing in,
                            ||
                            || if (szFile != null)
                            || {
                            || // open file here...this is where the exception occurs
                            || }
                            |
                            | To illustrate this point, add the following to a Form...
                            |
                            | private void SomeButton_Clic k(object sender, EventArgs e)
                            | {
                            | string szFile = null;
                            | using (SaveFileDialog sfd = new SaveFileDialog( ))
                            | {
                            | sfd.OverwritePr ompt = false; // no overwrite prompt
                            | if (sfd.ShowDialog () == DialogResult.OK )
                            | {
                            | szFile = sfd.FileName;
                            | }
                            | }
                            | if (szFile != null)
                            | {
                            | string filePath = szFile;
                            | try
                            | {
                            | // uncomment to get the exceptional behavior
                            | FileStream fs = new FileStream(szFi le, FileMode.Create ,
                            | FileAccess.Read Write /*, FileShare.ReadW rite*/);
                            | }
                            | finally
                            | {
                            | this.Text = szFile;
                            | }
                            | }
                            | }
                            |
                            | Run the program and select the SAME existing file twice in succession, an
                            AV
                            | will be thrown on you the second time. Uncomment the FileStream's
                            FileShare
                            | argument and run again, no exception will be thrown no matter the number
                            of
                            | times you select the same file.
                            | The reason it succeeds the first time is because the explorer has to
                            create
                            | the recent used file links in the users profile (File system and
                            registry),
                            | the second time you select the same file explorer will use the cached link
                            | (through the SaveFileDialog' s hook proc, other hooks my do different
                            | things). Note also that File system indexers may have hooks installed
                            which
                            | may open the file when being notified of a change , same goes for virus
                            | scanners or quota managers (and other filesystem filter drivers).
                            | So, whether you consider this as bad behavior (in which case you should
                            file
                            | a bug) or not, you have to program defensively, be prepared that you may
                            get
                            | AV whenever you use the shell integrated stuff and program accordingly.
                            | For instance, if you don't want to open the file for shared read/write,
                            try
                            | to open in Write mode first and handle the AV exception by opening the
                            file
                            | as shown above.
                            |
                            | Willy.

                            As a final note (sorry for 'spamming' this thread), above behavior doesn't
                            show up when using the OpenFile method to open the selected file like this:

                            ...
                            string szFile = null;
                            using (SaveFileDialog sfd = new SaveFileDialog( ))
                            {
                            sfd.OverwritePr ompt = false; // no overwrite prompt
                            if (sfd.ShowDialog () == DialogResult.OK )
                            {
                            if (szFile != null)
                            {
                            szFile = sfd.FileName;
                            ... = sfd.OpenFile();
                            ... // do you thing and write the stream
                            }
                            }
                            }

                            Willy.






                            Comment

                            • Willy Denoyette [MVP]

                              #15
                              Re: SaveFileDialog locks the file?


                              "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                              news:%23FZ9jCA2 GHA.1252@TK2MSF TNGP04.phx.gbl. ..
                              |
                              | "Willy Denoyette [MVP]" <willy.denoyett e@telenet.bewro te in message
                              | news:%23ByyBu%2 31GHA.1548@TK2M SFTNGP02.phx.gb l...
                              |
                              ||
                              || I can't tell, you don't post that significant part of your code, I don't
                              || know what you are doing in,
                              ||
                              || if (szFile != null)
                              || {
                              || // open file here...this is where the exception occurs
                              || }
                              |
                              | To illustrate this point, add the following to a Form...
                              |
                              | private void SomeButton_Clic k(object sender, EventArgs e)
                              | {
                              | string szFile = null;
                              | using (SaveFileDialog sfd = new SaveFileDialog( ))
                              | {
                              | sfd.OverwritePr ompt = false; // no overwrite prompt
                              | if (sfd.ShowDialog () == DialogResult.OK )
                              | {
                              | szFile = sfd.FileName;
                              | }
                              | }
                              | if (szFile != null)
                              | {
                              | string filePath = szFile;
                              | try
                              | {
                              | // uncomment to get the exceptional behavior
                              | FileStream fs = new FileStream(szFi le, FileMode.Create ,
                              | FileAccess.Read Write /*, FileShare.ReadW rite*/);
                              | }
                              | finally
                              | {
                              | this.Text = szFile;
                              | }
                              | }
                              | }
                              |
                              | Run the program and select the SAME existing file twice in succession, an
                              AV
                              | will be thrown on you the second time. Uncomment the FileStream's
                              FileShare
                              | argument and run again, no exception will be thrown no matter the number
                              of
                              | times you select the same file.
                              | The reason it succeeds the first time is because the explorer has to
                              create
                              | the recent used file links in the users profile (File system and
                              registry),
                              | the second time you select the same file explorer will use the cached link
                              | (through the SaveFileDialog' s hook proc, other hooks my do different
                              | things). Note also that File system indexers may have hooks installed
                              which
                              | may open the file when being notified of a change , same goes for virus
                              | scanners or quota managers (and other filesystem filter drivers).
                              | So, whether you consider this as bad behavior (in which case you should
                              file
                              | a bug) or not, you have to program defensively, be prepared that you may
                              get
                              | AV whenever you use the shell integrated stuff and program accordingly.
                              | For instance, if you don't want to open the file for shared read/write,
                              try
                              | to open in Write mode first and handle the AV exception by opening the
                              file
                              | as shown above.
                              |
                              | Willy.
                              |
                              |

                              Sorry, forget about this, the code snip is completely wrong, the reason it
                              fails at the next time is because the stream was not closed :-((
                              The code should look something like this...
                              ...
                              if(!String.IsNu llOrEmpty(sfd.F ileName))
                              {
                              string filePath = szFile;
                              try
                              {
                              FileStream fs = new FileStream(szFi le, FileMode.Create ,
                              FileAccess.Read Write);
                              //use file stream...
                              }
                              catch(IOExcepti on)
                              {
                              // another process may hold the file.
                              // if sharing violation, open the file using shared
                              read/write....
                              try
                              {
                              FileStream fs = new FileStream(szFi le, FileMode.Create ,
                              FileAccess.Read Write, FileShare.ReadW rite);
                              // process stream
                              }
                              catch(...)
                              {
                              // this is real bad, can't open the stream
                              }
                              finally
                              {
                              if(fs != null)
                              fs.Close();
                              //....
                              }
                              }

                              The same goes when using the OpenFile method you will have implement
                              something like this...

                              if (sfd.ShowDialog () == DialogResult.OK )
                              {
                              if(!String.IsNu llOrEmpty(sfd.F ileName))
                              {
                              try
                              {
                              FileStream fs = (FileStream)sfd .OpenFile())
                              {
                              //...
                              }
                              }
                              catch(...)
                              { // handle sharing violation... like above
                              }
                              finally
                              // Close stream
                              }

                              Willy.


                              Comment

                              Working...