A common scenario when you have a Windows form application is one in which you need to automate Office to work with or open files.
However, there are a few important details you need to about the file you are opening:
1) Is it there
2) Is it already open somewhere
3) If it is already open and can I grab the instance
To do this you must:
1) Check to see if the file exists.
2) If the file is open to grab the instance it is opened with. This can be done with BindToMoniker().
3) If the file is not open, open it and then grab an instance to it.
Here is the code:
using System.Runtime.InteropServices;
using System.Diagnostics;
{
// bind to the path… if the document is not open
// then the Marshal will open an new instance of Excel or
// open in the current active instance of Excel
Excel.Workbook wb = (Excel.Workbook)Marshal.BindToMoniker(fn);
if (wb == null)
{
// we need to start a new instance of Excel
// with the filename passed to it
Process p = new Process();
p.StartInfo.FileName = "excel.exe";
p.StartInfo.Arguments = fn; // send the filename to excel
p.Start(); // start an instance of Excel first
p.WaitForInputIdle(); // wait for the process to be ready
// now bind to minker again to connect to the instance
// of the file that we just opened
wb = (Excel.Workbook)Marshal.BindToMoniker(fn);
}
// show the application – just in case
wb.Application.Visible = true;
// verify the window is shown
wb.Windows[1].Visible = true;
// if minimized – restore the window
if (wb.Application.WindowState == Excel.XlWindowState.xlMinimized)
wb.Application.WindowState = Excel.XlWindowState.xlNormal;
// set the applcation to the foreground
SetForegroundWindow(wb.Application.Hwnd);
// then activate the workbook
wb.Activate();
return wb; // done
}
The code simply looks uses the Marshal BindToMoniker function to access the “object” that currently maintains the file – if it is in memory. If it is not found, we kick off a new process with that filename as a parameter passed to Excel. Excel will open the document and then we are able to use BindToMoniker again to get access to that workbook object. The code at the end does a lot of work to verify that Excel is visible and activated.
Finally to use all this:
{
string fn = @"c:\users\davidcr\desktop\test.xlsx";
if (File.Exists(fn))
{
Excel.Workbook wb = openFile(fn);
MessageBox.Show(wb.Name + " has been opened.");
}
}