• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

Read\write sim vars without a Windows App Handle

Messages
3
Country
australia
Hi,

Is there a way to read\write sim variables without using a Windows App Handle to connect to FS? I've had a look at the Simvars project and done some reading and it appears that the SDK only supports connecting to FS via the SimConnect() method. i.e. Can you connect via any other protocol\stream, or do I need to use a Windows app as a middle layer to whatever I'm building?

Thanks, and hope this isn't a stupid question.
 
SimConnect is the primary interface to work with the sim. You might get better information if you provided a clearer picture of exactly why you don't have a Windows application or Windows DLL. If you're trying to get something that isn't a Windows system to interact... you will have to write a custom DLL that gets loaded by the Sim to provide communications back and forth. However, not knowing exactly what you're trying to do... can't give much advice/info.
 
Is there a way to read\write sim variables without using a Windows App Handle to connect to FS?
1 - Just keep in mind that - no matter how magical everyone (here) thinks "a simulator executable" might be, it still remains a straight-forward plain old win32 / win64 executable
which has to obey all architectural, binary and coding laws of the Windows Operating system in order to be able to run on the Windows (tm) platform ;-)

Keep this ancient coding_wisdom in mind @ all times, especially when running into certain "SimConnect challenges"...

2 - If want another way (and another mindset) into "the sim"?
May I suggest to start digging into the another ancient way (a decade before SimConnect arrived at the scene) , which is called "FSUIPC.DLL" (or even older FS6IPC.DLL designed by Aces Studio Adam Zforan himself)
- [qoute]http://www.fsuipc.com/
-------------------------------------------------------------- Website of Pete Dowson, current inventor and maintainer of FSUIPC.DDL suite
-
- The official FSUIPC.dll support forum

3 - This is also a nice and clearly visually documented pdf to learn more about those FSUIPC.DLL basics
-https://www.sim-avionics.com/downloads/FSUIPC Help.pdf

#HackTheSim
 
Hi WarpD, thanks for your reply. The question was more around the need for a Window handle to create an interface between my code and MSFS. It's just strange that, with such an active developer community, the publishers haven't created better integration paths. I built my first FS tools >5 years ago - It was a Windows Phone app (when that device was still around) that displayed gauges. I'm just getting back into it, and with FS2020, I thought they might improved things a bit, by exposing new interfaces. Seems a bit archaic to be using Window handles.

Hi Ronald, thanks for your reply too. I get your point, but I'm just surprised there's not a better API exposed, or eventing system to interface with. That said, I've been reading a bit about modules. Perhaps there's a way to use modules, but not sure yet. Thanks for the link to FSUIPC.DLL, but I really don't want to go back in time. What would be ideal, is if the publishers had created an addressable endpoint for reading\writing LVARS in any language, using a routable protocol so you could even connect to a running instance remotely. e.g. SimConnect("myipaddress:msfs_port/GraphQL_Query"). Wishful thinking :)

Thanks again for your replies.
 
They don't need to provide new interfaces. There is nothing preventing you from creating your own DLL that wraps around the SimConnect API and allows you to obtain sim data using any interface you desire. FYI, SimConnect is designed to work across networks.
 
I get your point, but I'm just surprised there's not a better API exposed, or eventing system to interface with.
1 - From what I have been reading regarding "decent and well-dcoumented totally transparent interface-into-the-oldest-Microsoft-franchise-of-software" it still feels - to me - like this was never intended and/or planned in the first place.
If Adam Szofran (the developer who wrote the first flightsim interface called "FS6IPC") had not done this, I guess no-one inside the entire add-on development scene had been able to interface with the MSFS brand at all.
- https://www.avsim.com/profile/119478-adam-szofran/
- https://forum.simflight.com/topic/5460-fsuipc-payware/


What would be ideal, is if the publishers had created an addressable endpoint for reading\writing LVARS in any language,
using a routable protocol so you could even connect to a running instance remotely. e.g. SimConnect("myipaddress:msfs_port/GraphQL_Query").
2 - This feels like a great. Is this an idea worth sharing with the lead developers of Asobo Studios?
 
Hi,

Is there a way to read\write sim variables without using a Windows App Handle to connect to FS? I've had a look at the Simvars project and done some reading and it appears that the SDK only supports connecting to FS via the SimConnect() method. i.e. Can you connect via any other protocol\stream, or do I need to use a Windows app as a middle layer to whatever I'm building?

Thanks, and hope this isn't a stupid question.
Hi, sorry for the late reply... I'm new here :)

You do not need a Window handle to use SimConnect. This is a very common misconception, and many console-based SimConnect clients I've seen create fake windows and other trickery to get around it, including lots of `sleep()`ing and other workarounds.

Meanwhile, SimConnect_Open() (in C[++]) or the SimConnect constructor (in C#, shown here but not really documented) can optionally take what is known as a "wait handle" instead of (or in addition to, I suppose) a Window handle.

I'm not going to delve into explanations of wait handles in general, but in short you can use one to "wait for" a "signal" from SimConnect that a new message is available. You then call the SimConnect message dispatch processor which in turn, essentially, returns any message(s) waiting to be processed (the exact mechanism depends on the language used). Typically this waiting would be in a new thread, but not necessarily (depending on your needs). This takes the place of using the window event processor (and is arguably better anyway since your message dispatch doesn't have to run in the main/UI thread).

For C++/WinAPI this is maybe a good reference to start with: Using Event Objects (Synchronization)
For C#/.NET this would be the equivalent: EventWaitHandle

I don't have any simple examples to point you to... but I do have a couple:

For C++ you could look at this class and search for hSimEventHandle (there are only a few instances where it is used.... it is declared in the header file as a HANDLE type).
Or another example, in a more complex code base can be seen in my WASimClient, search for hSimEvent.

For C# you can look at my SimConnectService class and search the code for EventWaitHandle _scReady then see where _scReady is used (this part is actually pretty simple, there's just lots of other code there which can be ignored). Currently defined at this line (but may change): SimConnectService.cs#L116

If you have any questions, let me know.

As a possible alternative to using SimConnect (at least directly) and for access to L vars and lots of other possibilities, you may want to investigate my WASimCommander project which is a WASM module "server" and ready-to-use client implementations for C++ and .NET (including an example for Python).

If you like Python there's also a nice library named Python-SimConnect which abstracts some of the gory details (I've not used it myself except to try it out). There are some similar "abstraction layers" for C# and probably other languages.

HTH,
-Max
 
Last edited:
Thanks Max for sharing your own coding_insights and code_sample references. Very interesting material!
 
Hi, sorry for the late reply... I'm new here :)

You do not need a Window handle to use SimConnect. This is a very common misconception, and many console-based SimConnect clients I've seen create fake windows and other trickery to get around it, including lots of `sleep()`ing and other workarounds.

Meanwhile, SimConnect_Open() (in C[++]) or the SimConnect constructor (in C#, shown here but not really documented) can optionally take what is known as a "wait handle" instead of (or in addition to, I suppose) a Window handle.

I'm not going to delve into explanations of wait handles in general, but in short you can use one to "wait for" a "signal" from SimConnect that a new message is available. You then call the SimConnect message dispatch processor which in turn, essentially, returns any message(s) waiting to be processed (the exact mechanism depends on the language used). Typically this waiting would be in a new thread, but not necessarily (depending on your needs). This takes the place of using the window event processor (and is arguably better anyway since your message dispatch doesn't have to run in the main/UI thread).

For C++/WinAPI this is maybe a good reference to start with: Using Event Objects (Synchronization)
For C#/.NET this would be the equivalent: EventWaitHandle

I don't have any simple examples to point you to... but I do have a couple:

For C++ you could look at this class and search for hSimEventHandle (there are only a few instances where it is used.... it is declared in the header file as a HANDLE type).
Or another example, in a more complex code base can be seen in my WASimClient, search for hSimEvent.

For C# you can look at my SimConnectService class and search the code for EventWaitHandle _scReady then see where _scReady is used (this part is actually pretty simple, there's just lots of other code there which can be ignored). Currently defined at this line (but may change): SimConnectService.cs#L116

If you have any questions, let me know.

As a possible alternative to using SimConnect (at least directly) and for access to L vars and lots of other possibilities, you may want to investigate my WASimCommander project which is a WASM module "server" and ready-to-use client implementations for C++ and .NET (including an example for Python).

If you like Python there's also a nice library named Python-SimConnect which abstracts some of the gory details (I've not used it myself except to try it out). There are some similar "abstraction layers" for C# and probably other languages.

HTH,
-Max
Hey, I have a dumb question. Howcome you're allowed to declare _simconnect in namespace, but I can't? I get "A namespace cannot directly contain members..."


Code:
namespace SimConnector
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.FlightSimulator.SimConnect;
using System.Runtime.InteropServices;
    /*GLOBAL SimConnect object for entire namespace?*/
    SimConnect _SimConnect;
 
Hey, I have a dumb question. Howcome you're allowed to declare _simconnect in namespace, but I can't? I get "A namespace cannot directly contain members..."


Code:
namespace SimConnector
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.FlightSimulator.SimConnect;
using System.Runtime.InteropServices;
    /*GLOBAL SimConnect object for entire namespace?*/
    SimConnect _SimConnect;

I'm not sure whose code that is (doesn't look familiar), but AFAIK the error you're getting is correct. It may have changed in some version of C#... I haven't been using it for very long but that does ring a bell.

Cheers,
-Mac
 
I'm not sure whose code that is (doesn't look familiar), but AFAIK the error you're getting is correct. It may have changed in some version of C#... I haven't been using it for very long but that does ring a bell.

Cheers,
-Mac
That's my code. It doesn't work. But when I look at https://github.com/mpaperno/MSFSTou...rtalPlugin/Services/SimConnectService.cs#L116, It looks to me like you're declaring _simconnect object in frontend... wondering why your delcaration works (assuming it does) and mine doesnt.
 
That's my code. It doesn't work. But when I look at https://github.com/mpaperno/MSFSTou...rtalPlugin/Services/SimConnectService.cs#L116, It looks to me like you're declaring _simconnect object in frontend... wondering why your delcaration works (assuming it does) and mine doesnt.
Ah, I see. But that whole file (at the link) is a Class, `SimConnectService`. The class definition is inside a namespace but that's it, all the other definitions are in the class itself. (Or maybe I'm still confused about what you mean.... the line you linked to declares a whole other variable.. ?)

-Max
 
Right after the SimConnecService class, you declare a SimConnect object. Looks to me that is not in a class... I must be misreading somehow?


C#:
public SimConnectService(ILogger<SimConnectService> logger, IReflectionService reflectionService, SimVarCollection simVarCollection) {
      _logger = logger ?? throw new ArgumentNullException(nameof(logger));
      _reflectionService = reflectionService ?? throw new ArgumentNullException(nameof(reflectionService));
      _simVarCollection = simVarCollection ?? throw new ArgumentNullException(nameof(simVarCollection));

      _simVarCollection.OnSimVarAdded += RegisterDataRequest;
      _simVarCollection.OnSimVarRemoved += DeregisterDataRequest;
    }

    #endregion Public

    const int SIM_CONNECT_TIMEOUT_MS  = 5000;   // SimConnect "Open" event timeout after successfully creating SimConnect() instance (should really be almost instant if everything is OK)
    const int MSG_RCV_WAIT_TIME_MS    = 5000;   // SimConnect.ReceiveMessage() wait time
    // maximum stored requests for error tracking (adding is fast but search is 0(n)), should be large enough to handle flood of requests at initial connection
    const int MAX_STORED_REQUEST_RECORDS = 500;
    const int WM_USER_SIMCONNECT = 0x0402;      // user event ID for SimConnect

    readonly ILogger<SimConnectService> _logger;
    readonly IReflectionService _reflectionService;
    readonly SimVarCollection _simVarCollection;

    bool _connected;
    bool _connecting;
    bool _simConnectHasQuit = false;  // flag to prevent trying to invoke SimConnect in certain situations, eg. after a Quit or crash.
    int _reqTrackIndex = 0;  // current write slot index in _requestTracking array
    uint _wasmClientId = 0xFF700C49;
    bool _wasmInitialUpdate = true;
    bool WasmConnected => WasmStatus == WasmModuleStatus.Connected;
    bool WasmInitialized => WasmStatus > WasmModuleStatus.NotFound;
    Task _messageWaitTask;
    SimConnect _simConnect;
 
Right after the SimConnecService class, you declare a SimConnect object. Looks to me that is not in a class... I must be misreading somehow?


C#:
public SimConnectService(ILogger<SimConnectService> logger, IReflectionService reflectionService, SimVarCollection simVarCollection) {
...
    }
...
    SimConnect _simConnect;
If you're referring to the code I left in just above, that's not "after" a class... you're looking at the class constructor there. If you mean that the SimConnect object isn't defined (created) in the constructor, that's correct... there's no reason it has to be. It is clearly declared in the class declaration though.
 
Hi Everyone, Life (work/family) got in the way of my FS Development projects and I'm only just getting back into it again. Thanks for all the replies, especially Max for sharing the wait handle approach. Will have a play with that tonight and see how I go.
 
Back
Top