C# Winforms Exception from HRESULT: 0x80040154 - c#

I have a winforms application which works perfectly in my x64 Win 7 dev environment but I cannot get the Outlook feature to work at all on the x86 XP machine, I keep getting this error when I try to open up a new Outlook mail with the address/subject line pre-filled in from the application side.
This only started happening since adding the reference to: Microsoft.Office.Interop.Outlook
This is the code used to create a new mail:
private void CreateOutlookEmail(string addresses)
{
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = "";
mailItem.To = addresses;
mailItem.Body = "";
mailItem.Display(false);
}
I have been searching the forums for an answer but no luck thus far. Here is what I have tried without success:
Set the platform target to x86 in project properties in VS2010
Install the OWC11 binaries.
Install all windows updates on the win XP machine.
Must I install other packs on the XP machine?

You need to install the Primary Interop Assemblies on the system. This happens automatically on your development system since they are installed with VisualStudio. Other systems will not necessarily have them installed.
Better yet, you should probably be deploying with an installer - this would take care of the dependencies for you.
How to: Install Office Primary Interop Assemblies (MSDN)
Microsoft Office 2010: Primary Interop Assemblies Redistributable (download)
2007 Microsoft Office System Update: Redistributable Primary Interop Assemblies (download)
Office 2003 Update: Redistributable Primary Interop Assemblies (download)
See Also : How to: Install the Visual Studio Tools for Office Runtime Redistributable (MSDN)

Related

Cannot add reference to Outlook 2016 (Office 365) Interop (16.0.0.0)

I'm trying to add a reference to 'Microsoft Outlook 16.0 Object Library' in a C# .NET 4.6.1 WPF project, because I have office 2016 installed. Previous versions of the Object Library are incompatible with the 2016 version of office.
If I use Excel's VBA editor, 'Microsoft Outlook 16.0 Object Library' is listed, and exists in C:\Program Files\WindowsApps\Microsoft.Office.Desktop_16010.9126.2116.0_x86_8wekyb3d8bbwe\VFS\ProgramFilesCommonX86\Microsoft Shared\OFFICE16\MSOUTL.OLB, as you can see below:
However, when I use Visual Studio, the COM tab does not list 'Microsoft Office 16.0 Object Library', and when I try to browse to C:\Program Files\WindowsApps, i get 'You dont currently have permission to access this folder', and clicking 'Continue' (to get access) results in 'You have been denied permission to access this folder'.
So basically, the Office 2016 dlls seem to have been tucked away in a folder that is inaccessible to man, dog, and local administrator.
All I'm trying to do is connect to the open Outlook application, and then send an email with an attachment, so perhaps another question to ask is, is there some new fangled way to communicate with Outlook 2016 that hasn't cropped up in my Googleathon?
Also worth noting is that my version of office is installed as a 'Windows Store Application' and therefore does not appear on the usual Add/Remove programs list, so I can't find any 'repair' options for the installation.
Thanks.
Further investigation reveals that I am doing the right thing - trying to add a COM reference to 'Microsoft Outlook 16.0 Object Library' is now the correct way to target Outlook ... https://stackoverflow.com/a/21018418/5040941.
I've checked the GAC, and the assemblies aren't registered. I've done a repair via the 'Apps and Features' right-click start menu option, and they still aren't appearing - it's as if the Windows Store apps just shove their dlls into the Program Files\WindowsApps\* folder, and don't bother to register them in the GAC.
In answer to the much appreciated comments!
Using the following code
Outlook.Application application = (Outlook.Application)Marshal.GetActiveObject("Outlook.Application");
If I use the nuget Microsoft.Office.Interop.Outlook package, i get a System.Runtime.InteropServices.COMException: 'Invalid class string (Exception from HRESULT: 0x800401F3 (CO_E_CLASSSTRING))' exception.
If I try using Microsoft Outlook 15.0 Object Library or Microsoft Outlook 14.0 Object Library references via the Assemblies/Extensions tab of Add Reference, I get a System.Runtime.InteropServices.COMException: 'Invalid class string (Exception from HRESULT: 0x800401F3 (CO_E_CLASSSTRING))' exception.
I don't think accessing the WindowsApps folder is the way to go.
Firstly, it's locked down for some reason which typically indicates the potential for trouble if i start digging around and changing security permissions, not to mention the fact that maintaining a copy of the latest dll in my solution will undoubtedly add unnecessary complexity to my project.
Secondly, but more importantly, if I have office installed, and I can access 'Microsoft Outlook 16.0 Object Library' from Excel Vba, then why can't I access it from Visual Studio?
There is obviously some issue with the installation not registering the dlls properly, only Excel has some trick it uses to make the reference available anyway.
Has anyone reading this managed to install Office 365/2016 Windows Store and found a reference to 'Microsoft Outlook 16.0 Object Library' in Visual Studio?
Am I the only with this problem?! Because it affects multiple computers in my office running Windows 10 and Office 365 ...
In answer to RogerN (thanks), please see the image below - I don't have Microsoft.Office.Interop.Outlook version 16 listed, and Microsoft.Office.Core isn't listed either.
If I try to use the v15 library, I get the following error:
System.Runtime.InteropServices.COMException
HResult=0x80040154
Message=Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
Source=mscorlib
*AND THE ANSWER IS *
The two computers I bought from Dell are 64 bit, but they come preinstalled with 32 bit, windows store versions of MS Office 2016/365.
In order to fix the problem, I had to:
uninstall the store app from Settings > Apps > Apps&Features > Microsoft Office Desktop Apps > Uninstall
log into portal.office.com
select install office apps, advanced, choosing the 64-bit version
Quite why Dell think we want 32 bit versions installed on 64 bit machines, or why someone from Microsoft hasn't posted a solution to this problem, is beyond my understanding, but nevertheless, RogerN was correct. Thanks to everyone for taking time out their days to help me out.
Elaborating on my earlier comment: From what you've described, it sounds like you've installed a 32-bit version of Microsoft Office on a 64-bit machine. Only 32-bit COM objects would have been registered, and therefore a 64-bit .NET application would be unable to find them. If you search your registry, you ought to find that the 0006F03A-0000-0000-C000-000000000046 class ID is only registered under the Wow6432Node.
To resolve the issue, you could either install the 64-bit version of Office or force your .NET application to target the x86 platform.

Does Primary Interop Assemblies ( PIA ) require Microsoft Office to be installed in the machine to work

Does Primary Interop Assemblies ( PIA ) require Microsoft Office to be installed in the machine to work ?
I have gone through so many confusing post/sites and unable arrivie at a conclusion.
I have a machine where office is not installed and I am using VS2010 . As Microsoft.Office.Interop.Excel assembly was not avaialble in COM section in referance . I add it through thought .Net section in referances . Still it throws the below error .
Retrieving the COM class factory for component with CLSID failed due
to the following error: 80040154 Class not registered (Exception from
HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
This is statement from Mircosoft website , The Office PIAs are not required on end-user computers to run Office solutions . What does this mean exactly ?
Does it mean without Office installation we can work with interop assemblies ?
If not why we require PIA when office needs to be installed to get things work ?
This is statement from Mircosoft website , The Office PIAs are not required on end-user computers to run Office solutions . What does this mean exactly ?
That's not the current quote I find. The one I find is:
The PIAs must also be installed on end-user computers to run Office solutions that target the .NET Framework 3.5. However, the Office PIAs are not required on end-user computers to run Office solutions that target the .NET Framework 4. For more information, see Designing and Creating Office Solutions. (https://msdn.microsoft.com/en-us/library/vstudio/hy7c6z9k(v=vs.100).aspx)
It means (for net 4+) that when you create an Office Solution in VS usint PIAs, you do not need to install those PIAs on the target computer to be able to run the solution. (the reason is because, if you've targeted Net4, if the Embed Interop Types property of each Office PIA reference in the project is set to True (this is the default value), the type information for the PIA types that are used by your solution is embedded into the solution assembly when you build the project. At run time, the embedded type information is used instead of the PIAs to call into the Office application's COM-based object model. For more information about how types from PIAs are embedded into your solution (https://msdn.microsoft.com/en-us/library/vstudio/3295w01c(v=vs.100).aspx)
For example: I want to write a program in VB to doSomething on an XLSX sheet.
I have to install Excel, PIA, and VS on my development machine or I will not be able to write it.
Once this program is finished, I want Bob in accounting to run it. So I publish the program and it gets installed on Bob's machine. Bob will not need to have installed PIAs on his local machine to run the program. He will need office.
Does it mean without Office installation we can work with interop assemblies ?
The other way around. It means, with Net 4+ applications using PIA (EIT), your application can work without PIAs installed on the client machine (the needed pieces will be part of your deployment).
Does Primary Interop Assemblies ( PIA ) require Microsoft Office to be installed in the machine to work ?
Yes.
The PIA are simply assemblies that allow you to call the Office COM object model from .NET. The COM objects which are hosted by the Office applications still need to be present for this to work. The Class not registered error you get is because the COM object is missing on the computer. To fix that you need to install the version of Office your application is designed to work with.
Your question really has two parts:
What does a developer need to develop an application that makes use of Office components?
What does an end user need to run that application?
On MSDN, the article Office Solutions Development Overview (Visual Studio 2013) provides concise guidance for these questions. From the section "Automating Office Applications by Using Primary Interop Assemblies":
You must have the Office PIAs installed and registered in the global
assembly cache on your development computer to perform most
development tasks. For more information, see Configuring a Computer
to Develop Office Solutions. The Office PIAs are not required on
end-user computers to run Office solutions. For more information, see
Designing and Creating Office Solutions.
The first article makes it clear that the developer must install Microsoft Office:
To create add-ins and customizations for Microsoft Office, install a
supported version of Visual Studio, the .NET Framework, and Microsoft
Office.
And from the latter article in the section "Understanding When the Office PIAs Are Required on End User Computers":
By default, Office primary interop assemblies (PIAs) do not need to be
installed on end user computers if the Embed Interop Types
property of each Office PIA reference in the project is set to
True, which is the default value. In this scenario, the type information for the PIA types that are used by your solution is
embedded into the solution assembly when you build the project. At run
time, the embedded type information is used instead of the PIAs to
call into the Office application's COM-based object model. For more
information about how types from PIAs are embedded into your solution,
see Type Equivalence and Embedded Interop Types.

Avoid errors using Interop if the COMponent aren't installed

"If you want to use Interop, then the component should be installed in
the system. Otherwise, it won't work."
I have a WinForm application, that is used by many users in several SO (WinXP, Win7, Win8.1, WinServer 2008, WinServer 2012)
In development, I use a COM component (Outlook, SpeechLib,...).
Two keys:
Some users cannot installed the component. Or they haven't installed it.
Another users can be installed the component.
Any programatically way to:
avoid the application fails for the users that hasn't installed the component
the application works for the users that has installed the component
?
Notes:
Programmatically way to determine whether a particular COM library DLL has been installed or is installed. Anyways, if a particular COM library not installed, the target is that my source code not fails in runtime in that machine without that COM installed.
For example, for Excel, Word, Outlook COM (ActiveX), SpeechLib (Microsoft Speech Object Library), etc
I could have source code like this:
SpeechVoiceSpeakFlags SpFlags = SpeechVoiceSpeakFlags.SVSFlagsAsync;
SpeechLib.ISpeechVoice speech = new SpeechLib.SpVoiceClass();
// ....
Or anyways using Outlool application class, or Excel.Application, etc.
Type officeType = Type.GetTypeFromProgID("Excel.Application");
if (officeType == null)
{
// Excel is not installed.
// Show message or alert that Excel is not installed.
}
else
{
// Excel is installed.
// Continue your work.
}
My old issue, but not solution:
Detect Outlook installed and load dynamically INterop.Outlook
Detect Outlook installed and load dynamically INterop.Outlook
I have a Windows Forms application in VS2010. It has a reference to
Interop.Outlook (2003). Then, I have reinstalled Windows XP and
VS2010, but not install Outlook.
Now, the project not compiles.
I think this, my application will not work if Outlook not installed in
machine that my program executes on.
I need to know if I detect Outlook installed, and load dynamically
Interop.Outlook.dll (for using the Outlook PIA or Embedded Interop
types in .NET 4).
If the machine has Outlook (2003, 2007, 2010, perhaps need code to
detect version and do compatibility of Outlook versions) installed,
the application works fine with functionally Outlook.
If the machine hasn’t Outlook installed, (in runtime) the application
works fine without functionally Outlook. I think, If the machine
hasn’t Outlook installed, (in runtime) the application fails because
references (in source code) to Outlook.Application class?.
In development machine, the application works because Outlook (and
COM) is installed in the machine.
Any sample source code or goog patterns and practices about it??
References
Does this code fails if Office not installed in machine ?
How to detect installed version of MS-Office?
http://www.codeproject.com/Tips/679027/How-to-Check-Whether-Excel-is-Installed-in-the-Sys?msg=5027820#xx5027820xx
How to check, programatically, if MS Excel exists on a pc?
http://codeblog.jonskeet.uk/2009/07/07/faking-com-to-fool-the-c-compiler
I posted this elsewhere, but here's the code to detect if Outlook is installed. Basically, it tries to get the Outlook automation object.
using System;
using Microsoft.Office.Interop.Outlook;
class Program
{
static void Main(string[] args)
{
var outlookType = Type.GetTypeFromProgID("Outlook.Application");
if (outlookType == null)
{
Console.WriteLine("Not installed.");
}
else
{
var app = Activator.CreateInstance(outlookType) as Application;
Console.WriteLine(app.Name);
}
}
}
For SpeechLib, I think the right way to detect it is to just try and create a "new SpVoice()" instance wrapped with a try/catch. If it fails, then assume speech is not installed. Again, embedding the interop will allow you to avoid runtime type load issues.
Hope that helps.

Vsto Word: After install, error: could not load assembly

I've made a vsto for word, that uses the dll : Microsoft.SharePoint.Client.Runtime.dll. The vsto runs perfect on my (dev) machine and then VS2013/rigtclick/properties/publish.
For the user's PC (Xp + office 2010, install the app) I get the error: could not load assembly Microsoft.SharePoint.Client.Runtime.dll.
How can I solve/bypass this error?
Thank you
p.S.This is my first VSTO, so newbie errors are highly propable
My guess would be that the client computer doesn't have the correct libraries installed. I doubt that having Office 2010 installed will give you the Microsoft.SharePoint.Client.Runtime dll.
You'll probably need the 'SharePoint Foundation 2010 Client Object Model Redistributable' installed on the client machine.
From the most voted answer in this thread:
Which SDK do I need to start using sharepoint.client.dll?

Detect Outlook installed and load dynamically INterop.Outlook

I have a Windows Forms application in VS2010. It has a reference to Interop.Outlook (2003). Then, I have reinstalled Windows XP and VS2010, but not install Outlook.
Now, the project not compiles.
I think this, my application will not work if Outlook not installed in machine that my program executes on.
I need to know if I detect Outlook installed, and load dynamically Interop.Outlook.dll (for using the Outlook PIA or Embedded Interop types in .NET 4).
If the machine has Outlook (2003, 2007, 2010, perhaps need code to detect version and do compatibility of Outlook versions) installed, the application works fine with functionally Outlook.
If the machine hasn't Outlook installed, the application works fine without functionally Outlook.
Any sample source code or goog patterns and practices about it??
To detect if Outlook is installed, look for the "Outlook.Application" ProgID.
From an installer, look in the registry for HKEY_CLASSES_ROOT\Outlook.Application
At runtime, you can do this:
using System;
using Microsoft.Office.Interop.Outlook;
class Program
{
static void Main(string[] args)
{
var outlookType = Type.GetTypeFromProgID("Outlook.Application");
if (outlookType == null)
{
Console.WriteLine("Not installed.");
}
else
{
var app = Activator.CreateInstance(outlookType) as Application;
Console.WriteLine(app.Name);
}
}
}
To avoid the problem of dynamically loading the interop, you should set Embed Interop Types to true for Microsoft.Office.Interop.Outlook.Interop.dll
check the Installer APIs to detect the install state of Outlook or use one of the method described here.

Categories

Resources