public SuperMemoFilePath(FilePath filePath, NativeDataCfg nativeDataCfg)
            {
                FilePath = filePath;

                HasErrors = SMA.Utils.SuperMemoFinder.CheckSuperMemoExecutable(nativeDataCfg, filePath, out _, out var ex) == false;
                _ex       = ex;
            }
        public static bool CheckSuperMemoExecutable(
            NativeDataCfg nativeDataCfg,
            FilePath smFile,
            out NativeData nativeData,
            out SMAException ex)
        {
            nativeData = null;

            if (smFile == null)
            {
                ex = new SMAException("SM exe file path is null", new ArgumentNullException(nameof(smFile)));
                return(false);
            }

            if (smFile.Exists() == false)
            {
                ex = new SMAException(
                    $"Invalid file path for sm executable file: '{smFile}' could not be found. SMA cannot continue.");
                return(false);
            }

            if (smFile.HasPermission(FileIOPermissionAccess.Read) == false)
            {
                ex = new SMAException($"SMA needs read access to execute SM executable at {smFile.FullPath}.");
                return(false);
            }

            if (smFile.IsLocked())
            {
                ex = new SMAException($"{smFile.FullPath} is locked. Make sure it isn't already running.");
                return(false);
            }

            var smFileCrc32 = FileEx.GetCrc32(smFile.FullPath);

            nativeData = nativeDataCfg.SafeGet(smFileCrc32.ToUpper(CultureInfo.InvariantCulture));

            if (nativeData == null)
            {
                ex = new SMAException($"Unknown SM executable version with crc32 {smFileCrc32}.");
                return(false);
            }

            ex = null;

            return(true);
        }