Suppose I have a program running that periodically adds information to a .CSV file. Is there a way to write to the file while it is already open in Excel? Obviously the changes wouldn't be noticed until the file was re-opened in Excel, but as it stands right now, I'm catching IOException and just starting a new .csv file if the current one is already open.
Excel seems to open the file in exclusive mode, so the only way I can think of would be to write your changes to a temporary file, and then use FileSystemWatcher to see when the file is closed, and overwrite the file.
Not a very good idea, as you could lose data. The whole reason excel locks the file is so that you don't accidentally overwrite changes made in excel.
It sounds like the file is locked. I doubt you will be able to write to that file if it is open in another process.
As a former (and sort of current) VB Programmer, I can tell you Jared is correct - there is no way to do this directly. You can try to copy the file first, make your edits, then attempt to save the file back to its original location until the locked file becomes free. You should be able to copy that file, even while locked.
What about using Excel's object model and automating the addition of the data into the open spreadsheet? You'd probably need to prompt the user somehow to let them know what was happening.
Related
In my datalogging application I write to a temporary file of the form ... AppData\Local\Temp\euaxgd5z.csv
This opens by default in Excel.
Process.Start(TempFileLocationBox.Text.ToString());
The next time the timer tries to write more data to this file, an exception is thrown. However if I open it with TextPad
Process.Start("textpad.exe", TempFileLocationBox.Text.ToString());
it can write to the file quite happily and TextPad will ask if I want to reload it. How can I get Excel to behave as nicely as TextPad?
Personally, I wouldn't even try to 'communicate' to excel the fact that you want the file reloaded. I would just write a new file and open a new copy of excel, after closing the old copy if possible.
That way you won't need to worry if the user is using open office instead, for example.
I want to save some plain text periodically to a text file, and it will be really better if I can minimize the chance of corrupting the file in case the app gets terminated or the system restarts. What are the way to ensure that the plain text file is always good.
Edit
I will run the program from USB drive, so want to make sure the file is still perfect if I eject the drive without closing the App.
You could take a look at using transactions on the NTFS file system, assuming that the USB stick is formatted NTFS and your OS is Vista or better.
Do not use option FileMode.Create, which overwrites existing files. Instead, use option FileMode.Append when creating the file stream, so that any text will be appended to the file without modifying last data.
However, try not to keep the files opened for long period, just open them and read or write and then Dispose them.
Use File.AppendAllText to open, append and close in one go.
I had searched a lot of examples, but none work perfect for me. I am using C#.
My application need to remove the files in folder, only when the file is closed.
The try-catch File.Open(...) method only works for certain filetype like doc, xls, ppt, pdf, mp3 etc, but not work for txt, zip, html etc...
The behavior your are seeing doesn't have anything to do with the file's extension or contents. It has to do with the way the associated applications treat those files. For example, Notepad, Internet Explorer, etc will not hold a lock on an opened file once the contents are read. That's why .txt and .html files are able to be opened.
Microsoft Office, virtually all media players, etc will hold a lock on the file. In the case of Office, it's doing so to make sure other programs don't delete/move the file out from under it. In the case of a media player, the files are usually too big to be read into memory completely. That's why those file types are locked when in use.
In other words, those files that appear to not be in use aren't actually in use. The program read the data from the file and close it and now it's done with it. There's really no easy way to determine whether or not another program has a particular file open if it no longer has an open handle to the file.
Open the file in the binary mode File.Open(...) will work for all files.
Try opening the file in write mode, I think there is something to specify that the lock is exculsive..but for some reason if your thread dies..dunno if that lock will be released automatically...
all you need is to delete the file that is not in use ... rigth ... Simply ignore the exception thrown by File.Delete. Since it will not delete the file that is in use ..
try
{
File.Delete(path);
}
catch(Exception e)
{
// ignore ... or whatever action
}
you can also catch specific exceptions to take specific action ... like IOException for file in use, UnauthorizedAccessException for read only files and permission issues etc ...
Checking file for opening and then trying to delete may still through exception as file may have been opened by some process between checking and deleting operations ..
My question is why when using FileSystemWatcher Class to monitor when an excel file is saved the FileSystemEventArgs returnes .Deleted ?
When monitoring .txt format file it is .Changed
I suppose: because the Excel first creates a temporary file, writes the information there, than deletes the original .xls file and renames the temporary file.
It might be that Excel ensures this way that the original file is not lost if save operation fails.
It looks like Excel may well be deleting and re-creating the file you're watching. One way to prove this empirically is to have your application that watches the file running and then open and save the file in another application, for example Notepad. If this only results in the Changed event being triggered, then it's Excel causing the Deleted event to trigger.
Is there any way to determine if a file is open by anything include applications that do not lock the file (like notepad).
I need to detect when a given file myfile.txt is no longer open in any application including notepad - so i cannot use File.Open(...) with exclusive access to test since the file has no lock on it.
No. When Notepad has opened a file, it has read the entire file in and then closed it. So there is no trace in the OS that links Notepad's private memory with the file on disk.
Opening the file exclusively will not work, because Notepad does not have the file open. Searching Notepad's handle table will not work, because Notepad does not have the file open.
The only way to detect this is to write an unmanaged DLL that is injected into every process to scan their virtual memory, searching for the exact file contents. Not recommended.
You must call File.Open(...) specifying your desired access flags and check the returning value to determine if the file is opened or if the access is denied. This is the recommended and safe way to access a file.