views:

137

answers:

4

I am currently hosting an IE Browser control in a .NET (2.0) Form and using it to load Office files such as Excel and Word thusly:

_ieCtrl.Navigate("C:\\test.xls", False);

The hosting and loading works well except whenever I navigate to a file I am presented with a dialog that asks whether I want to save or open the file. (This is standard IE file-download behavior.) I always want to open it of course and I do not want the dialog to show.

Another issue is that when I close the window that hosts the IE control and the Office doc the document does not close and remains open on disk. This means that subsequent attempts to open the same file via my app or the native office app will fail because of the sharing violation.

Is there a programmatic way of avoiding this dialog and cleaning up resources afterward? I am asking for a programmatic answer because web research has only yielded solutions that entail modifying OS-level settings.

Bounty NOTE:

I am open to any solution to this issue that will allow me to:

  • Host an Excel spreadsheet inside my application
  • Work rather transparently (avoid usability issues like the one described above)
  • Avoid having to make any OS-specific changes that may affect other applications (especially icluding IE)
  • Is zero additional cost (no licensed 3rd party libs please) Code Project and other open source resources are OK
  • Not mess around with the DSO Framer ActiveX control, unless a stable version is developed/discovered
A: 

If you want to open the file in a separate Excel instance (not embedded in the WebBrowser control), you can simply call

Process.Start(@"C:\Test.xls");
SLaks
That would be fine but the final product is a dashboard of sorts that needs to group a number of different types of data in a single form, thus my need to hosting a control capable of displaying MS Office docs. (Ideas for workarounds that would allow the same type of hosting are welcome.)
Paul Sasik
+2  A: 

This is a horrible hack and should only be considered as a last resort: SendKeys.Send("{O}");

http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys%28VS.71%29.aspx

Something similar to
_ieCtrl.Navigate("C:\\test.xls", False);
(code to sleep or wait may be needed here)
SendKeys.Send("{O}");

Basically, you send the "o" key to the dialog so it presses the "open" option. You are simulating a keyboard presses to click the "open" button. It is hackey because

  • 1) you may need to wait in between calls. If you send the o key before the dialog is up it will be missed. Hopefully the navigate call is finished when the dialog pops (dont know behavior of control in c#). You may need to experiment with the time since different computers will open faster\slower
  • 2) If the dialog is not shown on a computer, you will be inserting "o"s into it. This may cause problems when exiting because it may popup another dialog to try and save the changes. May be able to prevent this by opening it in read-only mode
  • 3) Different versions or windows may need different sendkeys commands. For example, you may need to send "o" and them the "{enter}" key
  • 4) Probably more :)
bugtussle
Would you mind expanding on this? E.g. more code, links to docs etc. There's now a bounty riding on it and, hack or not, your solution is the best option so far. ;-)
Paul Sasik
added some detail
bugtussle
Maybe instead of sleeping i could go into a tight loop looking for a window to open after i call Navigate? That should be more stable and deterministic than waiting for some arbitrary period of time and then blindly sending the click to whatever window happens to be topmost?
Paul Sasik
That could work! I may look at something similar for my program :)
bugtussle
You could use doevents in your loop but I think that on a scale of evilness, sendkeys and doevents are tied at 11. I wish there was a way to avoid these two functions but sometimes it is unavoidable.
bugtussle
brutal brutality!
Luiscencio
+3  A: 

Is your intention for the user to be able to work with the Excel file in an Excel-ish way (i.e. columns, rows, formulas, etc.), possibly saving it back? If this is the case, I can't see how you can solve this problem well without relying on COM Interop with the Excel object model or by integrating third-party libraries to work with the Excel sheet. I know you said no paid solutions, but there are some feature-rich 3rd-party controls out there just for working with Excel files within applications.

I noticed in your comment to SLaks that the final product is a "dashboard of sorts". If your intention is to design a a custom dashboard application, have you considered parsing the Excel file(s) to extract the data and then presenting it in a logical manner within your application. This removes the need to directly display and work with the Excel file while still allowing you to work with the data inside that file. If you are trying to get the data outside of the file, here are two approaches among many:

  • You might consider using the Excel object model and COM interop to read the data from the Excel file into your application. Granted, this includes a dependency on Excel being installed, but it is a possibility. This article has some great code for getting started with reading Excel files in this way.
  • A better way might be to use a library that doesn't have a dependency on Excel being installed on the local system. This answer suggests using the Excel Data Reader library, available on CodePlex.

I know this answer side-steps your original answer of "hosting MS Office documents in [a] custom app," but in case what you're really interested in is the data inside those Excel files, hopefully this answer will prove helpful.

Ben McCormack
Great set of options, thanks! I will check them out. Also, dependency on Excel being installed isn't really an issue. If I could avoid it, great, if not, not that big a deal.
Paul Sasik
@Paul any time I've read Excel data into .NET (which has been pretty rare), I've depended on the Excel interop library. However, even if you can count on Excel being on every machine you plan to deploy your application, you still need to pay attention to *which version* of Excel they are running. I think the referenced libraries are entirely different, so if you needed to handle different versions, you'd have to do figure out how to handle references to the different files at run-time. There may be an easier way to solve that problem, but either way it's tough.
Ben McCormack
@Paul If I were starting out, I would look at the other Excel-independent solutions first and see if that allowed me to get the information I needed, then look at Excel Interop if the other solution came up short.
Ben McCormack
A: 

Office was never meant to run in embedded mode, not in a web page or in an ActiveX Document host. Microsoft had time and time again given us the warning. From pulling dsoframer from the knowledge base to skipping the BrowserFlags registry key in Office 2007. Move to Office add-ins, Excel Web Access or Office Web Apps as quickly as you can.

Sheng Jiang 蒋晟