Tom Knowlton
asked on
C# and COM+ Interface not registered?
From a C# / .NET / COM+ perspective, what would it mean if I got a message saying "Interface not registered"
Here is my Class Library source code:
using System;
using System.Runtime.InteropServ ices;
using System.Xml;
using CDO;
using ADODB;
using System.IO;
using System.Text;
using System.EnterpriseServices;
namespace MyEventSink
{
/// <summary>
/// Summary description for Class1.
/// </summary>
[Guid("16369924-5F32-4E26- AE89-8308B 5C162E2")]
public class ExchEventSink: ServicedComponent , IExStoreAsyncEvents
{
//public string ClassID = "F92EFC3A-FDD8-4225-B005-1 3FD3D5D54D 1";
//public string InterfaceId = "704A413F-F8FE-476B-9206-6 9AB6300D75 2";
//public string EventsId = "DCC71BD5-6627-4FBF-BB5A-D B8FEA1EB17 7";
public string ClassID = "cf63289d-18d1-43af-ba90-9 e41cac93ee 6";
public string InterfaceId = "323733b0-3c0d-47d4-86fa-f d67d651cf8 1";
public string EventsId = "3721271c-65f0-441a-91d6-6 a86d1c7584 6";
public ExchEventSink()
{
}
#region IExStoreAsyncEvents Members
public void OnSave(IExStoreEventInfo pEventInfo, string bstrURLItem, int lFlags)
{
try
{
if(System.Convert.ToBoolea n(lFlags))
{
Process_mail(bstrURLItem);
}
}
catch (Exception ex)
{
throw (ex);
}
}
public void OnDelete(IExStoreEventInfo pEventInfo, string bstrURLItem, int lFlags)
{
try
{
}
catch(Exception ex)
{
throw (ex);
}
}
#endregion
private void Process_mail(string bstrURLItem)
{
CDO.Message iMessage=new CDO.MessageClass();
int i;
int aNum;
string eName;
string fName;
ADODB.Stream stm;
CDO.IBodyPart iPrt;
string sFrom;
string sDate;
try
{
iMessage.DataSource.Open(b strURLItem ,null,ADOD B.ConnectM odeEnum.ad ModeRead,A DODB.Recor dCreateOpt ionsEnum.a dFailIfNot Exists,ADO DB.RecordO penOptions Enum.adOpe nSource,"" ,"");
FileStream fs = new FileStream(@"c:\temp\MyEve ntSink.log ",FileMode .OpenOrCre ate);
fs.Write(Encoding.ASCII.Ge tBytes(bst rURLItem), 0,bstrURLI tem.Length );
fs.Close();
sFrom = iMessage.From;
sDate = iMessage.ReceivedTime.ToSt ring();
aNum = iMessage.Attachments.Count ;
for(i=1;i<=aNum;i++)
{
fName = iMessage.Attachments[i].Fi leName;
eName = fName.Substring(fName.Leng th-3,3).To Upper();
if(eName == "TXT")
{
iPrt = iMessage.Attachments[i];
iPrt.ContentMediaType = "text/plain";
iPrt.Charset = "windows-1250";
stm = iPrt.GetDecodedContentStre am();
Process_attachment(stm,fNa me,sFrom,s Date);
iPrt =null;
}
}
}
catch (Exception ex)
{
throw (ex);
}
}
}
}
Here is my Assembly Code:
using System.Reflection;
using System.Runtime.CompilerSer vices;
using System.Runtime.InteropServ ices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("MyEventSink ")]
[assembly: AssemblyDescription("My Event Sink")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
[assembly: Guid("2a910565-736c-48d3-a 9bb-f64afc b70a83")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configurat ion>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\m ykey.snk") ]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("..\\..\\k ey.snk")]
[assembly: AssemblyKeyName("")]
Here is my Class Library source code:
using System;
using System.Runtime.InteropServ
using System.Xml;
using CDO;
using ADODB;
using System.IO;
using System.Text;
using System.EnterpriseServices;
namespace MyEventSink
{
/// <summary>
/// Summary description for Class1.
/// </summary>
[Guid("16369924-5F32-4E26-
public class ExchEventSink: ServicedComponent , IExStoreAsyncEvents
{
//public string ClassID = "F92EFC3A-FDD8-4225-B005-1
//public string InterfaceId = "704A413F-F8FE-476B-9206-6
//public string EventsId = "DCC71BD5-6627-4FBF-BB5A-D
public string ClassID = "cf63289d-18d1-43af-ba90-9
public string InterfaceId = "323733b0-3c0d-47d4-86fa-f
public string EventsId = "3721271c-65f0-441a-91d6-6
public ExchEventSink()
{
}
#region IExStoreAsyncEvents Members
public void OnSave(IExStoreEventInfo pEventInfo, string bstrURLItem, int lFlags)
{
try
{
if(System.Convert.ToBoolea
{
Process_mail(bstrURLItem);
}
}
catch (Exception ex)
{
throw (ex);
}
}
public void OnDelete(IExStoreEventInfo
{
try
{
}
catch(Exception ex)
{
throw (ex);
}
}
#endregion
private void Process_mail(string bstrURLItem)
{
CDO.Message iMessage=new CDO.MessageClass();
int i;
int aNum;
string eName;
string fName;
ADODB.Stream stm;
CDO.IBodyPart iPrt;
string sFrom;
string sDate;
try
{
iMessage.DataSource.Open(b
FileStream fs = new FileStream(@"c:\temp\MyEve
fs.Write(Encoding.ASCII.Ge
fs.Close();
sFrom = iMessage.From;
sDate = iMessage.ReceivedTime.ToSt
aNum = iMessage.Attachments.Count
for(i=1;i<=aNum;i++)
{
fName = iMessage.Attachments[i].Fi
eName = fName.Substring(fName.Leng
if(eName == "TXT")
{
iPrt = iMessage.Attachments[i];
iPrt.ContentMediaType = "text/plain";
iPrt.Charset = "windows-1250";
stm = iPrt.GetDecodedContentStre
Process_attachment(stm,fNa
iPrt =null;
}
}
}
catch (Exception ex)
{
throw (ex);
}
}
}
}
Here is my Assembly Code:
using System.Reflection;
using System.Runtime.CompilerSer
using System.Runtime.InteropServ
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("MyEventSink
[assembly: AssemblyDescription("My Event Sink")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
[assembly: Guid("2a910565-736c-48d3-a
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configurat
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\m
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("..\\..\\k
[assembly: AssemblyKeyName("")]
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I stumbled upon the answer I needed.
Turns out RegEvent.vbs is not needed.
Exchange Explorer (found with Exchange 2003 SDK Tools) does the exact same thing.
Go here for details:
https://www.experts-exchange.com/questions/20962654/Please-help-troubleshoot-Exchange-Event-Sink-registration-problem.html
All I had to do was right-click on the Component Services COM App....and click START.
Turns out RegEvent.vbs is not needed.
Exchange Explorer (found with Exchange 2003 SDK Tools) does the exact same thing.
Go here for details:
https://www.experts-exchange.com/questions/20962654/Please-help-troubleshoot-Exchange-Event-Sink-registration-problem.html
All I had to do was right-click on the Component Services COM App....and click START.
ASKER
The tutorial at this link:
http://www.codeproject.com/csharp/CsManagedEventSinksHooks.asp
is very very good...................... but it does have some flaws.
1) You do NOT need to run RegEvent.vbs AT ALL......ignore this suggestion in the tutorial. Instead, download and install the SDK Tools and run Exchange Explorer instead to register the Event and hook it into the EventSink code.
2) I recommend using regsvcs /appname:YourAppName <full path to your DLL including extension> from the command line, instead of using the Component Services GUI to register the COM DLL. I have to do some further testing to see if the GUI works...but I know for sure the command line route using REGSVCS works well.
3) After you have registered the COM DLL (your event sink) in Component Services......then go and register the Exchange Store Event using Exchange Explorer. THEN go back to Component Services....right-click on your App Name and click on START. This is what actually starts the EventSink (your C# DLL) talking to the Exchange Store. Until you do this nothing will happen. This was left out of the tutorial. A small thing, but an important thing to mention.
http://www.codeproject.com/csharp/CsManagedEventSinksHooks.asp
is very very good......................
1) You do NOT need to run RegEvent.vbs AT ALL......ignore this suggestion in the tutorial. Instead, download and install the SDK Tools and run Exchange Explorer instead to register the Event and hook it into the EventSink code.
2) I recommend using regsvcs /appname:YourAppName <full path to your DLL including extension> from the command line, instead of using the Component Services GUI to register the COM DLL. I have to do some further testing to see if the GUI works...but I know for sure the command line route using REGSVCS works well.
3) After you have registered the COM DLL (your event sink) in Component Services......then go and register the Exchange Store Event using Exchange Explorer. THEN go back to Component Services....right-click on your App Name and click on START. This is what actually starts the EventSink (your C# DLL) talking to the Exchange Store. Until you do this nothing will happen. This was left out of the tutorial. A small thing, but an important thing to mention.
ASKER
UPDATE:
Well, guess what?
I finally had a major breakthrough on this @!#$^% problem that has been driving me crazy for the last few weeks!!!!!!!
It is a very small change.
Apparently the method MoveFirst( ) does not work so well with Exchange.
This was the cause of my COMException: "Interface not registered" error message this entire time.
The solution is to use Move(1,0) instead of MoveFirst( ).
That's it. Simple.
This answer came courtesy of Tom Rizzo, an author who was kind enough to correspond with me and help me figure-out finally what the problem was.:
Looking for a good book on programming Exchange, Outlook, ADSI and
SharePoint? Check out http://www.microsoft.com/MSPress/books/5517.asp
My I aslo reommend:
.NET and COM: The Complete Interoperability Guide ISBN:067232170X
http://www.amazon.ca/exec/obidos/ASIN/067232170X/componentsnot-20/701-9386310-4703553
Well, guess what?
I finally had a major breakthrough on this @!#$^% problem that has been driving me crazy for the last few weeks!!!!!!!
It is a very small change.
Apparently the method MoveFirst( ) does not work so well with Exchange.
This was the cause of my COMException: "Interface not registered" error message this entire time.
The solution is to use Move(1,0) instead of MoveFirst( ).
That's it. Simple.
This answer came courtesy of Tom Rizzo, an author who was kind enough to correspond with me and help me figure-out finally what the problem was.:
Looking for a good book on programming Exchange, Outlook, ADSI and
SharePoint? Check out http://www.microsoft.com/MSPress/books/5517.asp
My I aslo reommend:
.NET and COM: The Complete Interoperability Guide ISBN:067232170X
http://www.amazon.ca/exec/obidos/ASIN/067232170X/componentsnot-20/701-9386310-4703553
ASKER
More on the MoveFirst problem I described:
http://support.microsoft.com/default.aspx?scid=kb;en-us;273791
If you are getting into Event Sinks....I recommend the following tutorial:
http://www.codeproject.com/csharp/CsManagedEventSinksHooks.asp
Make sure and read the article questions and follow-ups at the bottom!
There are a few caveats. E-mail me at my Profile e-mail address and we can talk about them. :)
http://support.microsoft.com/default.aspx?scid=kb;en-us;273791
If you are getting into Event Sinks....I recommend the following tutorial:
http://www.codeproject.com/csharp/CsManagedEventSinksHooks.asp
Make sure and read the article questions and follow-ups at the bottom!
There are a few caveats. E-mail me at my Profile e-mail address and we can talk about them. :)
ASKER
This is the exact tutorial that brought me to this point in the first place. :)
Please read my summary of the problem here:
http://www.knowltonfamily.com/es_troubleshoot.htm