Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / February 2004

Tip: Looking for answers? Try searching our database.

MFC App compiled with /clr

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Kaixin - 12 Feb 2004 23:23 GMT
Hello,
We successfully compiled (on .NET 2003) and ran a MFC application using COM,
and then we try to compile it with /clr switch on .NET 2003. The compilation
is successful, but the MFC app failed to start with an error thrown "Cannot
change thread mode after it is set..", when calling HRESULT
hr(::CoInitialize(NULL));.
Could someone please help?
Thanks in advance,
Kaixin
Richard Grimes [MVP] - 17 Feb 2004 21:08 GMT
> Hello,
> We successfully compiled (on .NET 2003) and ran a MFC application
[quoted text clipped - 5 lines]
> Thanks in advance,
> Kaixin

hmmm, this is not simple to track down.

You see, once a thread joins a COM apartment (by calling CoInituializeEx) it
does so for life/ If you call CoInituializeEx on the same thread to join a
different apartment, you'll get the error you are seeing.

.NET will call CoIninitalizeEx automatically just before the first time that
a thread accesses COM. By default a .NET thread will join the MTA, but you
can use the [STAThread] attribute on a method to indicate that *if*
CoInituializeEx is called then the thread should be STA. Another was to do
this is to call

System.Threading.Thread.CurrentThread.ApartmentState = ApartmentState.STA;

> when calling HRESULT hr(::CoInitialize(NULL));.

Are you suggesting that the error happens on this line? If so, then I
suspect .NET has already initialized the thread to join another apartment.
You should have a look at the .NET code and see what it does, and perhaps
see if you can get the .NET code called *after* the MFC initialization has
occurred.

I have seen problems due to using .NET web services (there's some COM calls
somewhere in the .NET web services client code). Also, if you use .NET forms
you may have some issues because .NET forms are COM servers (to support drag
and drop).

Richard
Signature

my email evpuneqt@zicf.bet is encrypted with ROT13 (www.rot13.org)
sign up for my free .NET newsletter at
http://www.wd-mag.com/newsletters/

Kaixin - 19 Feb 2004 00:26 GMT
Hello Dr Grimes, is this you? You are famous! And thanks for your help!

I added some code to test the thread apartment state, prior calling HRESULT
hr(::CoInitialize(NULL)); in C++ as the following. And this piece of code is
called by almost every windows service or app we develop.
if(Thread::CurrentThread->ApartmentState == ApartmentState::STA)

{Thread::CurrentThread->ApartmentState = ApartmentState::MTA;}

else if(Thread::CurrentThread->ApartmentState == ApartmentState::MTA)

{Thread::CurrentThread->ApartmentState = ApartmentState::STA;}

else{Thread::CurrentThread->ApartmentState = ApartmentState::Unknown;}

HRESULT hr;

hr = ::CoInitialize(NULL);

Below are my observations today:
- If I compile and start a windows service (compiled with /clr) with 'debug'
as start parameter in Services Manager, Apartment state is STA; CoInitialize
returns S_FALSE, which is ok, since it is not considered as FAILED. Our
service started.
- If I compile and start a windows MFC app (compiled with /clr) with
'/winapp' as Debugging Command Argument from Visual Studio, Apartment state
is set to MTA; CoInitialize throws the excpetion not able to change thread
mode. Our app failed to start.

I believe that the thread is considered to be managed in both cases.
Although in my code, I tried to manipulate the apartment state, it had no
effect when calling CoInitialize. In fact, "Once the concurrency model for a
thread is set, it cannot be changed. ", quoted from MSDN COM CoInitializeEx.

Since our code does not control the .NET call to CoInitializeEx, my quest
would be to find a way to somehow change from a MTA appartment to a STA one
for our apps to run, if this is feasible. Do you agree? Or you can point me
out to a different direction?

Thanks,
Kaixin

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.