Виртуальная файловая система для объединения двух директорий

Есть некое приложение (написанное не мной и доступа к нему нет), которое возможно расширить различными модификациями, делается это простым размещением .dll файлов рядом с основным .exe.

Со временем, у данного проекта накапливается очень много подобных расширений и главная директория превращается в помойку, где трудно найти оригинальные файлы и файлы расширений.

Сейчас решил побороть эту проблему и отделить модификации от основного приложения, поместив их в отдельную директорию, но вот незадача - проект переписать не могу, из другой директории он не регистрирует модификации. Думал решить эту проблему при помощи "символических ссылок" (и их аналогов), но попал в некий тупик, где мне пришлось бы уйму файлов прописывать вручную данными ссылками и если произойдет добавление/удаление чего либо, то опять же, создавать новую ссылку руками. Также для решения этой задачи при помощи ссылок, мне придется все перенаправлять в одну директорию, которая будет некой файловой помойкой и уже от туда запускать проект, согласитесь, не очень удобное решение...

Долго размышляя над этим всем я вспомнил, что довольно давно видел проект, который позволял отсоединить от игры профили, настройки, модификации и все остальное и делал это он все довольно элегантно, сохраняя все в одной директории игры. Звался тот проект Mod Organizer. Изучив особенности данной программы я понял, что они используют так называемую "Виртуальную файловую систему" / VFS (Virtual File System), это как я понял некий абстрактный слой над основной файловой системой OS, который как-раз и позволит сделать то, чего я хочу.

Поискав хотя бы простую реализацию подобного, я наткнулся на библиотеки по типу Zio, которые вроде это умеют делать, но как бы я их не крутил - результат нулевой, я не могу даже просто соединить две реальных директории в 1 виртуальную, уж про запуск программы я молчу..

Вопрос: Ребят, подтолкните на правильный путь, помогите реализовать VFS, которая соединила бы в себе две директории в 1 и запустила бы проект.

Пример директорий:

  • До:

    /App/Application.exe
    /App/SomeMod.dll
    /App/SomeMod2.dll

  • После:

    /App/Application.exe
    /Modifications/SomeMod.dll
    /Modifications/SomeMod2.dll

И при запуске /App/Application.exe программа находит все в Modifications, регистрирует их и успешно запускается.


Ответы (2 шт):

Автор решения: user7860670

Подобных результатов можно достичь несколькими способами. Например вместо копирования файлов расширений туда-сюда можно создавать жесткие ссылки NTFS (hard links). Или использовать NTFS reparse points, простейшим случаем которых являются символические ссылки (symbolic links) и монтируемые папки, а более продвинутые сценарии использования требуют написания драйверов. Также существует альтернативный вариант с написанием расширения оболочки (Shell Namespace Extensions). Есть API для монтирования облачных файловых хранилищ (Сloud Sync Engines). Ну а в качестве более удобного варианта для локальной работы можно использовать API проецируемой файловой системы (Projected File System (ProjFS)).

Этот вариант не требует написания драйверов, все делается в userspace буквально в несколько строк. Начинаете монтирование вызовом PrjMarkDirectoryAsPlaceholder указывая путь для монтируемой папки и придуманный GUID и запускаете обработчик вызовом PrjStartVirtualizing указывая путь для монтируемой папки и пачку функций обратного вызова в которых можно по-своему реализовать перечисление содержимого этой папки и доступ непосредственно к данным.

В качестве полноценного примере можно поглядеть Virtual File System for Git.


ЗЫ мне представляется, что для простого менеджера расширений будет более чем достаточно просто обрабатывать файлики с описанием расширений (то бишь со списком файликов, которые относятся к этому расширению) и переименовывать соответствующие .dll например в .dll~ чтобы они не подгружались и обратно.

→ Ссылка