I have a c# application that opens up a COM instance of excel and dumps some data from an Access 2000 database via oleDB onto the sheet then releases the excel object, but I get a window after I close the program with the title bar:
DDE Server Error: [applicationName.exe] - Application Error
I think I've narrowed this down to be an issue with closing excel before I close my program. Figuring this was an issue with the com objects I created, I went through my code and tried to find every place where I stored an Excel COM object and make sure it was released before setting it to null. I ignored ones I didn't store e.g.
excelSheet.GetRange("A1", "A1).Value2 = "Hello";
I still recieve the error and I think I've released all my stored COM objects, is there another reason I might still be getting this error?
Perhaps you're not properly cleaning up your Excel references?
Check out this thread on how to do this.
Related
I frequently receive ok-only prompts while automating add-ins in Excel, stating that Microsoft Excel is waiting for another application to complete an OLE action Error. How to use Interop.dll to show a custom message and handle this error programmatically. Before receiving the promptenter link description here
While You possibly can catch these exceptions depending on your automation framework and do something with it - these type of errors typically comes from not closing the files properly when changing from one to another.
Make sure you dispose all that can be disposed and close all which can be closed in reverse order obviously and it should go away.
If You need more details do post your code for opening and closing looks like a bug there which will make it not coming up.
You do not technically have to use interop, could you consider using a more modern package for interacting with excel?
If you are using google drive / file stream then this may be the problem. Turn off "Real Time Presence in Microsoft Office" then the messages go away.
I'm currently using COM Interop in .NET to export the contents of a DataTable to Excel. It's a method I've been using for years, but the problem is that COM is sketchy and throws random, intermittent, untraceable exceptions. This hasn't been a huge issue, since it's always just been code on a machine dedicated for this purpose and the exceptions are pretty rare, but recently I wrote a front-end for a data warehouse and I've got 200+ users on it, and the problem has (as you would expect) grown exponentially.
The problem is finding a method that does what COM does without the problems that come with COM. Namely, creating an Excel file in-memory (no writing to disk) that is a new workbook, so that when the user hits "Save" for the first time, it will ask them where they want to save the file and what they want to call it.
I know I can export a DataTable to an Excel file using OpenXML: Export DataTable to Excel with Open Xml SDK in c#
And I know I can create an OpenXML Excel object in-memory without writing to a file on disk: How to create Excel file using OpenXML without creating a local file?
The problem is the last step: Opening that in-memory file in Excel (without using COM)
Getting this to work would be my ideal option.
Now, I would prefer not to write to a file, but that isn't a deal breaker if there are no other options, so as a backup option I've also considered using OpenXML to create an Excel Template, and opening the Template (using Process.Start).
The problem with that approach is that some users have reported that Templates sometimes open as xltx files in Edit mode by default, instead of opening as new xlsx files: https://answers.microsoft.com/en-us/office/forum/office_2007-customize/is-there-a-way-to-get-my-excel-template-xltx-file/ab36cd4d-f6b0-46e0-8f15-533a4acb357f?page=1
This would be an even bigger issue than the random errors I'm getting from using COM.
Any ideas are appreciated.
EDIT - These are the COM errors I get:
Cannot create ActiveX component.
COM target does not implement IDispatch.
Exception from HRESULT: 0x800AC472
Select method of Range class failed
Operation unavailable (Exception from HRESULT: 0x800401E3 (MK_E_UNAVAILABLE))
The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER))
The remote procedure call failed. (Exception from HRESULT: 0x800706BE)
Unable to cast COM object of type 'System.__ComObject' to interface type 'System.Collections.IEnumerable'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{496B0ABE-CDEE-11D3-88E8-00902754C43A}' failed due to the following error: 'The requested object does not exist. (Exception from HRESULT: 0x80010114)' and the COM component does not support IDispatch::Invoke calls for DISPID_NEWENUM.
Unable to get the Add property of the Workbooks class
Activate method of Workbook class failed
I've received 107 errors over the course of a few months, but I've gotten more lately since I updated the feature to attach to any existing instance of Excel that the user might already have open instead of creating a new one. Before, when I was always creating a new Excel instance each time, the errors were much more rare (and were largely solved by making Excel invisible while I did the work behind the scenes).
This is a suggestion more than an answer. Consider trying to save the file to a temporary location and set it to Read-Only in the file system. The would force your users to do a SaveAs rather than a Save. Then use the Excel command line options (apparently /n is best) to open the XLSX file as if it were a template.
Those command line options are located here:Excel Command Line Options
I have a code that open an Excel file and read the content. Each time i run the code for the first time, it opens the Excel file without prompting me. But from the second time going it always prompt me this message
TestFile.xlsx is being modified by user 1. Open as read only
and it always prompt at this portion of the code:
Excel ._Workbook xlsBook = xlsApp .Workbooks.Open (_fileName,0,false,5 ,"","",false ,Excel .XlPlatform .xlWindows ,"",true ,false ,0,true ,false ,false );
NB: i also close the file after the operation done and also using VS 2012
So what can be the problem of this prompt ??
After running your Code and exiting, look in the taskmanager, most likely die EXCEL.EXE instance is still running.
you most likely didn't release all the com objects like:
System.Runtime.InteropServices.Marshal.ReleaseComObject(_theWorkbook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_sheets);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_workSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_range);
System.Runtime.InteropServices.Marshal.ReleaseComObject(_excelObj);
Make sure there are no resources where the file would be still opened. Could you post the code you're using to close the resource? Perhaps there's an error there.
Finally, as ugly as it is, it's valid for testing purposes: try manually calling the garbage collector after closing the file.
FINALLY, consider using the OpenXml API to work with Excel/Word files, as opposed to the Interop DLLs (remember these require the client to have Excel installed, as opposed to the OpenXml libraries which you can deploy with your application).
I'm using Microsoft.Office.Interop.Excel to create Excel reports with C#. Those reports have a large amount of graphics and take long time to prepare. During the preparation, The instance of the Excel application that my program uses is hidden from the user.
MY problem is that Microsoft Office tends to share application instances automatically. If the user opens an Excel workbook, Excel will try to find a running instance of Excel and open the document from there. When the user tries to open an Excel workbook while my program is running, it is attached to the instance my program uses.
This generates two problem. First, it forces my reports into visibility before they are supposed to become visible. And second, my program now needs to fight with user over the attention of the Excel instance - and my program usually loses.
So, is there any way to make the Excel instance reject requests(from the user. it should still obey to my program) to open documents, and make Office ignore my instance when it has to decide how to open an Excel document?
You could handle the Application.WorkbookOpen event. In here, either start a second instance of Excel and have it open the workbook, or close the workbook with an error message.
I also saw the Application.Interactive property. I haven't played with this, but it may be of use to you.
You can use NPOI, I suggest you visit the following link
http://npoi.codeplex.com/discussions/36157?ProjectName=npoi
I have done a little experimenting, and I think this will work:
Whenever you begin working with Excel, create two instances, and work with the second. When you're done with your work, delete the second instance and its object, then check the "UserControl" property of the first. If it returns "true", then delete only the object, but leave the process for that instance behind. If it returns "false", then delete the instance as well.
As far as I can tell, the user can open and close any number of workbooks, and it will use the first instance you created, as long as you don't delete it, and the second instance will be unmolested.
here is my question:
I have developed a program that uses Microsoft.Excel COM components in order to read/write over Excel files. Well, my app is doing good but when I open, for instance, another file directly with Excel while my program is running, the file(s) that my app uses appear within Excel. I do not want this. I tried also the Visibility property of Excel Application class, but that was not the solution, it just does not work.
NOTE : I have checked this question out.
Restrict access to excel file opened by C# program
Yet, it says no proper solution actually.
You can use Application.IgnoreRemoteRequests = true. This will avoid users opening excel files in the same Excel process as the one you are using.
There is one caveat though: you have to make sure that all execution paths of your application reset this property to false. This property WILL NOT reset itself when you quit and release your Excel application which means that Excel will not respond correctly to a subsequent user who double clicks on a *.xls file for example.
EDIT: Possible issues with IgnoreRemoteRequest
Ok, to make this clearer I'll detail a little bit more what issues you can run into using this feature (at least these are the only ones I've run into when I had to use this feature).
When setting IgnoreRemoteRequests = true you have to make sure you reset this property BEFORE quiting and/or releasing the COM Excel application. If you don't, Excel will not respond to DDE requests which means if someone double clicks on a *.xls file, the file will not open (Excel will start up, but it wont open the file automatically).
This however is only true if you quit the application and/or release it without reseting the property. You just have to make sure that wherever it is in your code that you are quitting/resetting you set the IgnoreRemoteRquests back to false before.
If you'r application crashes and it hasn't been able to clean up (unhandled exception) then the EXCEL process will keep running (if invisible, you will only see it in the Task Manager). That is normal as your app didnt have a chance to quit and release the internal Excel it is using. This however is not an issue. If a user ignores this "leaked" Excel process until it's eventually killed in next reboot or whatever, or manually kills it from the task bar, Excel will work perfectly fine.
Note: MS Excel 2007. Don't know about behavior of previous versions.
Have you tried running your program under a service account? This should avoid the excel com object interfering with the instance used by the logged in console user, so they will not see the effects of your com objects. It's probably also better security practice to run COM type applications under a service account instead of a user account as well, but that's for another question.