.NET Forum / .NET Framework / New Users / September 2006
SaveFileDialog locks the file?
|
|
Thread rating:  |
Peter Duniho - 12 Sep 2006 21:44 GMT 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 - 12 Sep 2006 22:38 GMT >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 [quoted text clipped - 9 lines] > 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?
Peter Duniho - 12 Sep 2006 23:39 GMT > 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
Emby - 13 Sep 2006 02:00 GMT 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
>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 [quoted text clipped - 64 lines] > Much thanks, > Pete Peter Duniho - 13 Sep 2006 08:06 GMT > Hi Pete, > [quoted text clipped - 5 lines] > > 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(1000) 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
Willy Denoyette [MVP] - 13 Sep 2006 09:12 GMT |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 [quoted text clipped - 64 lines] | 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.
Emby - 13 Sep 2006 15:05 GMT 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 "ShowReadOnly" and "MultiSelect", while Save has "CreatePrompt" and "OverwritePrompt".
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
> |I searched using Google, on the web and in the newsgroups, and found > nothing [quoted text clipped - 92 lines] > > Willy. Willy Denoyette [MVP] - 13 Sep 2006 21:55 GMT | Hi Willy, | [quoted text clipped - 8 lines] | 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(100); after the using block, this should give sufficient time to explorer to execute it's task and to close the file.
Willy.
Peter Duniho - 13 Sep 2006 20:14 GMT > 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
Willy Denoyette [MVP] - 13 Sep 2006 23:29 GMT | > The SaveFileDialog does not open the selected file unless you open the | > file [quoted text clipped - 5 lines] | 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 [quoted text clipped - 7 lines] | 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.
Peter Duniho - 14 Sep 2006 03:01 GMT > 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 [quoted text clipped - 5 lines] > 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
Willy Denoyette [MVP] - 14 Sep 2006 11:49 GMT | > 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. [quoted text clipped - 4 lines] | 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 [quoted text clipped - 3 lines] | 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 [quoted text clipped - 3 lines] | *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 [quoted text clipped - 5 lines] | 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 [quoted text clipped - 3 lines] | 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 [quoted text clipped - 9 lines] | 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.
Willy Denoyette [MVP] - 14 Sep 2006 14:21 GMT | I can't tell, you don't post that significant part of your code, I don't | know what you are doing in, [quoted text clipped - 3 lines] | // open file here...this is where the exception occurs | } To illustrate this point, add the following to a Form...
private void SomeButton_Click(object sender, EventArgs e) { string szFile = null; using (SaveFileDialog sfd = new SaveFileDialog()) { sfd.OverwritePrompt = 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(szFile, FileMode.Create, FileAccess.ReadWrite /*, FileShare.ReadWrite*/); } 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.
Willy Denoyette [MVP] - 14 Sep 2006 14:34 GMT || I can't tell, you don't post that significant part of your code, I don't || know what you are doing in, [quoted text clipped - 52 lines] | | 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.OverwritePrompt = 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.
Willy Denoyette [MVP] - 14 Sep 2006 17:43 GMT || I can't tell, you don't post that significant part of your code, I don't || know what you are doing in, [quoted text clipped - 52 lines] | | 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.IsNullOrEmpty(sfd.FileName)) { string filePath = szFile; try { FileStream fs = new FileStream(szFile, FileMode.Create, FileAccess.ReadWrite); //use file stream... } catch(IOException) { // another process may hold the file. // if sharing violation, open the file using shared read/write.... try { FileStream fs = new FileStream(szFile, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); // 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.IsNullOrEmpty(sfd.FileName)) { try { FileStream fs = (FileStream)sfd.OpenFile()) { //... } } catch(...) { // handle sharing violation... like above } finally // Close stream }
Willy.
Peter Duniho - 14 Sep 2006 18:09 GMT > 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. And you are talking like a Microsoft apologist, one who can't imagine that an API ought to have a consistent, deterministic, reliable behavior.
It's one thing for there to be a possibility that the file might become locked before I try to access it. Any number of processes may do that, and that's fine with me. However, it's just plain *dumb* for the one API that is supposed to return a file to open for writing to actually *lock* that file and not unlock it before returning that file information to the program that called it.
Do you actually believe that it is reasonable behavior to require the caller to loop, repeatedly attempting to open the desired file until it can be opened?
> | 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 [quoted text clipped - 11 lines] > holding the file and in what mode it's been opened, else I will stop > replying. As I said before, all I'm doing is creating a new FileStream, using the "new FileStream()" syntax. It's not rocket science.
> [...] > No, sorry, this is realy badly explained. Here's another try: [quoted text clipped - 3 lines] > 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. [...] Do you mean "OpenFile"? There's no "FileOpen" method.
Where in the documentation does it say that "it's up to me to implement the file creation and Save logics"? In the documentation for SaveFileDialog.OpenFile, it reads:
"Opens the file with read/write permission selected by the user"
Furthermore, it *specifically* says to use the FileName property to avoid having the SaveFileDialog from deleting existing data in an existing file:
"For security purposes, this method creates a new file with the selected name and opens it with read/write permissions. This can cause unintentional loss of data if you select an existing file to save to. To save data to an existing file while retaining existing data, use the File class to open the file using the file name returned in the FileName property"
I see absolutely no documentation that says "if the file exists, OpenFile returns a null stream reference". In fact, it specifically says that if the file exists, it will still return a valid stream, but will overwrite the existing file with a new one. Nor do I see anything that says that it's up to me "to implement the file creation and Save logics" (unless by that you simply mean that I need to use the FileName property as a parameter to a method such as creating a new FileStream object, in which case *that's exactly what I'm doing*).
Nowhere in the documentation does it suggest that the SaveFileDialog may itself lock the file and that I need to repeatedly attempt to open the file until it has unlocked it.
You have several times referred to documentation that does not appear to actually exist. Perhaps you could actually post some references in the form of URLs where I can read the supposed documentation that says I'm doing this all wrong.
> It has nothing to do with .NET. But of course to you, everything is .NET > once you use the framework, right? I have NEVER seen this happen, and I was one of the very first developers to actually use the common file dialogs. It's true, a lot of years have gone by since they first appeared, and who knows what people at Microsoft have done since then. But I've never seen the file save dialog keep a file locked after returning to the caller, except in the .NET context.
That strongly suggests a possible .NET relevance.
If you can post a non-.NET example that reproduces the exact same problem, I will be happy to accept your claim that this is not a .NET problem. Until then the evidence, however circumstantial it may be, points to a .NET problem.
> [...] > 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. From the documentation:
"Prompts the user to select a location for saving a file. This class cannot be inherited"
and
"This class can either open and overwrite an existing file or create a new file. Most of the functionality for this class is found in the FileDialog class"
That's it as far as "explained in the docs what the class is designed for". There's no mention in the FileDialog class description about the dialog locking the file, or suggesting that I am improperly using the class by getting the file name from the FileName property. Where in the documentation do you see it saying that I should not get the file name from the FileName property, or that I must call the OpenFile method, or that the OpenFile method returns a null stream if the file exists, or that if a null stream is returned, I must implement my own file open and save logic?
> [...]
> | 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. It doesn't matter if the side effects may be different if the SaveFileDialog class is the correct class to use. You specifically asked me why I'm not using the OpenFileDialog, as if that was the class I was supposed to use. Since it's NOT the class I'm supposed to use, how it behaves isn't relevant here, not with respect to solving the problem being discussed.
Pete
Willy Denoyette [MVP] - 14 Sep 2006 19:46 GMT | > 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. | | And you are talking like a Microsoft apologist, one who can't imagine that | an API ought to have a consistent, deterministic, reliable behavior. No, I'm talking like someone who's trying to help you out to find a solution for the issue you (and possibly others) have. But it looks like you are here to insult those who are trying to help.
| It's one thing for there to be a possibility that the file might become | locked before I try to access it. Any number of processes may do that, and [quoted text clipped - 6 lines] | to loop, repeatedly attempting to open the desired file until it can be | opened? Where did I suggest you to loop or whatever?
| > | 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 [quoted text clipped - 14 lines] | As I said before, all I'm doing is creating a new FileStream, using the "new | FileStream()" syntax. It's not rocket science. No, no rocket science, but still too hard for you to post your code.
| > [...] | > No, sorry, this is realy badly explained. Here's another try: [quoted text clipped - 5 lines] | | Do you mean "OpenFile"? There's no "FileOpen" method. Sorry meant, OpenFile.
| Where in the documentation does it say that "it's up to me to implement the | file creation and Save logics"? In the documentation for | SaveFileDialog.OpenFile, it reads: [1]From: Working with the SaveFileDialog Component (Windows Forms Programming) in MSDN. <snip Use it as a simple solution for enabling users to save files instead of configuring your own dialog box. By relying on standard Windows dialog boxes, the basic functionality of applications you create is immediately familiar to users. Be aware, however, that when using the SaveFileDialog component, you must write your own file-saving logic. /snip>
| "Opens the file with read/write permission selected by the user" | [quoted text clipped - 9 lines] | I see absolutely no documentation that says "if the file exists, OpenFile | returns a null stream reference". That's right, bad wording of my part, should read.... However, if the file exists, FileOpen fails (which means there is sharing violation) the method throws and returns a null Stream reference.
In fact, it specifically says that if the
| file exists, it will still return a valid stream, but will overwrite the | existing file with a new one. Nor do I see anything that says that it's up | to me "to implement the file creation and Save logics" (unless by that you | simply mean that I need to use the FileName property as a parameter to a | method such as creating a new FileStream object, in which case *that's | exactly what I'm doing*). That's right, however I didn't see your code yet.
| Nowhere in the documentation does it suggest that the SaveFileDialog may | itself lock the file and that I need to repeatedly attempt to open the file | until it has unlocked it. No, because the SaveFileDialog implementation doesn't lock the file (unless you call OpenFile or whatever other IO API).
| You have several times referred to documentation that does not appear to | actually exist. Perhaps you could actually post some references in the form | of URLs where I can read the supposed documentation that says I'm doing this | all wrong. Several times? mind to tell me when I refered to the docs except when I said: <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.>
See [1]above, for a reference.
| > It has nothing to do with .NET. But of course to you, everything is .NET | > once you use the framework, right? [quoted text clipped - 4 lines] | done since then. But I've never seen the file save dialog keep a file | locked after returning to the caller, except in the .NET context. Again it's not the common dialog (wrapped by the .NET class) who's locking the file, IF it's not your own code who has the file open, it must be another process who opens the file (non-shared), that other 'component' can be anything from a badly written shell extention that has registerd a hook or another badly implemented process that opens the file non-shared (less likely, but still possible).
| That strongly suggests a possible .NET relevance. | | If you can post a non-.NET example that reproduces the exact same problem, I | will be happy to accept your claim that this is not a .NET problem. Until | then the evidence, however circumstantial it may be, points to a .NET | problem. I have a C# sample that doesn't have the issue you are seeing (not using any loops and sleeps etc..), no matter the file type and the times I call it.
| > [...] | > No, they don't, it's explained in the docs what the class is designed for, [quoted text clipped - 21 lines] | exists, or that if a null stream is returned, I must implement my own file | open and save logic? See [1] above.
| > [...] | [quoted text clipped - 10 lines] | Since it's NOT the class I'm supposed to use, how it behaves isn't relevant | here, not with respect to solving the problem being discussed. All I wanted to know is if both behaved the same, that's all. As long as I don't see any code that illustrates the issue, I wont reply any further. All I'm trying here is to help you out, if you think you don't need any help it's ok for me.
Willy.
Peter Duniho - 14 Sep 2006 20:01 GMT > No, I'm talking like someone who's trying to help you out to find a > solution > for the issue you (and possibly others) have. But it looks like you are > here > to insult those who are trying to help. You're the one calling me a "naive developer", and I'm being insulting?
Uh, right. You've promised to stop "helping" a couple of times now...maybe now would be a good time to keep that promise.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|