Using interop with Excel on a remote machine - c#

I'm attempting to use office interop to interact with Excel on a remote machine. The simplest-seeming way I found to do this was to use the Microsoft.VisualBasic.Interaction.CreateObject method, which is documented here. In my case, the call made to it is:
var excelApp = (Application)Interaction.CreateObject("Excel.Application", machineName);
However, this isn't fully working as expected. The results I'm getting:
When the machineName is the local machine that I'm running the code on, this works as expected.
When the machineName is a remote machine, an instance of Excel actually is started on the machine, but the CreateObject call fails with exception:
System.Exception: The remote server machine does not exist or is unavailable.
Googling this message doesn't reveal much of use, the results seem to all be people with different symptoms.
I don't really have any leads on what's causing this. I noticed that the method documentation page I linked previously rather cryptically states:
Refer to COM documentation (see Microsoft Developer Network) for additional information on making an application accessible on a remote networked computer. You may need to add a registry key for your application.
But I've yet to find that documentation.
Any suggestions for what could be the problem here? Or, failing that, a different way of achieving the same thing? Due to my situation, remote interop like this is a firm requirement- using Excel on a local machine to access a remote file is not sufficient.
Additionally, I would very much like to avoid a solution that requires a service or anything similar to be running on the Excel client machine, which as I understand it would be necessary if I wanted to use Activator.CreateInstance with a UrlAttribute.

The problem was a DCOM configuration issue. All the appropriate permissions were set, but the application was not configured to run as the interactive user. I suspect that this problem is relatively uniquely identified by the combination of being able to launch the process but not being able to connect to it afterwards.
The setting for this can be found in Component Services (dcomcnfg), under:
Component Services > Computers > My Computer > DCOM Config > Microsoft Excel Application. Right click this, select 'Properties', and configuration for which user account to run under is found on the 'Identity' tab.
An additional problem that I found along the way was that 'Microsoft Excel Application' was not initially listed in Component services, due to having 32-bit Excel on 64-bit Windows.
A solution for this, found here, was to run the 32-bit version of mmc (which can be done from the command line by starting with argument -32) and use the Component Services snap-in

Related

New PrintServer object fails, "printer name is invalid"

I'm migrating a working ASP.NET web application from WS2008R2 to WS2016, but the same happens on WS2012R2. It fails when executing:
new System.Printing.PrintServer(#"\\printserver");
It throws:
System.Exception: An exception occurred while creating the PrintServer
object. Win32 error: The printer name is invalid.
printserver is not an alias but a hostname. It loads correctly on Windows Explorer. The same line works fine on a regular Console Application when compiling under the same .NET 4.5.2, and also in PowerShell when loading the System.Printing.dll. The GAC shows the right assemblies, and I've also added them manually just in case.
I've set the same application pool configuration settings from the working WS2008 (disabled 32-bit applications and Classic mode), but I've tried different combinations in any case. The application pool runs under the same domain service account on both old and new.
As some user also suggested, I've installed the Print and Document services role, even though the old server doesn't have it, but to no avail.
I'm out of ideas, any kind of help would be greatly appreciated. Thanks!
Not really a solution... But I "fixed" this by changing the path of the website in IIS manager back and forth a couple of times. Yes, after a year of trying all I could think of on several servers.
Anyway, not sure what exactly unblocked the situation, but it works for me.

Silverlight 5 with elevated privileges in browser using clientaccesspolicy.xml

I am trying to get my silverlight application running with elevated privileges in browser. However, no matter what I do, it doesnt get elevated.
I have tried to add registry key AllowElevatedTrustAppsInBrowser (as DWORD with value 1), and signed the XAP file using VS 2012. I also came across a blog that mentioned the clientaccesspolicy.xml file, but I was not able to allow elevated privileges with this either. I put the xml file inside the web project hosting the html file that displays the XAP.
Has anyone actually managed to get this to run?
I also tried following this: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2011/04/27/silverlight-5-beta-rough-notes-trusted-apps-in-the-browser.aspx but im unsure about where to run the commands he runs on windows.
There is a good summary on how to enable in-browser elevated trust by Mister Goodcat here, where he also provides some troubleshooting tips:
One thing to keep in mind is that even if your application runs as trusted in-browser app, it is still subject to the security restrictions the browser itself imposes. That means that its possibilities may be much more restricted than if they ran out of browser, for example by Internet Explorer's Protected Mode. In addition, the Silverlight runtime itself restricts use of certain features for in-browser trusted apps, for example you cannot use the Window class and/or create additional windows when you're running in the browser.
If none of the above applies to you and you still run into problems, one thing to do is check whether your certificate(s) have been installed correctly. There's a snap-in for the management console for this. Here is an article that describes how to get there (note that you should add a snap-in for your user account, not the computer account as in this description).
You can also check whether your registry key is actually and successfully queried, for example by using a tool like Process Monitor from the Sysinternals Suite. Watch for operations of type "ReqQueryValue" of your browser executable that access the key we created above, and make sure the Result is "SUCCESS".

Calling a remote .NET DLL inside COM+ without the proxy installation

We have a three tier application entirely developed in .NET 4.0 (C#). As the enterprise application server we use COM+ 1.5 (I know it's a little bit legacy...). There are a server part and a client part both developed in C# for .NET 4.0.
The server part exposes services inheriting the ServicedComponent class and returning objects which implement the "Serializable" attribute. The client calls the remote classes via the COM+ exported proxy of the component. We distribute the client app through ClickOnce and we have to install, with Admin privileges, the COM+ generated Proxy onto every client machine. This is the bad point.
So we are trying to evaluate other techniques which allow us to eliminate this proxy installation but it's not so clear how to do this. We'd like to find a low impact way that allow us to use the same COM+ part and including in some way the Proxy into the client side code.
We have tried to use code like this in the client part but still requires the COM registration.
Type comObjectType = Type.GetTypeFromProgID("SumNameSpace.SumClass", "servercomplus", true);
SumInterface comObject = Activator.CreateInstance(comObjectType) as SumInterface;
We thought that using in the client part the interface instead the class would have to work, but we have the exception:
Runtime.InteropServices.COMException (0x800401F3): Invalid class string (Exception from HRESULT: 0x800401F3 (CO_E_CLASSSTRING))
This error should happen if there aren't the correct information about the Interface in the Windows Registry, but we don't know...
Any idea?
thanks a lot
There's no question you need the COM+ proxy installed on all the client machines, and you want to install it with the proxy installation package. The error you're getting is the result of the missing ProgID entry under the HKEY_CLASSES_ROOT hive in the registry. This registry entry, among others, is provided by the installation package. This isn't all the the proxy installer provides; I found a pretty good overview here.
It sounds like what you are really looking for is to create a custom application manifest for your ClickOnce deployment. This should allow you to bundle the proxy installer as a bootstrap prerequisite into your ClickOnce deployment. However the install will still require administrative permissions; I don't see a way around that (see note below). Here is a link to a tool that works with ClickOnce manifests that was created by Stackoverflow user Greg Jackman. I don't have any experience with this, but based on Greg's post it looks like it may be helpful to you.
One final note: even if you do find a way to run the installation package as a non-elevated user, you don't want to do that. Running non-elevated will change the way the package interacts with the registry. Short story, it will fail silently.
Use group policy to distribute the components?

Error with Excel and C# when logged off the server

I have written a Windows Service in C#. My service is meant to open an Excel macro-enabled workbook (this is in Excel 2010). I have installed this service on our server which is running Windows Server 2008 64-bit. My service seems to have a problem launching Excel when no one is logged on the server, does anyone have a solution to this?
I get the following error:
System.Runtime.InteropServices.COMException (0x8000401A): Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 8000401a.
Excel is installed on the server, the service works fine when I am logged on the server but once all users have logged off, I get the above error. I would like the service to launch my Excel workbook regardless of an open session on the server or not.
My service seems to have a problem launching Excel when no one is logged on the server, does anyone have a solution to this.
Of course it has a problem. Windows Services cannot show a user interface, so how would you expect it to launch a GUI application like Microsoft Excel when there is no user logged in?
The specific COM error code that you receive means:
8000401a: The server process could not be started because the configured identity is incorrect. Check the username and password.
In other words, Excel is trying to start as an interactive user, which refers to the user that is currently logged on directly to the server console. Since no user is logged on, no interactive user exists, and the application fails when it tries to assume this identity.
The design was broken anyway: Excel was not designed to be run from a Windows Service. Create a standard Windows application instead. If you need it to run in the background without a UI of its own, don't create a window.
Basically, Cody Gray's answer is right. In the past I had a need to launch Excel from a Windows Service in order to print the file.
We were able to get past that kind of errors by setting the service to run as a specific user account and from time to time, log on as that user account and try to launch the files that failed to see the error messages popped up by Excel.
In your case, it is possibly because Excel is started for the first time and it asks you for something like your initials.
Are you using Office Automation to start Excel? Sorry, but Office Automation is not supported in service processes. It is designed to work only in an interactive process.
If you're lucky, Using Office Automation from a service process won't work. If you're not lucky, it will appear to work, and you'll actually put your application into production. You'll then start finding random bugs which are very difficult to reproduce, and even more difficult to fix without breaking something else.
That will be due to the fact that the real bug is a design bug - you used Office Automation from a service process.
Take it from the Voice of Experience...

Microsoft Access required for C# database access on end-user machines?

Silly question, perhaps.
I've developed an app on my machine that uses a Microsoft Access database (.mdb) to access certain information and populate a table with monitoring data using OLEDb.
The application works fine on my machine, but when I put the release on test machines (without MS Access), it crashes. Interestingly, if I were to launch the application on the testing machine with the database filename just renamed, it loads like it should albeit without the data.
I seem to get an UnauthorizedAccessException exception thrown which further clouds my confusion.
Both the development machine and the machine I'm testing it on have .NET 3.5 installed.
I would expect a barage of 'No's in reply to my question, but what the heck - does the testing machine need to have MS Access installed?
Regards
Try downloading the Office Connectivity Components here. This will let you read and create Access databases without having Access installed.
It doesn't need MS Access but you will need the required driver for your version of Access. You may need to do a test release that outputs to a log the exact Exception and message.
Make sure you have latest Jet 4 OLEDB drivers installed. There might also be a problem if you run the application from a network share (then it runs with restricted rights).
You say you got an UnauthorizedAccessException. I'd check read/write permissions to the .mdb file and location first.
If you're running as a service remember that they run under more restricted accounts.
You don't need Access itself. You will need to have JET drivers and associated files at least as current as the ones on your development machine — if you're recycling an old machine to use for testing that could be the problem.
However, this really sounds like a permissions issue, either on the database file itself or inside the file if you're using Access's security mechanisms.
It turns out the issue was a hardware problem. One of the serial ports on the card I was using had gone capput when it got moved to a new machine.
Turns out the problem wasn't database related, as the exception would've suggested.
Some interesting points on JET were raised though, which could be useful to anyone with Database access issues.
Thanks for your help guys.

Categories