0

I made an application for Windows Compact Framework 3.5 , which appears to work fine.

After compilation a .exe file is created on my computer. Until recently, I could actually also run this exe file on my computer. (without the use of a simulator)

But recently I noticed that my application only runs on mobile devices. When I try to run it on my desktop computer I receive a strange error message which indicates that I should run my application with the [STAThread] directive for the Main() method.

However, for my mobile devices this is not necessary, everything works fine as is. In fact, I cannot even add the [STAThread] to the source code because the compact framework does not support it. Adding it causes compilation errors.

Unfortunately that's also the problem now. I would love to add some conditional code which evaluates if it's running on Windows CE or Windows Desktop. When it runs on desktop it should then start the code in STAThread mode. However, I cannot find a way to add this kind of code, because it doesn't compile. It always comes down to the point that the compiler does not know what STAThread is.

Is there a way or trick to handle this?

A good workaround for me, would be to compile it in a different way, perhaps by selecting a different target platform when I compile it for desktop computers. However, I am not able to do so currently. Any ideas ?

bvdb
  • 22,839
  • 10
  • 110
  • 123
  • _Until recently_ - so something changed. What OS are you running on, what changes to the application, can you match this to a recent update ? – H H Jan 04 '17 at 18:29
  • @HenkHolterman Indeed, I started using the WebBrowser component. It seems to me, as if the WebBrowser implementation on a mobile device can run fine in MTA, while a full blown windows system's WebBrowser component requires STA. Which is indeed the reason for this question (I wanted to leave this out of scope for this question, because it only makes things more complicated) :) – bvdb Jan 04 '17 at 18:40
  • 2
    Simple CF apps will run without modification on desktop, this is well known. But apps that use CF-only APIs (ie aygshell related), will not run. The STAThread compile option can only be used during compile (AFAIK). If a DLL was compiled with that option I can imagine that it wil not run on desktop. For the web browser component, you need to not load this hardcoded but from within code and then load either the full framework one or the CF one. CF Forms are hardcoded to MTA. If a COM is loaded that requires STA, it will give exception. – josef Jan 05 '17 at 04:59

1 Answers1

1

In summary the code only needs to run in STA state when it runs on a desktop computer. Furthermore the STA state isn't even available on a mobile device.

This is what I came up with:

    static void Main() 
    {
        Type type = typeof(Thread);
        MethodInfo methodInfo = type.GetMethod("SetApartmentState");

        if (methodInfo != null)
        {
            // full .net framework
            // --> requires STA apartmentstate

            Thread thread = new Thread(() => Run());
            methodInfo.Invoke(thread, new object[] { ApartmentState.STA });
            thread.Start();
            thread.Join();
        }
        else
        {
            // .net compact framework
            // --> needs no special attention (can run in MTA)
            Run();
        }
    }

Note: The Run() method above, is the one that starts the application.

Due to the fact that the code is written in Compact Framework, the apartment state cannot be set directly, simply because there is no setApartmentState method. But fortunately, it can be done using reflection, because the method will actually be available at runtime when (and only when) the code runs on the full .net framework.

bvdb
  • 22,839
  • 10
  • 110
  • 123
  • 1
    You sir, have saved my day. I am using `OpenFileDialog` on a .NET CF 3.5 program that runs on both Mobile and Desktop. On the desktop version it throws `Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process.` Your solution saved me from having to create my own OpenFileDialog. – Lionet Chen May 27 '20 at 04:30