|
Hello
With the help of coffee and guesswork I've managed to use COM and Interop to open an Outlook .msg file and extract content from it. I have Outlook 2007 installed and I'm using Microsoft.Office.Interop.Outlook PIA runtime version 2.0.50727 (Version 14.0.0.0)
I'm using .NET 4 in a WPF application.
My problem is that my code starts an Outlook process but does not close it down afterwards. If I am already running Outlook, my code seems to attach to that process rather than start another one and if outlook is already running, my app.Quit() message closes the existing Outlook application (not the process.)
My question is am I going about this in the wrong way? I've read lots of posts about using Outlook but nothing that describes with authority how I should cleanly open, interrogate and close an outlook message.
Here's the code:
public override void ViewContent(string strFilePath)
{
base.ViewContent(strFilePath);
Microsoft.Office.Interop.Outlook.Application app = null;
Microsoft.Office.Interop.Outlook.NameSpace session = null;
Microsoft.Office.Interop.Outlook.MailItem item = null;
try
{
app = new Microsoft.Office.Interop.Outlook.Application();
session = app.Session;
item = session.OpenSharedItem(strFilePath) as Microsoft.Office.Interop.Outlook.MailItem;
if(item != null)
{
Subject = item.Subject;
From = item.SenderName;
if(string.IsNullOrEmpty(item.SenderEmailAddress) == false)
From += "{" + item.SenderEmailAddress + "}";
MessageText = item.Body;
item.Unload += new ItemEvents_10_UnloadEventHandler(item_Unload);
item.Close(OlInspectorClose.olDiscard);
}
app.Quit();
}
catch(Exception)
{
}
finally
{
if(item != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(item);
if(session != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(session);
if(app != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
item = null;
session = null;
app = null;
}
}
Is this the right way to use COM and Interop? Does anyone have any pointers for me or a guide showing best practices? I'm new to COM so if anyone thinks my code is going to leak or use up handles or some other horror please let me know.
Thanks all,
Keith
|
|
|
|
|
So, I had asked the question in the subject itself: Is COM an 'outdated' technology?
If it is, what are the technologies that replace COM? And how?
If it is not, why such an old technology is still there? (I understand the basic design of COM and I understand why it was needed back then.)
I am hoping to see a discussion emerging about this, in the hope that I will be able to learn a lot.
|
|
|
|
|
krumia wrote: I am hoping to see a discussion emerging about this,
This forum is not the place for discussions, it's for technical questions; try the Lounge.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I thought of posting this in the lounge, but all the same this is where most the COM experts gather, I suppose.
I have asked what I felt as a technical question anyway: Is COM an 'outdated' technology?
having asked the technical question in the technical forum, I don't think 'hoping to see a discussion' is a sin. After all, the boundary between question-answer session and discussion is unclear.
Anyway, I will re-post this in the lounge. Thanks for the hint.
|
|
|
|
|
krumia wrote: I have asked what I felt as a technical question anyway: Is COM an 'outdated' technology?
No, you have asked a philosophical question, there is nothing technical about it. You are asking people to give their opinions on something; opinions that will vary widely based on their own assumptions and possibly even prejudices.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Richard MacCutchan wrote: This forum is not the place for discussions
err, umm "Home Articles Quick Answers Discussions Learning Zones Features Help! The Lounge
|
|
|
|
|
OK, let's count the number of people who responded to this call for a discussion here.
Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness
|
|
|
|
|
It amazes me how many people attempt to use redirection instead of acknowledging that someone elses point was valid. At this point in time, the tab above for this forum is titled "Discussions". You were wrong. Just admit it. 
|
|
|
|
|
As I said, count how many people actually responded to the request for a discussion. Try answering the question; but first make sure you read How-to-get-an-answer-to-your-question[^].
Binding 100,000 items to a list box can be just silly regardless of what pattern you are following. Jeremy Likness
|
|
|
|
|
krumia wrote: So, I had asked the question in the subject itself: Is COM an 'outdated' technology?
..it is.
krumia wrote: If it is, what are the technologies that replace COM? And how?
DCOM and more recently, .NET. No, I'm not going to reiterate history, it's out there on the web somewhere.
krumia wrote: If it is not, why such an old technology is still there?
Because having something newer that "replaces X" does not really replace X. Assembly and C++ are still around, as is the Latin language.
krumia wrote: I am hoping to see a discussion emerging about this
Just look up one of the old ones
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
Hello,
I am now facing a very strange issue.
One of our product installers registers numerous COM dll's during the installation of the product. Subsequently, this creates COM+ applications under Administrative tools --> Component Services --> COM+ applications.
One of the COM+ applications is created during the install to run under NETWORK SERVICE account. However, at times , it has been observed that the identity of this COM+ application is set to interactive. I am using a msi based installer. The windows installer log files clearly state that the COM+ application was set to run under NETWORK SERVICE account.
We use our own custom code to create this COM+ application.
This issue is not reproducible at will. However, it does happen on some environments.
Either of the two things is happening:
i)There is a bug in the installer code which is causing this
ii)There is something outside of install which is causing this.
I need to root cause this behavior.
Reason as to what is causing this.
Upon carrying out some research on the web, i have come across the following two articles:
http://support.microsoft.com/kb/926098
http://blogs.msdn.com/b/distributedservices/archive/2009/06/19/tracing-in-com-and-complus.aspx
These two articles talk about how diagnostic logging can be enabled for COM+ components.
However, i am not really sure if they will be of use to me , as i need to accurately pin point as to what is changing the identity of the COM+ component to INTERACTIVE USER.
The other major disadvantage with this logging is that the .etl files output ,are in a binary format and can only be decoded by contacting Microsoft with the help of so called .tmf files.
Questions:
i)What are the other options available to me to diagnose this issue?
ii)Can i format the .etl files without the help of Microsoft?
iii)Is there any mechanism in place just like process monitor, which could monitor all the events within COM+?
Any help would be very much appreciated.
Thanks,
Kiran Hegde
|
|
|
|
|
Hello,
Can i get some help here.?
Thanks,
Kiran Hegde
|
|
|
|
|
hi experts,
i get a COM server registered (a proxy-stub dll where the interface in), but i don't know the definition of the interface.
is it possible to convert the proxy-stub dll to a COM type library , so i can know the interface ?
or are there other ways to know the interface ?
|
|
|
|
|
Have a look here, and at the following answer <a href="http://www.codeproject.com/Messages/3294656/Re-using-interface.aspx">http://www.codeproject.com/Messages/3294656/Re-using-interface.aspx</a>[<a href="http://www.codeproject.com/Messages/3294656/Re-using-interface.aspx" target="_blank" title="New Window">^</a>]
|
|
|
|
|
If you only want to view the interface definitions, you can use a tool called OLE/COM Object Viewer that comes along with Visual Studio.
From this tool select the menu option File -> View TypeLib... and point to the proxy-stub dll.
But for this to work, the type library has to be packed into the DLL.
|
|
|
|
|
Hey,
in my excel plugin , i have dynamically generated the OLEOBJECTS Textbox ..
when i click on them to write something . THEY opens up the
Private Sub cmdActionTxt0_Change()
End Sub
VBA editor
i do not want it to be opened and simply want to write over them.
How is that possible.
|
|
|
|
|
Hey
I am creating my OWN EXCEL PLUGIN 2010 in vb.net for designing purpose. My requirement is in MY EXCEL sheet i want to select the 1028 By 768 pxiles area for designing .
that area will be calculated automatically on Load of Addin. so that i can start designing in the particular area only.
That are will be filled with WHITE COLOR.
and the selected area of 1028 by 768 pixels can be varied upon my requirement.
please help me as i am new to office tools.
or you can reply me at archanajain@claricetechnologies.com
|
|
|
|
|
Hi,
I have an Excel Addin which loads with Excel Application. Excel Addin then loads a COM dll on the click of Load button.
The loaded COM dll adds an Excel Workbook.
Excel::WorkbookPtr m_ptrDummyWbk;
Excel::WorkbooksPtr ptr_XLWb = m_myExcelPtr->GetWorkbooks();
m_ptrDummyWbk = ptr_XLWb->Add();
m_ptrDummyWbk->PutIsAddin(VARIANT_TRUE);
m_ptrDummyWbk->PutSaved(0,VARIANT_TRUE);
The loaded COM dll is released on the click of Unload button and m_ptrDummyWbk is closed and released.
m_ptrDummyWbk->PutSaved(0,VARIANT_TRUE);
HRESULT hr = m_ptrDummyWbk->Close(VARIANT_FALSE);
m_ptrDummyWbk = NULL
ptr_XLWb = NULL;
Now if i load the COM dll again by clicking the Load Button the application Crashes while adding the workbook
m_ptrDummyWbk = ptr_XLWb->Add();
The error displayed is: Quote: Unhandled exception at 0x2f430f9f in EXCEL.EXE: 0xC0000005: Access violation reading location 0x0b0231b8.
What could be the potential cause of this crash and how to get rid of it?
|
|
|
|
|
I have these 2 lines of code, if I remark them out, my function runs fine, but does not add the data to the metabase key. If I leave them in, I can't unload the Variant Array, and I get a CRT Heap Failure upon exiting the function.
I sort of know what it does, it takes the new array entry and converts the type to VT_DISPATCH, and then copies the CLASS MimeMap into the array's last entry.
I have worked hard to get the complete function to work, and it does, it generates the MimeMap Key, loads the data, but I can't exit the function clean, and call it again.
If I need to post more, let me know.
V_VT(&va.pa[cVariants]) = VT_DISPATCH;
V_DISPATCH(&va.pa[cVariants]) = pME;
++cVariants;
|
|
|
|
|
How many elements does va.pa own.
The heap failure is probably occurring because you're exceeding the bounds of the array when you do ++cVariants .
|
|
|
|
|
I thought about that. If the mime map key is empty at 0, I add an entry, the +CVariants becomes 1. In the For Loop SafeArrayPutElement, it loops once.
so no existing data, add pME, va.pa = {pa=0x003a7200 DISPATCH = 0x017a8458 } vt = 9, cVariants = 0
the added data is the 0, first array entry, but makes the SafeArray Bound 1, because it can't be 0?
So you don't think that my pME is distorting the va.pa?, I can't see the data, so I don't know.
I'm in Antarctica here on this one, it's not a popular subject, and wrappers have been created to do the job in VB. I'm learning that super hard stuff has been replaced with high level wrappers by MS. Thanks for looking at my post, I really need to pull this off, and move on to my socket issue. I think I'm so close to finishing this function.
if (NULL != pwszAddExtension && NULL != pwszAddType) {
CComPtr<IISMimeType> pME;
hr = pME.CoCreateInstance(L"MimeMap");
RETURN_ON_FAILURE(hr);
hr = pME->put_Extension(bstrAddExtension);
hr = pME->put_MimeType(bstrAddType);
RETURN_ON_FAILURE(hr);
SAFEARRAYBOUND saBound = {cVariants, 0};
SafeArray sa(VT_VARIANT, 1, &saBound); ,- the bound becomes 1
VARIANT varArray;
VariantInit(&varArray);
V_VT(&varArray) = (VT_VARIANT | VT_ARRAY);
V_ARRAY(&varArray) = sa.psa;
for (i = 0; i < cVariants; ++i) {
hr = SafeArrayPutElement(sa.psa, &i, &va.pa[i]);
RETURN_ON_FAILURE(hr);
}
|
|
|
|
|
Oh wow your a genius.
Over all in the end, the cVariants value was wrong when the first array called va was created. It was too small, so the one you pointed out added a value that was not initialized, it ncreased the size of the array, in a space that was too small. So that's why the delete [] va crashed.
So finally after week of messing with this, I broke the program down in 2, worked on the add mime until it was clean, and just added the code to read the current mimes.
I put much weight on your suggestion, but did keep it in mind.
Thanks Superman.
|
|
|
|
|
Hi,
I want to use an unregistered tlb file. To achieve this I figured out that i will need to install the tlb file in WinSxS folder.
Now my problem is how do i create a manifest file with this tlb file. Mt.exe requires -dll option to be used if -tlb file is specified to it.
Can anyone please help me out
|
|
|
|
|
You don't need to use side x side. The type library can be loaded as a file and the information you need extracted programmatically. But it won't be much fun. I would suggest that consider other ways to do this. I'm not sure whether the documentation is still around. MS want to discourage COM so I wouldn't be surprised if it had disappeared.
|
|
|
|
|
Hi All,
I have posted this message earlier on the ASP.Net forum, I did not notice there is a separate forum for Co Componenets. However I am moving the post to here, please have a look, any help would be much appreciated.
I am using a third Party Com Component in my ASP.NET application. I dont have much experience with COM Components and I think I have messed up here. Please help.
The Com component has a method which looks like following in the ILDASM:
.method public hidebysig newslot specialname virtual
instance class [stdole]stdole.IPicture
marshal( interface )
get_Preview([in] float64 rWorldMinX,
[in] float64 rWorldMinY,
[in] float64 rWorldMaxX,
[in] float64 rWorldMaxY,
[in] int32 dwPicWidth,
[in] int32 dwPicHeight,
[in] int32 PicType) runtime managed internalcall
In my code behind, I am using
object ComObjLateBound;
Type ComObjType;
ComObjType= Type.GetTypeFromCLSID(new Guid("{89251546-3F1C-430D-BA77-F86572FA4EF6}"));
ComObjLateBound= Activator.CreateInstance(ComObjType);
double viewMaxX = (double)ComObjType.InvokeMember("ViewMaxX", BindingFlags.Default | BindingFlags.GetProperty, null, ComObjLateBound, new object[] { });
double viewMaxX = (double)ComObjType.InvokeMember("ViewMaxY", BindingFlags.Default | BindingFlags.GetProperty, null, ComObjLateBound, new object[] { });
double viewMaxX = (double)ComObjType.InvokeMember("ViewMinX", BindingFlags.Default | BindingFlags.GetProperty, null, ComObjLateBound, new object[] { });
double viewMaxX = (double)ComObjType.InvokeMember("ViewMinY", BindingFlags.Default | BindingFlags.GetProperty, null, ComObjLateBound, new object[] { });
int imagewidth, imageheight, pictype;
imagewidth = 1280; imageheight = 800; pictype = 1;
object[] previewDetails = new object[7];
previewDetails[0] = viewMinX;
previewDetails[1] = viewMinY;
previewDetails[2] = viewMaxX;
previewDetails[3] = viewMaxY;
previewDetails[4] = imagewidth;
previewDetails[5] = imageheight;
previewDetails[6] = pictype;
IPicture picture = (IPicture)ComObjType.InvokeMember("get_Preview", BindingFlags.Default | BindingFlags.InvokeMethod, null, ComObjLateBound, previewDetails);
this fails with a COM Exception like
{"Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"}
with an ErrorCode of -2147352570 if that means something.
Now this is strange, because the exception type and Error Code remains exactly the same if I use any name instead of "get_Preview".
the COM component also has a Preview Property which looks the following in ILDASM:
.property class [stdole]stdole.IPicture Preview(float64,
float64,
float64,
float64,
int32,
int32,
int32)
I have also tried to use this property to get the IPicture value like:
IPicture picture = (IPicture)ComObjType.InvokeMember("Preview", BindingFlags.Default | BindingFlags.GetProperty, null, ComObjLateBound, previewDetails);
But it also falis with a message that Exception has been thrown by the target of an invocation.
Please note, I am not able to use early binding on this component as it gives me an error message -
Unable to cast COM object of type '<>' to interface type '<>'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{}' failed due to the following error: No such interface supported.
I think I am doing something wrong here. Can you please point out what it is?
Thanks in advance.
|
|
|
|
|