Click or drag to resize

IEngine Interface

IT Hit User File System
Represents custom user file system. Listens to OS file system calls and calls user interfaces implementations when data is required.

Namespace:  ITHit.FileSystem
Assembly:  ITHit.FileSystem (in ITHit.FileSystem.dll) Version: 8.2.27026.0
Syntax
public interface IEngine : IFileSystemFilter, 
	IDisposable

The IEngine type exposes the following members.

Properties
  NameDescription
Public propertyLicense
Gets or sets the license text.
Public propertyThrowExceptions
Indicates if the IEngine implementation must throw exception in case of any errors in the Engine itself or in the user code occures.
Top
Methods
  NameDescription
Public methodDispose
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
(Inherited from IDisposable.)
Public methodFilterAsync
Allows filtering file system items.
(Inherited from IFileSystemFilter.)
Public methodGetFileSystemItemAsync
Gets file or folder item corresponding to the remote storage item ID.
Public methodCode exampleGetMenuCommandAsync
Gets context menu command.
Public methodIsAuthenticatedAsync
Indicates if user is authenticated.
Public methodRiseError
Rises Error event. Throws an exception if the ThrowExceptions property is set to true.
Public methodServerNotifications(Byte, ILogger)
Creates, updates, moves and deletes files and folders in the user file system. Use object returned by this method by remote storage ID to apply changes sent by the remote storage.
Public methodServerNotifications(String, ILogger)
Creates, updates, moves and deletes files and folders in the user file system. Use object returned by this method by path to apply changes sent by the remote storage.
Public methodSetRemoteStorageRootItemId
Sets remote storage item ID for the root folder.
Top
Events
  NameDescription
Public eventDebug
Event fired when the IEngine or user file system implementation code sends a debug message.
Public eventError
Event fired in case of any exceptions in the IEngine or user file system implementation code.
Public eventMessage
Event fired when the IEngine or user file system implementation code sends an informational message.
Top
Remarks

Processes file system calls from operating system and calls user interfcaces, that implement file system, such as IFile, IFolder , etc.

This calss represents a generic file system with features supported on any operating system. The Windows implementation of this interface is located in [!:ITHit.FileSystem.Windows.EngineWindows] class. The macOS implementation of this interface is in [!:ITHit.FileSystem.Mac.EngineMac].

Examples

The code below is part of 'VirtualFileSystem' C# sample provided with the SDK.

C#
public class VirtualEngine : EngineWindows
{
    internal RemoteStorageMonitor RemoteStorageMonitor;

    internal readonly Mapping Mapping;

    public VirtualEngine(string license, string userFileSystemRootPath, string remoteStorageRootPath, LogFormatter logFormatter) :
        base(license, userFileSystemRootPath)
    {
        Mapping = new Mapping(Path, remoteStorageRootPath);

        // We want our file system to run regardless of any errors.
        // If any request to file system fails in user code or in Engine itself we continue processing.
        ThrowExceptions = false;

        StateChanged += Engine_StateChanged;
        ItemsChanged += Engine_ItemsChanged;
        SyncService.StateChanged += SyncService_StateChanged;
        Error += logFormatter.LogError;
        Message += logFormatter.LogMessage;
        Debug += logFormatter.LogDebug;

        RemoteStorageMonitor = new RemoteStorageMonitor(remoteStorageRootPath, this, this.Logger);
    }

    private void Engine_ItemsChanged(Engine sender, ItemsChangeEventArgs e)
    {
        var logger = Logger.CreateLogger(e.ComponentName);
        foreach (ChangeEventItem item in e.Items)
        {

            // If update from server failed becase a file is in use,
            // try to show merge dialog (for MS Office, etc.).
            if (e.Direction == SyncDirection.Incoming
                && e.OperationType == OperationType.UpdateContent)
            {
                switch (e.Result.Status)
                {
                    case OperationStatus.FileInUse:
                        ITHit.FileSystem.Windows.AppHelper.Utilities.TryNotifyUpdateAvailable(item.Path, e.Result.ShadowFilePath);
                        break;
                }
            }

            // Log info about the opertion.
            LogItemChange(e, item);
        }
    }

    private void LogItemChange(ItemsChangeEventArgs e, ChangeEventItem item)
    {
        var logger = Logger.CreateLogger(e.ComponentName);

        switch (e.Result.Status)
        {
            case OperationStatus.Success:
                switch (e.Source)
                {
                    case OperationSource.Server:
                        logger.LogMessage($"{e.Direction} {e.OperationType}: {e.Result.Status}", item.Path, item.NewPath, e.OperationContext, item.Metadata);
                        break;
                    case OperationSource.Client:
                        logger.LogDebug($"{e.Direction} {e.OperationType}: {e.Result.Status}", item.Path, item.NewPath, e.OperationContext, item.Metadata);
                        break;
                }
                break;
            case OperationStatus.Conflict:
                logger.LogMessage($"{e.Direction} {e.OperationType}: {e.Result.Status}", item.Path, item.NewPath, e.OperationContext, item.Metadata);
                break;
            case OperationStatus.Exception:
                logger.LogError($"{e.Direction} {e.OperationType}", item.Path, item.NewPath, e.Result.Exception, e.OperationContext, item.Metadata);
                break;
            case OperationStatus.Filtered:
                logger.LogDebug($"{e.Direction} {e.OperationType}: {e.Result.Status} by {e.Result.FilteredBy.GetType().Name}", item.Path, item.NewPath, e.OperationContext, item.Metadata);
                break;
            default:
                logger.LogDebug($"{e.Direction} {e.OperationType}: {e.Result.Status}. {e.Result.Message}", item.Path, item.NewPath, e.OperationContext, item.Metadata);
                break;
        }
    }

    public override async Task<bool> FilterAsync(SyncDirection direction, OperationType operationType, string path, FileSystemItemType itemType, string newPath, IOperationContext operationContext)
    {

        if (await new ZipFilter().FilterAsync(direction, operationType, path, itemType, newPath, operationContext))
        {
            return true;
        }

        if (await new MsOfficeFilter().FilterAsync(direction, operationType, path, itemType, newPath, operationContext))
        {
            return true;
        }

        if (await new AutoCadFilter().FilterAsync(direction, operationType, path, itemType, newPath, operationContext))
        {
            return true;
        }

        if (await new ErrorStatusFilter().FilterAsync(direction, operationType, path, itemType, newPath, operationContext))
        {
            return true;
        }

        return false;
    }

    public override async Task<IFileSystemItem> GetFileSystemItemAsync(byte[] remoteStorageItemId, FileSystemItemType itemType, IContext context, ILogger logger = null)
    {
        string userFileSystemPath = context.FileNameHint;
        if (itemType == FileSystemItemType.File)
        {
            return new VirtualFile(Mapping, userFileSystemPath, logger);
        }
        else
        {
            return new VirtualFolder(Mapping, userFileSystemPath, logger);
        }
    }

    public override async Task<IMenuCommand> GetMenuCommandAsync(Guid menuGuid, IOperationContext operationContext = null)
    {
        // For this method to be called you need to register a menu command handler.
        // See method description for more details.

        throw new NotImplementedException();
    }

    public override async Task StartAsync(bool processModified = true, CancellationToken cancellationToken = default)
    {
        await base.StartAsync(processModified, cancellationToken);
        await RemoteStorageMonitor.StartAsync();
    }

    public override async Task StopAsync()
    {
        await base.StopAsync();
        await RemoteStorageMonitor.StopAsync();
    }

    private void Engine_StateChanged(Engine engine, EngineWindows.StateChangeEventArgs e)
    {
        engine.Logger.LogMessage($"{e.NewState}", this.Path);
    }

    private void SyncService_StateChanged(object sender, SynchEventArgs e)
    {
        if (e.NewState == SynchronizationState.Enabled || e.NewState == SynchronizationState.Disabled)
        {
            SyncService.Logger.LogMessage($"{e.NewState}", this.Path);
        }
    }

    private bool disposedValue;

    protected override void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                RemoteStorageMonitor.Dispose();
            }

            // TODO: free unmanaged resources (unmanaged objects) and override finalizer
            // TODO: set large fields to null
            disposedValue = true;
        }
        base.Dispose(disposing);
    }
}

The code below is part of 'VirtualFileSystem' C# sample provided with the SDK.

C#
public static async Task Main(string[] args)
{
    // Load Settings.
    Settings = new ConfigurationBuilder().AddJsonFile("appsettings.json", false, true).Build().ReadSettings();

    logFormatter = new LogFormatter(log, Settings.AppID);
    WindowManager.ConfigureConsole();

    // Log environment description.
    logFormatter.PrintEnvironmentDescription();

    registrar = new Registrar(log);
    consoleProcessor = new ConsoleProcessor(registrar, logFormatter, Settings.AppID);

    try
    {
        // Register sync root and create app folders.
        await registrar.RegisterSyncRootAsync(
            SyncRootId, 
            Settings.UserFileSystemRootPath, 
            Settings.RemoteStorageRootPath,
            Settings.ProductName, 
            Path.Combine(Settings.IconsFolderPath, "Drive.ico"));

        using (Engine = new VirtualEngine(
            Settings.UserFileSystemLicense,
            Settings.UserFileSystemRootPath,
            Settings.RemoteStorageRootPath,
            logFormatter))
        {
            commands = new Commands(Engine, Settings.RemoteStorageRootPath, log);
            commands.RemoteStorageMonitor = Engine.RemoteStorageMonitor;
            consoleProcessor.Commands.TryAdd(Guid.Empty, commands);

            // Here we disable incoming sync. To get changes from your remote storage using pooling, call the IncomingPooling.ProcessAsync() method.
            Engine.SyncService.IncomingSyncMode = ITHit.FileSystem.Synchronization.IncomingSyncMode.Disabled;

            // Set the remote storage item ID for the root item. It will be passed to the IEngine.GetFileSystemItemAsync()
            // method as a remoteStorageItemId parameter when a root folder is requested. 
            // In this sample we do not set the ID becuse in case of a network path the ID is not available.
            //Engine.SetRemoteStorageRootItemId(rootItemId);

            // Print console commands.
            consoleProcessor.PrintHelp();

            // Print Engine config, settings, logging headers.
            await logFormatter.PrintEngineStartInfoAsync(Engine, Settings.RemoteStorageRootPath);

            // Start processing OS file system calls.
            await Engine.StartAsync();

            // Sync all changes from remote storage one time for demo purposes.
            await Engine.SyncService.IncomingPooling.ProcessAsync();
G
            // Opens Windows File Manager with user file system folder and remote storage folder.
            commands.ShowTestEnvironment(Settings.ProductName);
#endif
            // Keep this application running and reading user input.
            await consoleProcessor.ProcessUserInputAsync();
        }
    }
    catch (Exception ex)
    {
        log.Error(ex);
        await consoleProcessor.ProcessUserInputAsync();
    }
}
See Also