.NET Component as COM Component

W

willy

Hi,

I post this message after trying this for two days. Maybe I would have
to post this message in another group, but I'm sure you will
be going to inform me of that.

Aim
====
Using a .NET component (in fact a single C# class) as a COM component
(inproc server) from an native C++ application running both on a Pocket
PC 2003 (currently x86 Emulator only) using Visual Studio 2005 (RC).
The only task the native application performs is calling the .NET
Component, which opens a MessageBox
only.

Visaul Studio 2005 Solution Settings
===================================
- (Server) .NET Component: C# Smart Device Class Library (PPC2003)
- (Client) Native Application: Visual C++ (native) Smart Device Console
Application supporting MFC and ATL (PPC2003)

Problem
=======
It looks like the registration of the .NET COM Component fails on the
target and .NET component is never called. I can build both
applications without any errors or warnings. I have developed exactly
the same applications to be executed on my development host (Windows
XP, SP2) and that works perfectly well. But the point is, that Visual
Studio 2005 performs the registration of the .NET Component as an COM
component on the host automatically. Thus I have tried to do that
manually with the following source code and build tasks:

..NET Application
-----------------

CFMessager.cs:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

[GuidAttribute("A045D415-4877-450d-9FF5-8F9230878EBE")] //GUID created
using guidgen.exe
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface ICFMessager
{
void ShowMessage();
}

[ClassInterface(ClassInterfaceType.None)]
public class CFMessager : ICFMessager
{
public CFMessager()
{
//empty default constructor
}

public void ShowMessage()
{
MessageBox.Show("Hello from managed world", "Managed Window");
}
}

Native Application
------------------

CFApp.cpp:

#import "../CFMessage/cfmessage.tlb" raw_interfaces_only

void OnBtnClick()
{
HRESULT hr = NULL;


//inititalize COM
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED );

//Instantiate .NET Component
LPOLESTR strGUID;
StringFromCLSID(__uuidof(cfmessage::CFMessager), &strGUID);
cfmessage::ICFMessagerPtr comPtr(strGUID);

//this should open a managed message box
comPtr->ShowMessage();
}

In my opinion it takes the following steps to create both of the above
mentioned components:

(on the development host)

1. Compile .NET Component: csc /target:library /out:cfmessage.dll
/r:System.Windows.Forms.dll CFMessager.cs
2. Export Type Library: tlbexp cfmessage.dll /out:cfmessage.tlb
3. Compile & Deploy Native Application exe using Visual Studio 2005

After this step the cfmessage.dll should be registered on the pocket pc
2003 target. I've tried the following
possibilities:
- using a 3rd party regsvrce.exe, which did not work (terminates with
error code 87 'invalid parameter')
- packing the tlb into the native exe and registering it using
RegisterTypeLib() function on the target, which did not work. (no
registration takes place)

Conclusion
==========

I tracked down the problem to the _com_ptr_t function in comip.h, where
a COM Error is issued. A weired fact is, that strGUID does not match
with the GUID set in CFMessage.cs in the GuidAttribute, when i debug
the application.

What am I doing wrong or how could I register the .NET Component on the
target?

Thanks in advance for any help and hints,

Regards Willy
 
P

Paul G. Tobey [eMVP]

Can't do that. You can't host the .NET CF run-time from unmanaged code.

Paul T.

willy said:
Hi,

I post this message after trying this for two days. Maybe I would have
to post this message in another group, but I'm sure you will
be going to inform me of that.

Aim
====
Using a .NET component (in fact a single C# class) as a COM component
(inproc server) from an native C++ application running both on a Pocket
PC 2003 (currently x86 Emulator only) using Visual Studio 2005 (RC).
The only task the native application performs is calling the .NET
Component, which opens a MessageBox
only.

Visaul Studio 2005 Solution Settings
===================================
- (Server) .NET Component: C# Smart Device Class Library (PPC2003)
- (Client) Native Application: Visual C++ (native) Smart Device Console
Application supporting MFC and ATL (PPC2003)

Problem
=======
It looks like the registration of the .NET COM Component fails on the
target and .NET component is never called. I can build both
applications without any errors or warnings. I have developed exactly
the same applications to be executed on my development host (Windows
XP, SP2) and that works perfectly well. But the point is, that Visual
Studio 2005 performs the registration of the .NET Component as an COM
component on the host automatically. Thus I have tried to do that
manually with the following source code and build tasks:

.NET Application
-----------------

CFMessager.cs:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

[GuidAttribute("A045D415-4877-450d-9FF5-8F9230878EBE")] //GUID created
using guidgen.exe
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface ICFMessager
{
void ShowMessage();
}

[ClassInterface(ClassInterfaceType.None)]
public class CFMessager : ICFMessager
{
public CFMessager()
{
//empty default constructor
}

public void ShowMessage()
{
MessageBox.Show("Hello from managed world", "Managed Window");
}
}

Native Application
------------------

CFApp.cpp:

#import "../CFMessage/cfmessage.tlb" raw_interfaces_only

void OnBtnClick()
{
HRESULT hr = NULL;


//inititalize COM
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED );

//Instantiate .NET Component
LPOLESTR strGUID;
StringFromCLSID(__uuidof(cfmessage::CFMessager), &strGUID);
cfmessage::ICFMessagerPtr comPtr(strGUID);

//this should open a managed message box
comPtr->ShowMessage();
}

In my opinion it takes the following steps to create both of the above
mentioned components:

(on the development host)

1. Compile .NET Component: csc /target:library /out:cfmessage.dll
/r:System.Windows.Forms.dll CFMessager.cs
2. Export Type Library: tlbexp cfmessage.dll /out:cfmessage.tlb
3. Compile & Deploy Native Application exe using Visual Studio 2005

After this step the cfmessage.dll should be registered on the pocket pc
2003 target. I've tried the following
possibilities:
- using a 3rd party regsvrce.exe, which did not work (terminates with
error code 87 'invalid parameter')
- packing the tlb into the native exe and registering it using
RegisterTypeLib() function on the target, which did not work. (no
registration takes place)

Conclusion
==========

I tracked down the problem to the _com_ptr_t function in comip.h, where
a COM Error is issued. A weired fact is, that strGUID does not match
with the GUID set in CFMessage.cs in the GuidAttribute, when i debug
the application.

What am I doing wrong or how could I register the .NET Component on the
target?

Thanks in advance for any help and hints,

Regards Willy
 
D

Daniel Moth

....exactly, your only alternative is to actually use the dotnet code in
another process:
http://www.danielmoth.com/Blog/2005/05/cf-com-interop-1-faq.html

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Paul G. Tobey said:
Can't do that. You can't host the .NET CF run-time from unmanaged code.

Paul T.

willy said:
Hi,

I post this message after trying this for two days. Maybe I would have
to post this message in another group, but I'm sure you will
be going to inform me of that.

Aim
====
Using a .NET component (in fact a single C# class) as a COM component
(inproc server) from an native C++ application running both on a Pocket
PC 2003 (currently x86 Emulator only) using Visual Studio 2005 (RC).
The only task the native application performs is calling the .NET
Component, which opens a MessageBox
only.

Visaul Studio 2005 Solution Settings
===================================
- (Server) .NET Component: C# Smart Device Class Library (PPC2003)
- (Client) Native Application: Visual C++ (native) Smart Device Console
Application supporting MFC and ATL (PPC2003)

Problem
=======
It looks like the registration of the .NET COM Component fails on the
target and .NET component is never called. I can build both
applications without any errors or warnings. I have developed exactly
the same applications to be executed on my development host (Windows
XP, SP2) and that works perfectly well. But the point is, that Visual
Studio 2005 performs the registration of the .NET Component as an COM
component on the host automatically. Thus I have tried to do that
manually with the following source code and build tasks:

.NET Application
-----------------

CFMessager.cs:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

[GuidAttribute("A045D415-4877-450d-9FF5-8F9230878EBE")] //GUID created
using guidgen.exe
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[ComVisible(true)]
public interface ICFMessager
{
void ShowMessage();
}

[ClassInterface(ClassInterfaceType.None)]
public class CFMessager : ICFMessager
{
public CFMessager()
{
//empty default constructor
}

public void ShowMessage()
{
MessageBox.Show("Hello from managed world", "Managed Window");
}
}

Native Application
------------------

CFApp.cpp:

#import "../CFMessage/cfmessage.tlb" raw_interfaces_only

void OnBtnClick()
{
HRESULT hr = NULL;


//inititalize COM
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED );

//Instantiate .NET Component
LPOLESTR strGUID;
StringFromCLSID(__uuidof(cfmessage::CFMessager), &strGUID);
cfmessage::ICFMessagerPtr comPtr(strGUID);

//this should open a managed message box
comPtr->ShowMessage();
}

In my opinion it takes the following steps to create both of the above
mentioned components:

(on the development host)

1. Compile .NET Component: csc /target:library /out:cfmessage.dll
/r:System.Windows.Forms.dll CFMessager.cs
2. Export Type Library: tlbexp cfmessage.dll /out:cfmessage.tlb
3. Compile & Deploy Native Application exe using Visual Studio 2005

After this step the cfmessage.dll should be registered on the pocket pc
2003 target. I've tried the following
possibilities:
- using a 3rd party regsvrce.exe, which did not work (terminates with
error code 87 'invalid parameter')
- packing the tlb into the native exe and registering it using
RegisterTypeLib() function on the target, which did not work. (no
registration takes place)

Conclusion
==========

I tracked down the problem to the _com_ptr_t function in comip.h, where
a COM Error is issued. A weired fact is, that strGUID does not match
with the GUID set in CFMessage.cs in the GuidAttribute, when i debug
the application.

What am I doing wrong or how could I register the .NET Component on the
target?

Thanks in advance for any help and hints,

Regards Willy
 
W

willy

Hey Guyz,

thanks for your quick answers. Unfortunately, I've been sick for the
last 3 days (including weekend!!) :-(, so I could not answer before.
I do agree with your answers.

@Daniel: I'm currently evaluating, which of your proposed IPC would fit
our needs best. I will post our decision and sample solution here for
completeness.

The remaining question is still: How do I register a .NET component as
COM component on Windows CE?

Let's say I want to use COM (or even DCOM). I would create two
processes (one managed and the other native, where the managed process
would create the native process), where I would use COM to make calls
from managed to unmanaged code and vis-versa.

I think this is the part of my question, which does not belong to this
NG, but any tipps would be helpful. As I already mentioned, using
regsvrce.exe or similar tools did not work at all.

I know that DCOM is not supported by PPC2003, but our end target
platform is Windows CE 5.0 anyway.

Greetings Willy
 
W

willy

Hi all,

I ended up with giving up the COM Interop approach. I could not
register the .NET component as COM component on a pocket pc system.
P/Invoke is the new choice and does the job well. Since CF version 2.0,
callbacks from unmanged to managed code are supported, which fulfills
all of my requirements of managed-unmanged code interoperability in my
project.

Greetings Willy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top