Flight Simulator X, EZCA and FreeTrack

1) The problem

If you are running all three mentioned in the title, you probably have  a problem. The problem is that EZCA and FreeTrack kind of don’t like each other. When EZCA and FreeTrack are running together (at the same time), EZCA will crash after some time. Usually, it takes between 10-25 minutes. As the result, you will get a bunch of error messages related to memory access violation.

As I found out, there is memory leak when EZCA is running and FreeTrack is providing head movement inputs to it via TrackIR interface. Do not want to go into great detail here. Simply saying, EZCA memory usage slowly rises up to the point where you will get memory access violation error. At my system, this happens when it eats about 160MB of memory and it takes about 20 minutes to happen.

With FreeTrack running, EZCA eated nearly 150MB of memory. At this value, memory consumption stopped and EZCA crashed.

When it does, you have to close EZCA, close FreeTrack and than start FreeTrack and EZCA again (FreeTrack first, than EZCA). Well you can imagine this is quite annoying, considering you have to do that every 15-20 minutes or so.

One solution has been posted here: ECZA-FreeTrack Problem. [The site: http://passionfsx.iblogger.org/?page_id=164 is offline. Checked at 17.11.2013] The solution described on this page is based on the fact, that you need to close EZCA before it crashes due to the memory leak issue and then start it again. This was achiveved using two programs, that together manage to close and start over EZCA every 10-15 minutes, or whatever time inetrval you set. Thanks to this you should not see those error messages again and you don’t have to close and start anything manually. The only issue you will face is “freeze” of you view for couple of seconds during EZCA restart. While this solution works, it has some shortcomings.

First, I don’t like the idea to install and run another 2 programs while flying. It is true that these two programs will not have any mentionable performance hit, it is just that I try to keep my flight simulator computer as clean as possible.

Second, which is more painful, is the fact that with my configuration (Windows 8, nVidia graphic card) it does not work as shown. It will prevent EZCA from throwing those errors on you. But the problem is, that EZCA is quite agressive when it is starting so to say. It will steal focus from FSX when it is starting. I suspect this is because it is switching itself to High priority during start and FSX is normally running on Normal. However, at least with Nvidia graphic card, when this happens, FSX will minimize if you are running on fullscreen. I think you will agree, this is also annoying to happen every 10 minutes. If you are running FSX in windowed mode, focus will be stolen but at least you will see where you are flying.

2) My solution

To overcome the first shortcoming, I wrote my own PowerShell script which follows the same solution as that post mentioned above. It uses just operating system resources – no need to install anything (Except PowerShell at Windows XP where it is not standard part as in Vista or later).

Overcoming of second issue has proved to be more challenging that I originally thought and I was not 100% percent successful. But after 3 months of trying (well I did not work on that script every day), I got my script in stage where I think it is usable. If you will run FSX in windowed mode, the script will return focus to it quickly so you may not notice it was stolen. In fullscreen mode, FSX will still get minimized (at least on nVidia), but the script is able to restore window back to fullscreen. This process will take a couple of seconds and while still annoying, it is usable, at least by my opinion.

3) The script

You can download the script below. I believe the script is written in the way that you can set it and forget about it. Personally, I have set it as scheduled task that runs every 2 minutes. The script requires PowerShell v2, which is standard part of Windows Vista and above and can be downloaded for Windows XP.

The script is licensed under GPL v3 and it comes WITHOUT ANY WARRANTY. Use it at your own risk.

V 1.1 is new version released on 17.11.2013. This one uses different approach to monitor EZCA memory consumption. For more details, read: Flight Simulator X, EZCA and FreeTrack – restart script v 1.1 or look at .CHANGES section in the script comments.

Old version:

The archive contains 3 files:

  • silent_power_shell.vbs – Wrapper script to run our EZCA restart script. It will supress PowerShell console from showing. NOT my work. See its code for remarks.
  • ezca_restart.ps1 – Script to restart EZCA.
  • LICENSE.txt – Copy of GPL v3 license under which the script is released.

3.1) How does it work?

I tried to comment the script extensively. Hope you will “read” it the same way. The script behavior is commented in its source but I guess it would be nice to write it here too.

At the beginning, the script does a couple of checks. It checks if FSX is running and it quits if it does not. Depending on script settings, it checks if FreeTrack is running and quits if it does not. Than path to EZCA executable file is constructed and checked. If it is not valid, the script quits. Next check is there to find out if EZCA is running. Again, if it is not, the script quits (but you can force to run EZCA by script settings). Last check happens if control of EZCA memory usage is enabled. IF it is, script checks if EZCA memory usage is close to threshold where EZCA will eventually crash. If it is, script continues. Otherwise the script quits. If all checks are passed, EZCA is closed if it was running and it is started again. Than, a waiting loop of defined length is started. This is to wait for EZCA to load.

I did not find any better approach to tell when EZCA is ready. You need to test to see what time is needed for your system. Default is 5 seconds.

Within that waiting loop, three actions may happen if enabled by script settings. These are: EZCA priority and/or affinity may be set to predefined level and FSX window is restored if it was stolen focus (it is not foreground window).

Also, you can find short log file at the same folder where the script is saved. This log file is re-created by every script execution. Log name is: ezca_restart.txt.

It might seem complicated, but it is not as much as it was to write it 🙂

3.2) Script settings

You can modify script behavior by settings certain variables and options within the script. Lets talk about the ones you will likely to change. Speaking of script all the time, setting it’s options is not much user friendly. It actually means rewriting them in the script source code. I will try to explain what to do below. But if you will have no understanding of what I am writing about, default settings should work OK for you.

3.2.1) Modifying script decision making

Options for certain script decisions are defined by this enumeration:

public enum ScriptOptions 
 {
 # <summary>
 # Whether the script should modify EZCA priority
 # </summary>
 EZCA_MODIFY_PRIORITY = 1, 
 # <summary>
 # Whether the script should modify EZCA affinity
 # </summary>
 EZCA_MODIFY_AFFINITY = 2,
 # <summary>
 # Whether the script should EZCA even if it was not running. 
 # NOTE: Due to preceding checks, FSX must be running and EZCA executable 
 # path must me be also valid
 # </summary>
 EZCA_START_IF_NOT_RUNNING = 4,
 # <summary>
 # Whether the EZCA should be restarted only when FreeTrack is running. (ie. script will
 # terminate if Freetrack is not running)
 # </summary>
 EZCA_RESTART_ONLY_IF_FREETRACK_RUNNING = 8,
 # <summary>
 # If the script should make FSX window fullxscreen. (ie. This is NOT true fullscreen.
 # This will only maximize FSX window to cover whole screen if it is running in windowed
 # mode)
 # </summary>
 FSX_MAKE_WINDOW_FULLSCREEN = 16,
 # <summary>
 # Whether the script should restore FSX window if is no longer in foreground.
 # </summary>
 FSX_KEEP_FOREGROUND = 32,
 # <summary>
 # Whether the script should decide whether to kill EZCA by its memory usage.
 # See $EZCA_PRIVATE_BYTES_LIMIT, $EZCA_PRIVATE_BYTES_SMARGIN, $EZCA_PRIVATE_BYTES_MEASURE_TIME
 # and $TASK_INTERVAL and step 5.1
 # </summary>
 EZCA_RESTART_BY_MEM_LIMIT = 64 
}

These options are set at this line:

New-Variable SCRIPT_OPTIONS -Value ([ScriptOptions]::EZCA_START_IF_NOT_RUNNING -bor
         [ScriptOptions]::FSX_KEEP_FOREGROUND -bor
         [ScriptOptions]::EZCA_RESTART_ONLY_IF_FREETRACK_RUNNING -bor
         [ScriptOptions]::EZCA_RESTART_BY_MEM_LIMIT)

To add option, just type -bor after the last option and add one defined above. It must include enumeration name, ie. [ScriptOptions]. To unset option, just delete it. But make sure that there is one option at each side of -bor operator. It really hates to be alone from one side or another. The options shoved above are the default script options.

3.2.2) Checking of EZCA memory usage

The check of EZCA memory usage is enabled by default. This way, EZCA does not have to be restarted so often. At my system, the peak memory consumption before EZCA crashes is about 160MB and it takes about 20-22 minutes for EZCA to eat this amount of memory. I tested this only on my computer, so can’t promise it will be the same on yours. For that reason, there are some variables to modify for different memory limits:

# Max EZCA private memory bytes limit in Kb. If it rises above this value, EZCA is about to crash
New-Variable EZCA_PRIVATE_BYTES_LIMIT -Value 153600 -Option ReadOnly
# Safety margin for EZCA private memory bytes consumption
New-Variable EZCA_PRIVATE_BYTES_SMARGIN -Value 600 -Option ReadOnly
# For how long we will record EZCA memory consumption
New-Variable EZCA_PRIVATE_BYTES_MEASURE_TIME -Value 4 -Option ReadOnly
# What is the time interval between task execution in seconds
New-Variable TASK_INTERVAL -Value 120 -Option ReadOnly

The code that control EZCA memory usage gets memory usage between EZCA_PRIVATE_BYTES_MEASURE_TIME seconds. Based on the difference it calculates a memory usage rate of growth. Than it checks if approximate EZCA memory usage after TASK_INTERVAL seconds (ie. next time the script runs) will be greater than  (EZCA_PRIVATE_BYTES_LIMIT EZCA_PRIVATE_BYTES_SMARGIN). Saying another way, if EZCA memory consumption by the next time the script runs will be greater than maximum safe EZCA memory consuption. This is how the script decides if it is needed to restart EZCA now or if it may wait for next run. These are the variables you need to modify if EZCA crashes at memory usage different than about 160MB.

And of course make sure the relevant option is enabled, as it is by default:

New-Variable SCRIPT_OPTIONS -Value ([ScriptOptions]::EZCA_START_IF_NOT_RUNNING -bor
 [ScriptOptions]::FSX_KEEP_FOREGROUND -bor
 [ScriptOptions]::EZCA_RESTART_ONLY_IF_FREETRACK_RUNNING -bor
 [ScriptOptions]::EZCA_RESTART_BY_MEM_LIMIT)
3.2.3) To modify EZCA priority

Add [ScriptOptions]::EZCA_MODIFY_PRIORITY to EZCA_OPTIONS like that:

New-Variable SCRIPT_OPTIONS -Value ([ScriptOptions]::EZCA_START_IF_NOT_RUNNING -bor
 [ScriptOptions]::EZCA_RESTART_ONLY_IF_FREETRACK_RUNNING -bor
 [ScriptOptions]::FSX_KEEP_FOREGROUND -bor 
 [ScriptOptions]::EZCA_MODIFY_PRIORITY)

And set desired priority using this line in the code:

[System.Diagnostics.ProcessPriorityClass]$EZCA_PRIORITY = [System.Diagnostics.ProcessPriorityClass]::Normal

Another possible values are:

  • [System.Diagnostics.ProcessPriorityClass]::RealTime
  • [System.Diagnostics.ProcessPriorityClass]::AboveNormal
  • [System.Diagnostics.ProcessPriorityClass]::High
  • [System.Diagnostics.ProcessPriorityClass]::BelowNormal
  • [System.Diagnostics.ProcessPriorityClass]::Idle

But I would NOT recommend setting any other than normal. High and above will most likely help EZCA steal focus and prolong FSX window recovery time. Lower priority may be too low and camera view may be less responsive, especially when looking around.

3.2.4) To modify EZCA affinity

Affinity tells operating system which cores (physical and logical ones) the program should utilize. Usually OS will decide by itself and most likely will allow the program to use all logical processors. When fine-tuning FSX, some restrict’s addon programs to use different processors than FSX uses. This is very short explanation and it is kind of advanced topic. If you want the script to modify EZCA affinity, set [ScriptOptions]::EZCA_MODIFY_AFFINITY option like that:

New-Variable SCRIPT_OPTIONS -Value ([ScriptOptions]::EZCA_START_IF_NOT_RUNNING -bor
 [ScriptOptions]::EZCA_RESTART_ONLY_IF_FREETRACK_RUNNING -bor
 [ScriptOptions]::FSX_KEEP_FOREGROUND -bor 
 [ScriptOptions]::EZCA_MODIFY_AFFINITY)

And set desired affinity:

New-Variable EZCA_AFFINITY -Value ([Convert]::ToInt32([System.Math]::Pow(2,[System.Math]::Ceiling($processor_info.NumberOfLogicalProcessors / 2)) - 1)) -Option ReadOnly

Above is script default value of affinity that enables EZCA to run on half of all available logical processors. You can modify that to suit your needs.

As I wrote, affinity is advanced topic. So if you do not know anything about it, leave this option disabled or use default one. If you want to know more, Google or Wikipedia will help you for sure.

4) Set it and forget it

I wrote that I use this script as scheduled task and I suggest you to use it the same way if you like it.  In the archive you were able to download above, there are two files:

  • silent_power_shell.vbs – Helps to supress PowerShell console when running script. NOT my work. See its code for remarks.
  • ezca_restart.ps1 – Actual script.

Extract these two files at some folder. I have them in the C:\EZdok Software\ folder, which was made by EZCA installer. Now we will set scheduled task. Open Task Scheduler. There are couple of ways to do it, depending on operating system. On Vista and later, the faster way is probably to click Start and type: task in the search box. Task Scheduler should appear as the first result. Another way is to open Control Panel -> System and Security -> Administrative Tools -> Task Scheduler.

Within the Task Scheduler, select Action -> Create Task… The Create Task window will show. On the General tab, enter task name such as: EZCA Restart. Than select: Run only when user is logged on and Run with highest privileges.

On Triggers tab, click New… . If you are going to use EZCA memory usage control option, set the task to run about every 2-4 minutes. Otherwise, set it to repeat about every 10-15 minutes (or another time period that works for you). In both cases, repeat indefinitely. Than you can add trigger with OK button.

On Actions tab, click New… and select Action: Start a program. In the Program/script text field enter: wscript. In the Add Arguments (Optional): text field, enter: “c:\EZdok Software\silent_power_shell.vbs” “c:\EZdok Software\ezca_restart.ps1”. Of course replace c:\EZdok Software\ with path to folder where you saved the script. Confirm action with OK button. You can leave the other tabs as they are and click OK once again to create scheduled task.

Everything is shown in the following gallery:

If everything set correctly, you should find ezca_restart.txt at the folder where the script is located after the script ran. (So if you set everything like I showed and I have, C:\EZdok Software\ezca_restart.txt will be there after each execution of scheduled task).

5) Seeing is believing

As the last paragraph of this ever prolonging post, there is video demonstrating this script. You can see how it looks when you run FSX in fullscreen, windowed mode and windowed mode when you have enabled option to make fullscreen window. So in case of any problems, at least I can say: Hey, it worked for me, see…