Hi Dmytro,
This is the entire server class (ServerTest assembly):
using System;
using System.Runtime. Remoting;
using System.Runtime. Remoting.Lifeti me; // to set the lease to infinite
using System.Runtime. InteropServices ;
namespace ServerTest
{
/// <summary>
/// Summary description for IOComponent.
/// </summary>
public class Class1 : MarshalByRefObj ect, ServerData
{
static int m_EC;
#region Marshal By Reference Methods
public override Object InitializeLifet imeService()
{
return null;
}
#endregion
public Class1()
{
m_EC = 0;
}
public int MAKE_HRESULT(in t sev, int fac, int code)
{
return (((sev)<<31) | ((fac)<<16) | ((code)));
}
#region ServerData Members
public void ThrowException( )
{
int hRes = MAKE_HRESULT(1, 4,(int)m_EC++);
throw new COMException("M y new exception",hRes );
// Creates an
HRESULT of 0x80040000
}
#endregion
}
}
The ServerData interface is this:
using System;
namespace ServerTest
{
/// <summary>
/// Summary description for serverInterface .
/// </summary>
public interface ServerData
{
// methods
void ThrowException( );
}
}
To use this, the #import of the server code creates a secondary header file (.
tli) from the .tlb.
Here's my code for the client proxy, also written in C#:
// ServerProxy.cs
using System;
using ServerTest;
using System.Runtime. Remoting;
using System.Runtime. Remoting.Lifeti me; // to set the lease to infinite
using System.Runtime. InteropServices ;
namespace COMServerPS
{
/// <summary>
/// Summary description for ServerProxy.
/// </summary>
public class ServerProxy : MarshalByRefObj ect, ServerData
{
public Class1 _Server; // object
#region Marshal By Reference Methods
public override Object InitializeLifet imeService()
{
return null;
}
#endregion
public ServerProxy()
{
_Server = new Class1();
}
#region ServerData Members
[PreserveSig]
public void ThrowException( )
{
try
{
_Server.ThrowEx ception();
}
catch (Exception ex)
{
int hr = Marshal.GetHRFo rException(ex);
throw ex;
}
}
#endregion
}
}
This is the MFC header file:
// WindowsMFCAppli cationDlg.h : header file
//
#pragma once
#import "COMServerProxy .tlb" named_guids
#import "ServerTest.tlb " named_guids
// CWindowsMFCAppl icationDlg dialog
class CWindowsMFCAppl icationDlg : public CDialog
{
// Construction
public:
CWindowsMFCAppl icationDlg(CWnd * pParent = NULL); // standard constructor
// Dialog Data
....
// Namespace(from .tlb)::Interfac ePtr
ServerTest::Ser verDataPtr m_ioServer;
// Implementation
protected:
....
public:
afx_msg void OnBnClickedButt on1();
};
And the implementation file:
// WindowsMFCAppli cationDlg.cpp : implementation file
//
#include "stdafx.h"
#include "WindowsMFCAppl ication.h"
#include "WindowsMFCAppl icationDlg.h"
#include ".\windowsmfcap plicationdlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace System;
using namespace System::Runtime ::InteropServic es;
....
BOOL CWindowsMFCAppl icationDlg::OnI nitDialog()
{
CDialog::OnInit Dialog();
....
// must call CoInitialize() at least once prior to calling CreateInstance( )
HRESULT hRes = CoInitialize(NU LL);
// CreateInstance( Assembly Name::Class Name)
hRes = m_ioServer.Crea teInstance(__uu idof(COMServerP roxy::ServerPro xy));
return TRUE; // return TRUE unless you set the focus to a control
}
void CWindowsMFCAppl icationDlg::OnB nClickedButton1 ()
{
HRESULT hr = S_OK;
try
{
hr = m_ioServer->ThrowException ();
}
catch(COMExcept ion* ex )
{
int ec = ex->get_ErrorCode( );
Exception *exc = ex->GetBaseExcepti on();
hr = Marshal::GetHRF orException(ex) ;
}
catch(Exception * ex )
{
hr = Marshal::GetHRF orException(ex) ;
// HRESULT is 0x80004005
}
}
Tha's about it. It works between the managed types, but not unmanged C++.
Thanks,
Steve
Dmytro Lapshyn [MVP] wrote:
Hi,
First of all, how to you throw custom COMExceptions? I'd recommend that you
did it with Marshal.ThrowEx ceptionFromHR.
Also, the exception code itself looks suspicious as it can easily interfer
with system error codes. As far as I remember, it is safe to use codes from
0x80040201 and above for custom errors (VB6 has a dedicated constant for
that called vbObjectError).
Finally, as I am not an MFC programmer, can you please elaborate on what the
.tli file is?
I'm trying to send custom COMExceptions from my C# server. My test client
in
[quoted text clipped - 11 lines]
I can post the code, it is pretty simple.
--
Message posted via DotNetMonster.c om
http://www.dotnetmonster.com/Uwe/For...sharp/200602/1