0

I'm writing a small WinForms GUI utility in C#. It grabs an Access97 mdb file on the user's workstation, reads some data from it, converts the mdb file into a newer accdb file, uses the data it found in the old file to form part of the new file's name, and then copies the resulting file to a shared folder on the LAN.

I successfully implemented this by creating an Access object with the C# method Microsoft.Office.Interop.Access.Application(), and then calling ConvertAccessProject() with the necessary arguments. It started out working exactly as I wanted.

Then it started throwing a System.Runtime.InteropServices.COMException with HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE). This occurs as soon as I try to create the Access object. It has nothing to do with my files or their formats. The code never obtains an Access object from the COM server, and so, it never reaches the stage of querying or conversion. For three days, I've been trying to fix this.

A little background: After first I got this utility working, I ran into a problem with an SSIS module I'm building as part of the same project. It was having trouble using the Microsoft Jet 4.0 driver from Visual Studio to connect with the new file (or any other type of driver to connect to any Access file, for that matter). So, on a suggestion, I tried installing the driver update for Access 2007 and switching to the ACE.OLEDB driver in my SSIS project. I'm not sure that caused my current problem. Un-installing and re-installing the Access 2007 driver doesn't seem to change the behavior I get when I try to create an Access object in C# code.

From what I read in the various forums, the type of problem I'm having is endemic, and could be caused by, apparently, a set of machine states whose size is impossible to determine. As such, it might not be realistic for me to expect someone to post a direct, step-by-step procedure for fixing my problem that has a significant chance of working—-although I am still open to suggestions. Lacking a "silver bullet" fix, I would like pointers to in-depth, authoritative resources where I can learn how to figure what is happening under the hood on my own, without having to just blindly google other people's suggestions, and then "try this, and try that", hoping that one of the suggestions just so happens to work.

I know there are utilities like cdomcnfg and procmon that can give insight as to what is going on. I have found little public information on how to use them. I have a basic understanding of DCOM/ATL, although it's rather abstract. Other than taking Microsoft Certification training, what would be the best approach for me to educate myself? If there's a killer book out there on the interactions between DCOM, the registry, Interop, .Net, and the whole 32-bit versus 64-bit mess, I'll buy it.

FOLLOWUP #0 There is something I do not understand at all. In most other discussions of this topic, the suggestions (which are often effective solutions) center on going into dcomcnfg, opening Console root | Computers | My Computer | DCOM Config | Microsoft {applicable Office application}, and setting various properties on the applicable DCOM server--usually properties related to security or identity. In my case, there is no DCOM server for Microsoft Access in the branch. Nor for Excel, Word, Outlook, or any Office application. Is there supposed to be? On my machine at home, my Access file converter works just fine, and there is no Microsoft Access DCOM server available in dcomcnfg on that machine, either.

I'm assuming that the functionality of creating an instance of an Access Application ultimately resides in an old-school COM object housed in a dll somewhere. If it is possible for this functionality to work with no registered DCOM server, then what's the benefit of DCOM or dcomcnfg? Does .Net call into DCOM to access the dll, or does it use something else, like .Net/COM Interop? Is there some sort of an "interopcnfg" utility I can use to try to see what it's doing? If I install the Access 2016 redistributable, will it allow me to create an instance of a Microsoft.Office.Interop.Access object, or something else I can use to read data from and convert the file format of Access files? If yes, then will I have to manually install the Access 2016 redistributable on each user's machine, or can I just include it in the solution's build?

FOLLOWUP #1 I found something of interest Here. It states that "If you are using Office Interop from .Net Framework, then you are actually invoking a DCOM server through proxies included in the Office Interop tools." Yes, I am using .Net Framework to build my WinForms app. So then, I'm using a DCOM Server for Access. In that case, how did this thing ever work, and how is it working right now on my home computer, when there is no DCOM Server for Access on either machine? Oh, and I checked the CLSIDs, too, and it wasn't in there, either...

FOLOLOWUP #2 The minimal code to raise the Exception is as follows:

using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var app = new Microsoft.Office.Interop.Access.Application();
        }
    }
}

FOLLOWUP #3 What I found in the Event Log was hard to interpret. Running my compiled sample code from the console results in two events, spaced about 0.1 seconds apart. The first one's source is .Net Runtime:

- EventData 

Application: TestOfficeInterop.exe CoreCLR Version: 4.700.21.56803 .NET Core Version: 3.1.22 Description: The process was terminated due to an unhandled exception. Exception Info: System.IO.FileNotFoundException: Could not load file or assembly 'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'. The system cannot find the file specified. File name: 'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' at TestOfficeInterop.Program.Main(String[] args)  

The second one's source is Application Error:

- EventData 

TestOfficeInterop.exe 
1.0.0.0 
619ae151 
KERNELBASE.dll 
10.0.19041.1466 
e01c7650 
e0434352 
0000000000034f69 
3fdc 
01d80aed605afc3f

F:\TestOfficeInterop\TestOfficeInterop\bin\Debug\
netcoreapp3.1\TestOfficeInterop.exe 
C:\WINDOWS\System32\KERNELBASE.dll e380ef6d-79ae-4f02-939b-26a0f3e6fcf0 

Overall, I'm not sure how any of this information is more useful than what gets dumped out into my console:

F:\TestOfficeInterop\TestOfficeInterop\bin\Debug\netcoreapp3.1>.\TestOfficeInterop.exe
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'. The system cannot find the file specified.
File name: 'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'

at TestOfficeInterop.Program.Main(String[] args)

I noticed something in procmon that looks interesting, but I'm not sure. Running my sample code results in this file being read:

C:\ProgramData\Microsoft\NetFramework\BreadcrumbStore\netcore,Microsoft.Office.Interop.Access,15.0.4420.1017

Notice the version specified. This is only one example of hundreds of file accesses that all specify the same version number.

But what I get dumped out into my terminal says that a file could not be found:

'office, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'

Version 15.0.0.0 ??

What's up with that?

  • 1
    Asking for recommendations for books or tutorials is off topic for SO. Nonetheless, the following may be helpful (some of the info is in VB.NET), but should be easy to convert. https://social.msdn.microsoft.com/Forums/sqlserver/en-US/a0433fc0-81ea-425d-9356-5e72ba6a176c/microsoft-office-access-database-engine-2007-crashes-on-a-multithreaded-application?forum=accessdev – Tu deschizi eu inchid Jan 15 '22 at 23:57
  • 1
    Here are a few more: [Access Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=54920), https://stackoverflow.com/questions/69137918/accessviolationexception-thrown-by-oledbconnection-open/69138428#69138428 , https://stackoverflow.com/questions/70040215/oledbdataadapter-fill-and-oledbdatareader-takes-3-5-minutes-to-fill/70209998#70209998 – Tu deschizi eu inchid Jan 15 '22 at 23:57
  • Thank you for the information. Even though it wasn't directly relevant to my particular use case, I now have a slightly better understanding of the appropriate use of the different database drivers and the workings of Interop. – Erik Midtskogen Jan 16 '22 at 00:34
  • 1
    Never mind recommendations, this is lacking focus a bit. It's going to be much too difficult for us to diagnose this via comments. But can I suggest a repair installation of the entire Office, and barring that a full uninstall/reinstall. Are you executing your application under different permissions than Access, such as elevating to admin? Are you getting any logs in Windows Event Viewer -> Application Logs? – Charlieface Jan 16 '22 at 03:40
  • The symptom is simple, and that is that as soon as I call Microsoft.Office.Interop.Access.Application(), it bombs with the CO_E_SERVER_EXEEC_FAILURE. No, I'm running my app from VS in the same user login that I use for everything else. Learning how to set up, filter, and then analyze logs is exactly the type of thing I want to get better at doing, so that I can figure out what is happening. If you have any suggestions on where best to look to learn this skill, please do share. Most of the info I can find is newbie-level, and the rest is senior DevOps engineer level. I'm in between. – Erik Midtskogen Jan 16 '22 at 04:02
  • 2
    Unfortunately, there's no way for us to know why your code is failing because you haven't posted any code. As far as troubleshooting on your own, you stated that you have a machine that your code works on and another where it doesn't. Compare them and find out what is different. If you haven't opened Access on the computer with the issue, you may try doing so to ensure that it works. Additionally check if both computers are using the same archictecture for Office (Access): 32-bit or 64-bit. After that the easiest thing to do is as @Charlieface stated, uninstall/reinstall Office (Access). – Tu deschizi eu inchid Jan 16 '22 at 04:41
  • 1
    Open Windows Event Viewer -> Windows Logs -> right click Application Logs -> Filter Current Log -> select Error -> OK. Look at most recent errors and see if anything is relevant – Charlieface Jan 16 '22 at 04:45
  • 1
    CO_E_SERVER_EXEC_FAILURE is really a very generic error that means the server (out of process .exe) has failed to answer a call. For example, a bug/crash in the server will cause this error. It's not a configuration error, not a x86/x64 error, not a threading error, not a security error. As other said, try to repair/upgrade Office or compare versions with a running machine, also make sure all required Office components are installed, check event logs. – Simon Mourier Jan 16 '22 at 09:33
  • Thanks, everyone, for your advice. I am looking into all of your suggestions. The one issue I have with simply re-installing Office and hoping that this somehow fixes the problem in some way that I don't understand is that I foresee a future of endless call-backs to reinstall Office every time Windows does an update or someone adds, alters or removes some feature of Office. This seems to just be the way things work in the Microsoft ecosystem, but I want to try to avoid sinking into that swamp through defensive coding borne of understanding. – Erik Midtskogen Jan 16 '22 at 14:43

2 Answers2

0

Then it started throwing a System.Runtime.InteropServices.COMException with HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE).

This usually indicates that you run Office applications on the server side or from any unattended application.

All current versions of Microsoft Office were designed, tested, and configured to run as end-user products on a client workstation. They assume an interactive desktop and user profile. They do not provide the level of reentrancy or security that is necessary to meet the needs of server-side components that are designed to run unattended.

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. Read more about that in the Considerations for server-side Automation of Office article.

You may also find a similar post helpful - Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Sorry, but that's not what's happening. As stated, this is a WinForms GUI utility I'm writing, and it runs on the user's workstation. A user clicks a button to activate processing of the mdb file. The SSIS packages do run on a server, of course, but that's not a direct cause for my problem, as far as I can see. – Erik Midtskogen Jan 15 '22 at 23:00
0

Well, I ended up just giving in. I ran the Office Repair utility, and somehow, some deep, dark magic occurred, and now I'm up and running again. Or at least, I will be until the next time this thing stops working...

My plan for defensive coding is that, when the FileNotFoundException occurs, I'm going to catch it, report to the user that they (apparently) need to run the Office repair utility, and display instructions for doing this. I will also code a "fallback" utility as an alternative which I will offer to the user if and when the Exception occurs. If the user is unable or unwilling to perform the Office repair, they can use this utility to get the data loaded into SSIS, even though this process will unavoidably be much less user-friendly and much more error-prone than the full-featured utility as I intend it to work.

I'm a little disappointed that I was unable to pinpoint what the problem was. It seems that every time I write software for Windows, I spend more time dealing with this type of idiocy than I do actually generating software. Given that most of the Windows ecosystem is basically an ocean of broken, clunky, brittle interfaces living in black boxes that are held together with digital duct tape, I would much prefer to be able to systematically drill down to the root cause of any problem that should arise, the way *nix and Open Source people are accustomed to doing as a matter of course.

Nevertheless, it wasn't a complete waste of time. I did expand my knowledge in some significant and useful ways, which was the primary reason for my asking for help here. @user9938, @SimonMourier, and @Charileface, I thank you very much for your valuable input!