C++ unmanaged DLL fails to start Excel on IIS 7.5 - c#

we have a C++ Win32 DLL that reads data from Excel.
The application uses the following line to create an application:
xl.CreateInstance(L"Excel.Application");
I want to use this DLL on a .NET Project, so I've built a C++/CLI Wrapper, and reference the wrapper DLL on a C# Web Application.
Win32 (unmanaged) -> C++/CLI (managed) -> C#
The Web Application works fine on the Visual Studio integrated Web Server, however when I deploy to IIS it fails on the above line and returns the error "Invalid pointer".
I thought it could be a permissions problem so I impersonated the Web App but it didn't work. Looks like IIS does not allow open Excel from an unmanaged C++ DLL. I could open from C# but there is a lot of C++ code to read the spreadsheets and I don't want to write it again.
I am running IIS 7.5 and the applicaiton pool allow Win32 Applications.
Could you help me?
Best regards,

Using Office Interop on the server is NOT supported by MS - see http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757#kb2
Since Windows Vista MS introduced several security-related measures which prevent a Windows Service (IIS is just a special case of that) from doing "desktop-like" things... which means you would have to circumvent several security measures (impersonation alone won't cut it!) to get it to work (NOT recommended!).
The Integrated VS web server does NOT simulate the behaviour of IIS regarding permissions etc.
To deal with Excel in a server-scenario there are several options (free and commercial) out there:
I can recommend Aspose.Cells and Flexcel... didn't try SpreadsheetGear but hear+read lots of good things about it...
Free options (though for the newer xlsx format only!) are for example OpenXML 2 from MS and EPPlus.

Related

Using Interop Library for Web Server Side Excel Creation

I am trying to create excel files using interop library, but below is the error I get:
Creating an instance of the COM component with CLSID {00024500-0000-0000-
C000-000000000046} from the IClassFactory failed due to the following error: 8001010a
The message filter indicated that the application is busy.
(Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)).
I looked into lots of resources out there on the net, which broadly can be categorized into following:
Interop libraries are specifically built for desktop applications, and using them in a server side web application such as wcf is highly not recommended.
Permission issues related to interactive user or DefaultAppPool.
so and and so forth.
Well, here's the caveat, I cannot change the server side application and everything works everywhere else. Few days ago, office 2016 got pushed on my machine from IT, and things stopped working (with above error) on my local machine. Now I can't go and change a legacy code, but see if I can fix the issues on my local to do further development.
Here's what I did, please note that everything was working on this machine (when office 2013 was there):
Got office 2016 Uninstalled, and re-installed office 2013, same issue, hence reverted back to office 2016. Currently MS-Office 2016 32 Bit is installed.
Verified permissions on various sections of security tab of Microsoft Excel Application, have added IIS AppPool\DefaultAppPool user, IIS_IUSRS, Interactive User with full control permission, (shouldn't the error be "Access denied", had permissions been wrong?)
Created a new sample web application, to quickly debug, ran it in all combinations of cpu platform i.e. x86, AnyCpu, x64 - same issue.
Interestingly enough, it works if I point my sample application to IIS Express instead of Local IIS.
Added latest version of interop assembly available (Install-Package Microsoft.Office.Interop.Excel -Version 15.0.4795.1000) - still same issue
Added Microsoft Office 16.0 Object Library (2.8) to the project - still same issue
It's an age old question and its probably better to get away with interop, but I wanted to understand what might be going wrong - all the direct results for the error above suggest implementing IMessageFilter or what not, but I cannot change server side code, below line should simply work as it used to few days ago:
Microsoft.Office.Interop.Excel.Application l_ExcelApp =
new Microsoft.Office.Interop.Excel.Application();
but it doesn't, so what changed? what might have gone wrong?
Also, if it helps - ApplicationID listed in dcomcnfg (/32) is : 00020812-0000-0000-C000-000000000046}, but error has a different one.
Where to look? I hope answer to this question can guide lost souls for ever about this issue.
I'd recommend using the Open XML SDK for dealing or generating open XML documents on the server-side, see Welcome to the Open XML SDK 2.5 for Office for more information. Or just use any third-party components designed for the server-side execution.
As you already noticed, the Considerations for server-side Automation of Office article states the following:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.
Finally I was able to resolve my issue. Following works:
Web Application hosted in IIS, creating excel documents.
So it turns out, apart from the permissions, it is also very important that the application architecture should be similar i.e. my application was 64bit (running as Any CPU on 64bit OS). Whenever you run into such an issue, make sure following also (apart from setting right permissions to right user):
Make sure the architecture of the two applications i.e. (your own and excel) are in sync. One quick way to know whether your excel is 64bit or 32 bit is by looking into Task Manager running programs. If excel is listed as EXECEL.EXE*32 then your office is 32 bit.
When you install a new version of excel, make sure you completely remove previous versions (and not just uninstall, but also removal of dcomconfig office entries i.e. by deleting any registry entry you can find in regedit for the involved office applications guid, specially excel).
I made it work by removing Office 2016 completely as described in 2, afterwards installing Office 2013 and fixing Microsoft.Office.Core reference accordingly in my code.
Permissions that I assigned was following:
Application Identity - Interactive User
And inside Security tab, added IIS AppPool\DefaultAppPool user to all sections and gave full permission.
My app runs in ApplicationPoolIdentity inside IIS.
If doing all the above, still doesn't fix your problem, then God be with you, and more power to you for your journey towards open XML.

Will I require MS Excel installed on the server if I am generating Excel file using NetOffice?

I am trying out both NetOffice and NPOI for to use in an ASP.NET project.
I am making an ASP.NET web site where on click of a button, I want to generate an Excel file in a password protected state and send it to the client to download it.
But I want to know whether, will I require MS Excel installed on the server?
OR Is there a way where I can make this work on a server where MS Excel is NOT installed?
Also what are other pre-requisites for both these APIS?
I basically have to identify which of these APIs will work for me in a server without Microsoft Excel installed in it.
Please check documentation: http://netoffice.codeplex.com/documentation at question
What do I have to do to deliver my application with NetOffice?
Nothing except copying the needed assemblies to the target system. You don't need a registration or something like that with the exception of COMAddIns. Managed COMAddins generally have to be registered via the .Net Utility RegAsm.exe or the Windows Installer do that or you.

do clients running .net applications that reference the excel API need to have excel installed?

To be more specific, I'm referring to the COM component Microsoft.Office.Interop.Excel.dll.
If clients don't have excel installed on their computer, would the .net application even run or just crash the moment there is an attempt to access the dll?
Also, is it possible to work around any possible limitations by deploying a copy of this dll along with the .net application? (Assuming that it's legal to do so.)
If you're usig Excel COM Wrappers and you call any of the functions therein, you must have Excel installed in that computer. The interop DLLs just call the COM servers exposed by Office, in fact most surely in your computer if you test this you'll see an EXCEL.EXE process in the Task Manager.
So yeah, you need Excel installed for interop to work.

Web service vs. Office Automation

I have ASP.NET Web Service, that works under IIS.
I use Microsoft.Interop DLL to convert file from XML Table format to Excel 2003.
In my code I have reference to Microsoft.Interop DLL version 12. When I try to use this web service from VS, everything working correct.
But when I move my web service to 64-bit Windows Server 2008 I have problem with this convertion.
I place my Microsoft.Interop DLL into bin folder of my web service.
I also tried to make build for 86x and 64x platforms, but nothing changed.
Without converting my web service working correct.
What may cause this problem?
You cannot use Office Automation in a server process like a web service. It's designed to automate the Office desktop applications. In a service, it doesn't work, or causes bugs that are difficult to reproduce, is unsupported, and may even be a violation of your license with Microsoft.

Using ADO 3.5 to Import Data From Excel into 64-bit Application

I am currently developing a 64-bit C# application that needs to import its data from an Excel spreadsheet. I have heard that the best way to do this is by using ADO data connections. However, I have read (and experienced) that in order to make this work, I must be writing a 32-bit application as there is no OleDb odbc driver for 64-bit applications.
The problem is that I cannot compile my application as a 32-bit application or other parts of the program (which are not re-writable) will break down.
The fact that I cannot import data from Excel in a 64-bit application seems like a fairly ridiculous issue. How do I solve this problem? Or if not, what work-arounds are available?
Two possible solutions for you:
Use the Open XML SDK instead. This is Office 2007 specific, but it deals directly with the files and doesn't have to go through any DB driver. This is my weapon of choice because it's much faster and less flaky than automation and can handle the more "advanced" tasks like formatting.
Compile a separate x86 binary and launch the process from your x64 app as needed. The importer app can either provide feedback using some form of IPC or simply convert the file to something like CSV which you can read natively in the x64 app. (I'm not exactly a fan of this type of kludge, but you do what you've gotta do...)
I agree that it's kind of ridiculous that we still don't have an x64 JET or ACE driver, but that seems to be the way it is for now. Even MSDASQL won't work for you; there's a 64-bit library but I've read that the Excel component still only works in 32-bit mode.
Have you looked into using VSTO (Microsoft Visual Studio Tools for Office, which I believe are now included as part of VS 2008, and were available in earlier versions as a free download from Microsoft)? Or using OLE Automation?
SpreadsheetGear for .NET is an Excel compatible .NET component which is safe managed code written in C# and compiled for "Any CPU", so it works with 32 bit and 64 bit .NET. This is one of the big advantages of .NET - one build of SpreadsheetGear.dll works equally well with with the 32 bit .NET CLR and the 64 bit .NET CLR.
You can see online samples here and download the free trial here.
Disclaimer: I own SpreadsheetGear LLC

Categories