I have been trying to use IConverterSession to convert from EML to MSG (MIME to MAPI), but I keep stumbling on COM errors.
I use a C# MAPIMethods class to wrap IConverterSession (like the one found here : Save Mail in MIME format (*.eml) in Outlook Add-In).
First, I had the problems of unknown clsid, solved with this post (https://blogs.msdn.microsoft.com/stephen_griffin/2014/04/21/outlook-2013-click-to-run-and-com-interfaces/).
Now that the proper registry keys have been edited, I face a new problem: first, I get an error message The operating system is not presently configured to run this application, and I get a COMException: Retrieving the COM class factory for component with CLSID {4E3A7680-B77A-11D0-9DA5-00C04FD65685} failed due to the following error: 8007013d The system cannot find message text for message number 0x in the message file for . (Exception from HRESULT: 0x8007013D).
My code is :
Type converter = Type.GetTypeFromCLSID(MAPIMethods.CLSID_IConverterSession, true);
object obj = Activator.CreateInstance(converter);
MAPIMethods.IConverterSession session = (MAPIMethods.IConverterSession)obj;
The error is raised on "object obj = Activator.CreateInstance(converter);"
A COMException normally means that "type is a COM object but the class identifier used to obtain the type is invalid, or the identified class is not registered.". So either Type converter = Type.GetTypeFromCLSID(MAPIMethods.CLSID_IConverterSession, true); does not return the proper type, or there is still a registry key missing somewhere.
I am using Office 15 (2013) C2R 32 bits on Win 64bits. The application is setup on an x86 build configuration.
Is there something I am missing somewhere? Can anyone help?
"The operating system is not presently configured to run this application" - it sure sounds like your app is compiled as x64 on a machine with a 32 bit version of Outlook.
Have you tried to use Redemption? It wraps IConverterSession for .Net languages. Something like the following should do the job.
using Redemption;
...
Redemmption.RDOSession session = new Redemmption.RDOSession();
Redemmption.RDOMail msg = session.CreateMessageFromMsgFile(#"c:\temp\test.msg");
msg.Import(#"c:\temp\test.eml", Redemption.rdoSaveAsType.olRFC822);
msg.Save();
olRFC822 format will use IConverterSession if it is available or the internal Redemption converter if IConverterSesison is not available (e.g. under Exchange version of MAPI or the latest versions of Outlook 2016 C2R where IConverterSession cannot be used).
Use olRFC822_Redemption or olRFC822_Outlook if you always want to force Redemption or Outlook (IConverterSession) converter.
Related
I'm having a similar problem to this question in getting a pair of "custom" MAPI properties from a MailItem in a C# console app, but with the extra twist that it works locally but not on the server.
The two properties are PR_SERVERID and PR_MSGID and both are available on the mailitems when inspected via MFCMAPI, I'm accessing them as follows:
MessageDetails.PR_SERVERID = Message.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/PR_SERVERID").ToString();
MessageDetails.PR_MSG_ID = Message.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/PR_MSGID").ToString();
Where Message is of type Outlook.MailItem. When I run this locally (from built exe or in debug) it works but on a separate server the exact same message fails with:
15:17:26 Error getting getting MAPI properties from the stub:
System.ApplicationException: System.Runtime.InteropServices.COMException (0x8004010F):
The property "http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/PR_SERVERID" is unknown or cannot be found.
Before this, I am successfully retrieving two "standard" MAPI properties (PR_CREATOR_NAME and PR_INTERNET_MESSAGE_ID) from the same item so the MailItem is accessible.
The DASL for the properties shown in MFCMAPI is identical between the two servers and my local machine and both are running Outlook 2010 and accessing the mailItem by invoking an Outlook session.
The only thing I could think of was that Outlook itself is unable to recognise the custom properties without some configuration that's missing on the remote server(s), does Outlook have to have a property configured at the namespace level for it to be recognised even if identified by a DASL?
Edit: Additional information on the mail items:
The mails are "stubs" downloaded from an archive system, the two attributes then provide the identifier for the "full" message content. I'm downloading the stub from the remote server, saving it locally and then accessing each stub in the set using:
Outlook.NameSpace NS = _outlookApplication.GetNamespace("MAPI");
Object item = _outlookApplication.Session.OpenSharedItem(MessageDetails.FilePath)
Outlook.MailItem Message = (Outlook.MailItem)item;
And attempting to add the two properties to the MessageDetails object by getting the properties from Message.
Edit 2:
I've noticed that when retrieving the properties on a "fresh" host, I get a security prompt for "a program is trying to access e-mail address information stored in Outlook" when I access the custom properties but not when I access the subjectline/sender etc. from the standard properties. The seems to indicate that there is something about these custom properties that is "different" when accessed via COM interop using outlook. Nevermind, this is simply default protection on calling PropertyAccessor.GetProperty.
Answer:
Dmitry is spot on and I have marked his response as the answer, the properties were not accessible because they had never been created on the store. With user machines these have been created because at some point we "archived" mails into the remote store and set the custom properties on the stubs left in our mail boxes. On the servers this had never been done so I added an option for a "first run" that creates a dummy object, sets two empty custom properties on it, saves it then deletes it. Subsequent runs are then able to access the properties using PropertyAccessor.GetProperty.
Outlook Object Model always assumes PT_UNICODE / PT_STRING8 type for the properties in the "string" namespace. The type in your case is PT_LONG (0x0003).
As a test, can you install Redemption (I am its author) and try the following script from OutlookSpy (I am also its author - click Script, paste the script, click Run)
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Msg = Session.GetMessageFromMsgFile("c:\temp\yourmsg.msg")
MsgBox Msg.Fields("http://schemas.microsoft.com/mapi/string/{00020329-0000-0000-C000-000000000046}/PR_SERVERID/0x00000003")
UPDATE
Try the following script in OutlookSpy on a machine where your code fails. When the IMessage window pops up, do you see the named properties?
set msg = Application.Session.OpenSharedItem("c:\temp\yourmsg.msg")
BrowseObject(msg.MAPIOBJECT)
I would guess that the interface defined by {00020329-0000-0000-C000-000000000046} is not installed on the server. Search for it (e.g. using Regedit) on your machine where it works, and note what dll it is associated with (this will be in the InprocServer32 sub key as the default property. Then do the same on the server: it will probably not find the CLSID at all.
If this is the case, then you need to install the missing dll - and all its dependencies which means the package it was wrapped up in.
I searched many examples of how to consume webservices methods with C#,
but all of them say to right click and add a service reference and type the address.
However I dont know why, but the webserver wich I am trying to connect does not work with this...
Here the address
https://bauru.sigiss.com.br/bauru/ws/sigiss_ws.php?wsdl
Can someone help me how could I interact with this specific webservice?
Using the WcfTestClient1 shows an error (that is probably the one you're running in to on an import):
Error: Cannot import wsdl:portTypeDetail: The ' ' character, hexadecimal value 0x20, cannot be included in a name.Parameter name: nameXPath to Error Source: //wsdl:definitions[#targetNamespace='urn:sigiss_ws']/wsdl:portType[#name='WebService SigISSPortType']Error: Cannot import wsdl:bindingDetail: There was an error importing a wsdl:portType that the wsdl:binding is dependent on.XPath to wsdl:portType: //wsdl:definitions[#targetNamespace='urn:sigiss_ws']/wsdl:portType[#name='WebService SigISSPortType']XPath to Error Source: //wsdl:definitions[#targetNamespace='urn:sigiss_ws']/wsdl:binding[#name='WebService SigISSBinding']Error: Cannot import wsdl:portDetail: There was an error importing a wsdl:binding that the wsdl:port is dependent on.XPath to wsdl:binding: //wsdl:definitions[#targetNamespace='urn:sigiss_ws']/wsdl:binding[#name='WebService SigISSBinding']XPath to Error Source: //wsdl:definitions[#targetNamespace='urn:sigiss_ws']/wsdl:service[#name='WebService SigISS']/wsdl:port[#name='WebService SigISSPort']Warning: No code was generated.If you were trying to generate a client, this could be because the metadata documents did not contain any valid contracts or servicesor because all contracts/services were discovered to exist in /reference assemblies. Verify that you passed all the metadata documents to the tool.Warning: If you would like to generate data contracts from schemas make sure to use the /dataContractOnly option.
I don't know enough about the service, but you may take a look at Can I create an element with forward slash as part of the name and find it's probably an attribute being used to decorate a property (which has a space in it).
1 WcftestClient can usually be found in C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\
If for whatever reason you can't get to it (e.g. a proxy server is used where you're working) then simply go to the WSDL in your browser, save the page as an XML file on disk, and when adding a service reference again don't put in the web URL, put the path to it on disk (e.g. C:\temp\wsdl.xml).
Finally I got someone who had the exaclty same problem as I did! He said to do the following:
For Windows Vista, Windows 7 e Server 2008:
Start>Run
Regedit
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/SecurityProviders/Schannel/Protocols
Right Click on Protocols -> New -> Key
Name: TLS 1.0
Right Click on the new key -> New -> Key
Name: Client
Select the created folder (Client), right click New -> Value DWORD
Name: Enabled
After that just add the reference to your project. To avoid happening the same in your app users, force the SSL use before instanciate the webservice:
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Ssl3;
I am building an application in C# using visual studio 2010 on windows server 2008, the application is to use directshownet the .net wrapper of direct show to access the system's web camera to get the video stream but the application is generating this error
Retrieving the COM class factory for component with CLSID {C1F400A0-3F08-11D3-9F0B-006008039E37} failed due to the following error: 80040154.
the source code is below
public Capture(int iDeviceNum, int iWidth, int iHeight, short iBPP, Control hControl)
{
DsDevice[] capDevices;
// Get the collection of video devices
capDevices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
if (iDeviceNum + 1 > capDevices.Length)
{
throw new Exception("No video capture devices found at that index!");
}
try
{
// Set up the capture graph
SetupGraph(capDevices[iDeviceNum], iWidth, iHeight, iBPP);
//// tell the callback to ignore new images
m_PictureReady = new ManualResetEvent(false);
}
catch
{
Dispose();
throw;
}
}
the code throws the error whenever it reaches this line
SetupGraph(capDevices[iDeviceNum], iWidth, iHeight, iBPP);
please people help me out, I have googled it but couldnt find a solution
That guid is associated with a capture device with the name "Sample Grabber". It is declared in an SDK header named qedit.h, docs are here. Note the deprecation warning, qedit.h is no longer part of the Windows SDK and I don't have it installed on my Windows 7 machine.
It sounds like you have a slight case of registry corruption, possibly induced by a Windows upgrade. With the Sample Grabber filter still enlisted as a device but the actual filter no longer registered. No idea how to fix this damage, ask at superuser.com. These kind of mishaps are however likely to occur on your user's machine as well. Do catch the exception and continue looking for another available capture device.
You may want to try to compile your project explicitly in x86 mode instead of Any and see if that fixes the issue. It's also possible you are missing a required DLL on your machine.
I have a VB6 Active DLL that I'm trying to call from C#.
I've converted it using tblimp and imported it into VS 2010.
I then instantiate it using:
AppWebActiveX.Users appWebActiveX = new appWebActiveX.Users();
There's a Users interface and a UsersClass class when I look in the object browser.
Then I call:
bool isExistingUser = appWebActiveX.IsExistingUser("cat");
bool IsExisting(string) is a valid method, according to the object browser.
However, this returns:
Unable to cast COM object of type 'AppWebActiveX.UsersClass' to interface type 'AppWebActiveX._Users'. ... No such interface supported ...
The latest stack call is to System.StubHelpers.StubHelpers.GetCOMIPFromRCW.
I'm running the app on Windows Server 2003 Standard Edition (x86 - 32bit) and it's a 32-bit DLL. I'm making the call from a C# console app.
Any advice?
Turns out that I'd omitted the [STAThread] attribute from the main method.
I have a COM server, implemented in C#. It exposes a class decorated like this:
[ComVisible(true)]
[ProgId("MyServer.MyClass")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
I registered the DLL with "regasm /codebase MyServer". This server must be used from a WSC (a COM server implemented in JScript). Therefore I used the AutoDispatch interface.
When the WSC calls
o = new ActiveXObject("MyServer.MyClass");
I get the error "Automation serve can't create object".
I checked the registration of the COM server with this C++ program:
hr = ::CoInitialize(NULL);
hr = ::CLSIDFromProgID(L"MyServer.MyClass", &clsid);
hr = ::CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&pObj);
and was able to create the object. All return values have been checked to be S_OK.
What is needed to make the COM server accessible for JScript?
If the problem is x64, see the answer of Hot to make COM ActiveX object work in IE 64 bit?
Are the types used in your class ole automation compatible? I don't know if jscript checks for oleautomation compatibility up front.