Source code for flexicon.code.FLExGlobals
#
# FLExGlobals.py
#
# Module: FieldWorks Language Explorer path initialisation.
#
# This module sets up the path for import of the
# FieldWorks Assemblies.
#
# Platform: Python.NET & IRONPython
# FieldWorks Version 9.0, 9.1
#
# Copyright Craig Farrow, 2011 - 2022
#
import sys
import os
import platform
import glob
import shutil
import clr
import System
clr.AddReference("System.Data")
from System import Environment
from System.Reflection import Assembly
from Microsoft.Win32 import Registry, RegistryKey
import logging
logger = logging.getLogger(__name__)
# ----------------------------------------------------------------
# Public globals
FWCodeDir = None
FWProjectsDir = None
FWExecutable = None
FWShortVersion = None
FWLongVersion = None
# (Double dirname() goes up a directory)
APIHelpFile = os.path.join(os.path.dirname(os.path.dirname(__file__)), r"docs\flexlibsAPI\flexlibs2.html")
# ----------------------------------------------------------------
# FieldWorks registry constants
FW_SUPPORTED_VERSIONS = ["9"]
FWREG_CODEDIR = "RootCodeDir"
FWREG_PROJECTSDIR = "ProjectsDir"
FWRegKeys = {
"9": r"SOFTWARE\SIL\FieldWorks\9",
}
# ----------------------------------------------------------------
[docs]
def GetFWRegKey():
logger.info(".NET version: %s" % Environment.Version)
# Note: The registry looks up 32bit (via WOW3264Node) if we are
# running 32 bit Python, so no need for special handling.
python32or64 = platform.architecture()[0] # "32bit"/"64bit"
for fwVersion in FW_SUPPORTED_VERSIONS:
logger.info("Looking for FieldWorks %s, %s..." % (fwVersion, python32or64))
RegKey = FWRegKeys[fwVersion]
rKey = Registry.CurrentUser.OpenSubKey(RegKey)
logger.info("GetFWRegKey: %s => %s" % (RegKey, rKey))
if rKey and rKey.GetValue(FWREG_CODEDIR):
return rKey
rKey = Registry.LocalMachine.OpenSubKey(RegKey)
logger.info("GetFWRegKey: %s => %s" % (RegKey, rKey))
if rKey and rKey.GetValue(FWREG_CODEDIR):
return rKey
msg = "%s FieldWorks %s not found" % (python32or64, " or ".join(FW_SUPPORTED_VERSIONS))
raise Exception(msg)
# -------------------------------------------------------------------
[docs]
def InitialiseFWGlobals():
global FWCodeDir
global FWProjectsDir
global FWExecutable
global FWShortVersion
global FWLongVersion
try:
rKey = GetFWRegKey()
except Exception as e:
logging.exception("Couldn't find FieldWorks registry entry")
raise
if platform.system() == "Linux":
# Linux support is incomplete: as of Apr2024 FW uses flatpak and
# this path no longer works. On installed Linux FW,
# FWREG_CODEDIR points to /usr/share/fieldworks,
# but FieldWorks.exe resides in /usr/lib/fieldworks.
# I can't find any registry keys/values that point to
# the correct location.
# For installed version, the app calls /bin/fieldworks-flex
# from /usr/share/applications/fieldworks-applicatoins.desktop,
# which in turn calls /usr/lib/fieldworks/run-app FieldWorks.exe etc.
#
# The following is based on the logic in /usr/lib/fieldworks/environ
FWCodeDir = os.path.join(rKey.GetValue(FWREG_CODEDIR), "../../lib/fieldworks")
else:
# On windows, FWREG_CODEDIR is correct.
FWCodeDir = rKey.GetValue(FWREG_CODEDIR)
# FWREG_PROJECTSDIR is correct on Windows and Linux.
FWProjectsDir = rKey.GetValue(FWREG_PROJECTSDIR)
if not os.access(os.path.join(FWCodeDir, "FieldWorks.exe"), os.F_OK):
# On developer's machines we also check the build directories
# for FieldWorks.exe
if platform.system() == "Linux":
devPaths = [
os.path.dirname(rKey.GetValue(FWREG_CODEDIR)),
]
else:
# Windows
devPaths = [
os.path.join(FWCodeDir, r"..\Output\Release\\"),
os.path.join(FWCodeDir, r"..\Output\Debug\\"),
]
for p in devPaths:
if os.access(os.path.join(p, "FieldWorks.exe"), os.F_OK):
FWCodeDir = p
break
else:
# This can happen if there is a ghost registry entry for
# an uninstalled FLEx
msg = "FieldWorks.exe not found in %s" % FWCodeDir
logger.error(msg)
raise Exception(msg)
FWExecutable = os.path.join(FWCodeDir, "FieldWorks.exe")
# Add the FW code directory to the search path for importing FW libs.
sys.path.append(FWCodeDir)
logger.info("sys.path = \n\t%s" % "\n\t".join(sys.path))
# These can't be imported until the path is set:
clr.AddReference("FwUtils")
from SIL.FieldWorks.Common.FwUtils import VersionInfoProvider
# Get the full version information out of FW itself
vip = VersionInfoProvider(Assembly.GetAssembly(VersionInfoProvider), False)
FWShortVersion = System.Version(vip.ShortNumericAppVersion) # e.g. 8.1.3
FWLongVersion = vip.ApplicationVersion
logger.info("Found FieldWorks installation")
logger.info("FWCodeDir = %s" % FWCodeDir)
logger.info("FWProjectsDir = %s" % FWProjectsDir)
logger.info("FWShortVersion = %s" % FWShortVersion)
logger.info("FWLongVersion = %s" % FWLongVersion)