FileSystemWatcher Class - c#

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.

Related

Open excel file in a temporary file

I have been using excel interop for a while now but decided to start using EPPLUS library instead for some reasons.
I like it but I would like to open the excel files the same way Excel Interop does: Open the file as a temporary file that does not really exist anywhere.
So far, EPPLUS must save the file somewhere so that I can open it using:
System.Diagnostics.Process.Start()
What I have tried so far is delete the file after I open it:
excelPack.SaveAs(new FileInfo(name));
File.SetAttributes(name, FileAttributes.ReadOnly); //Force the user to save file As
System.Diagnostics.Process.Start(name);
File.Delete(name); //Crash here. File is in use
But as you can see, it crashed at last line because the file is opened.
The Solution is quite simple. Simply set the file attributes to normal before deleting it. This will somehow tell windows that the file is no longer in use:
excelPack.SaveAs(new FileInfo(name));
File.SetAttributes(name, FileAttributes.ReadOnly); //Force the user to save file As
System.Diagnostics.Process.Start(name);
File.SetAttributes(name, FileAttributes.Normal);
File.Delete(name);
The file will be deleted but it will still be open in Excel in Read Only. The user will be able to save it.

Why do some applications lock files and others don't?

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.

How can I pass a value from Batch to an Excel VBA macro?

I have a C# program which generates a CSV file, then opens an XLSM file in Excel (using ProcessStartInfo and Process.Start). The macro in the XLSM loads the CSV file and distributes data from it to specific cells. Eventually this will be C# generating a spreadsheet without macros that can be loaded in any office suite, and the CSV will disappear.
My problem is that this system now needs to support running the XLSM from anywhere on disk. It finds the CSV via a hardcoded relative path, which doesn't work from a user-specified location. I'd like to do something similar to passing a compiler parameter to define a constant.
EDIT 1:
Alternative approaches I have considered and rejected:
Copy the XLSM to a standard location near the CSV and run it from there.
I would need to copy the file back to its original location, but I don't know when Excel is closed to do that... Except maybe in Excel, but it doesn't know the original location, hence this question.
Create the CSV file next to the user-specified XLSM location.
The CSV file's location is specified in an NLOG configuration file, and changing the surrounding implementation to use a hardcoded path would be expensive. This is the only idea I've had that could work, but it would hurt.
Create a Windows-based hard link to the custom location from the standard location.
I can't assume I'm running on an NTFS filesystem.
Porting your CSV generating program to a user machine you could:
set an environment variable on the user machine to the target directory; e.g. (cmd line) SET CSVPATH=C:\My\CSV
let the macro from your CSV processing XLSM read this environment variable using the Environ() function; e.g. (VBA) MyPath = Environ("CSVPATH") & "\"
alternatively, you could
use a directory selection dialog in an "installation XLSM" to write the correct file path(s) to the target machine's registry using the SaveSetting statement
let the macro from your CSV processing XLSM read the registry using the GetSetting() function to get the correct path

How can I force the user to save an excel file in excel?

I am create an .xls file programatically and opening it in excel
for example:
Process.Start("c:/blabla.xls");
I am deleting the file when excel is closed, so I would like to prompt the user if he wants to save the file when excel before it is closed, and ideally make him save it to a new location.
I'm hoping there is an argument I can feed to excel during the Process.Start
Instead of opening Excel with an Excel file (.xls), you could open Excel with a Excel template (.xlt). This should open a new, unnamed file in Excel, using your xlt as the template. Since the file is unnamed, the user will be prompted to choose a location and file name if he made any changes.
(I'm not sure if renaming the file suffices; you might have to save the file as a template.)
EDIT: In fact, there is a command-line switch lets you do exactly that (open a normal Excel file as a template):
excel.exe /t C:\blabla.xls
Handle the BeforeClosed event.
This is assuming you are using Excel automation. Which, after reading your question again it appears you are not.
http://j-walk.com/ss/excel/tips/tip78.htm

Write to file that is open in Excel

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.

Categories