diff --git a/assets/jsons/translations/de.json b/assets/jsons/translations/de.json index d51065ab..c7e7a533 100644 --- a/assets/jsons/translations/de.json +++ b/assets/jsons/translations/de.json @@ -641,6 +641,7 @@ "EPERM": "BSManager hat nicht die erforderlichen Berechtigungen, um den Ordner zu verknüpfen.", "EACCES": "BSManager hat nicht die erforderlichen Berechtigungen, um den Ordner zu verknüpfen.", "ENOSPC": "Die Festplatte ist voll, machen Sie Platz und versuchen Sie es erneut.", + "LinkingNotSupported": "Ordnerverknüpfung wird auf diesem Dateisystem nicht unterstützt.", "UNKNOWN_ERROR": "Ein unbekannter Fehler ist beim Verknüpfen des Ordners aufgetreten." } }, diff --git a/assets/jsons/translations/en.json b/assets/jsons/translations/en.json index 90d3fe7f..8b769c7d 100644 --- a/assets/jsons/translations/en.json +++ b/assets/jsons/translations/en.json @@ -641,6 +641,7 @@ "EPERM": "BSManager does not have the necessary permissions to link the folder.", "EACCES": "BSManager does not have the necessary permissions to link the folder.", "ENOSPC": "The disk is full, make some space and try again.", + "LinkingNotSupported": "Folder linking is not supported on this file system.", "UNKNOWN_ERROR": "An unknown error has occurred while linking the folder." } }, diff --git a/assets/jsons/translations/es.json b/assets/jsons/translations/es.json index 639a59ee..61cba828 100644 --- a/assets/jsons/translations/es.json +++ b/assets/jsons/translations/es.json @@ -641,6 +641,7 @@ "EPERM": "BSManager no tiene los permisos necesarios para enlazar la carpeta.", "EACCES": "BSManager no tiene los permisos necesarios para enlazar la carpeta.", "ENOSPC": "El disco está lleno, libera espacio e inténtalo de nuevo.", + "LinkingNotSupported": "El enlace de carpetas no es compatible con este sistema de archivos.", "UNKNOWN_ERROR": "Se ha producido un error desconocido al enlazar la carpeta." } }, diff --git a/assets/jsons/translations/fr.json b/assets/jsons/translations/fr.json index 9f626b80..09ff7267 100644 --- a/assets/jsons/translations/fr.json +++ b/assets/jsons/translations/fr.json @@ -641,6 +641,7 @@ "EPERM": "BSManager n'a pas les autorisations nécessaires pour lier le dossier.", "EACCES": "BSManager n'a pas les autorisations nécessaires pour lier le dossier.", "ENOSPC": "Le disque est plein, faites de la place et réessayez.", + "LinkingNotSupported": "La liaison de dossier n'est pas supportée sur ce système de fichiers.", "UNKNOWN_ERROR": "Une erreur inconnue est survenue lors de la liaison du dossier." } }, diff --git a/assets/jsons/translations/it.json b/assets/jsons/translations/it.json index d91f50ff..6be54279 100644 --- a/assets/jsons/translations/it.json +++ b/assets/jsons/translations/it.json @@ -641,6 +641,7 @@ "EPERM": "BSManager non ha i permessi necessari per condividere la cartella.", "EACCES": "BSManager non ha i permessi necessari per condividere la cartella.", "ENOSPC": "Il disco è pieno, libera un pò di spazio e riprova.", + "LinkingNotSupported": "Il collegamento delle cartelle non è supportato su questo file system.", "UNKNOWN_ERROR": "C'è stato un errore sconosciuto durante la condivisione della cartella." } }, diff --git a/assets/jsons/translations/ja.json b/assets/jsons/translations/ja.json index 2622dcd4..356fb81e 100644 --- a/assets/jsons/translations/ja.json +++ b/assets/jsons/translations/ja.json @@ -641,6 +641,7 @@ "EPERM": "BSManagerにはフォルダをリンクするための必要な権限がありません。", "EACCES": "BSManagerにはフォルダをリンクするための必要な権限がありません。", "ENOSPC": "ディスクがいっぱいです。空き容量を作ってもう一度試してください。", + "LinkingNotSupported": "このファイルシステムではフォルダのリンクはサポートされていません。", "UNKNOWN_ERROR": "フォルダをリンク中に不明なエラーが発生しました。" } }, diff --git a/assets/jsons/translations/ko.json b/assets/jsons/translations/ko.json index a63919d3..d95476be 100644 --- a/assets/jsons/translations/ko.json +++ b/assets/jsons/translations/ko.json @@ -641,6 +641,7 @@ "EPERM": "BSManager에 폴더를 연결하기 위한 권한이 부족합니다.", "EACCES": "BSManager에 폴더를 연결하기 위한 권한이 부족합니다.", "ENOSPC": "디스크가 가득 찼습니다. 공간을 확보하고 다시 시도하세요.", + "LinkingNotSupported": "이 파일 시스템에서는 폴더 연결이 지원되지 않습니다.", "UNKNOWN_ERROR": "폴더를 연결하는 중 알 수 없는 오류가 발생했습니다." } }, diff --git a/assets/jsons/translations/ru.json b/assets/jsons/translations/ru.json index 902367b3..d583e90e 100644 --- a/assets/jsons/translations/ru.json +++ b/assets/jsons/translations/ru.json @@ -641,6 +641,7 @@ "EPERM": "BSManager не имеет необходимых прав для связывания папки.", "EACCES": "BSManager не имеет необходимых прав для связывания папки.", "ENOSPC": "Диск заполнен, освободите место и попробуйте снова.", + "LinkingNotSupported": "Ссылки на папки не поддерживаются в этой файловой системе.", "UNKNOWN_ERROR": "Произошла неизвестная ошибка при связывании папки." } }, diff --git a/assets/jsons/translations/zh-tw.json b/assets/jsons/translations/zh-tw.json index ce2b6964..bec5592d 100644 --- a/assets/jsons/translations/zh-tw.json +++ b/assets/jsons/translations/zh-tw.json @@ -641,6 +641,7 @@ "EPERM": "BSManager沒有必要的權限來連結文件夾。", "EACCES": "BSManager沒有必要的權限來連結文件夾。", "ENOSPC": "磁碟已滿,請騰出空間後再試。", + "LinkingNotSupported": "該檔案系統不支援資料夾連結。", "UNKNOWN_ERROR": "連結文件夾時發生未知錯誤。" } }, diff --git a/assets/jsons/translations/zh.json b/assets/jsons/translations/zh.json index f5a6cd15..93434081 100644 --- a/assets/jsons/translations/zh.json +++ b/assets/jsons/translations/zh.json @@ -641,6 +641,7 @@ "EPERM": "BSManager没有必要的权限来链接文件夹。", "EACCES": "BSManager没有必要的权限来链接文件夹。", "ENOSPC": "磁盘已满,请腾出空间后再试。", + "LinkingNotSupported": "该文件系统不支持文件夹链接。", "UNKNOWN_ERROR": "链接文件夹时发生未知错误。" } }, diff --git a/src/main/services/folder-linker.service.ts b/src/main/services/folder-linker.service.ts index 65e9f507..277f3c83 100644 --- a/src/main/services/folder-linker.service.ts +++ b/src/main/services/folder-linker.service.ts @@ -3,10 +3,13 @@ import log from "electron-log"; import { deleteFolder, ensureFolderExist, moveFolderContent, pathExist, unlinkPath } from "../helpers/fs.helpers"; import { lstat, symlink } from "fs/promises"; import path from "path"; -import { copy, readlink } from "fs-extra"; +import { copy, mkdirSync, readlink, rmSync, symlinkSync, unlinkSync } from "fs-extra"; import { lastValueFrom } from "rxjs"; import { noop } from "shared/helpers/function.helpers"; import { StaticConfigurationService } from "./static-configuration.service"; +import { randomUUID } from "crypto"; +import { CustomError } from "shared/models/exceptions/custom-error.class"; +import { tryit } from "shared/helpers/error.helpers"; export class FolderLinkerService { private static instance: FolderLinkerService; @@ -41,6 +44,29 @@ export class FolderLinkerService { } } + public isLinkingSupported(): boolean { + const uuid = randomUUID(); + const installationPath = this.installLocationService.installationDirectory(); + const testFolder = path.join(installationPath, uuid); + const testLink = path.join(installationPath, `${uuid}_link`); + + const resLink = tryit(() => { + mkdirSync(testFolder); + symlinkSync(testFolder, testLink, this.getLinkingType()); + }); + + tryit(() => { + rmSync(testFolder, { force: true, recursive: true }); + unlinkSync(testLink); + }); + + if(resLink.error){ + log.error("Unable to create symlink", resLink.error); + } + + return !resLink.error; + } + public sharedFolder(): string { return this.installLocationService.sharedContentPath(); } @@ -74,6 +100,10 @@ export class FolderLinkerService { } public async linkFolder(folderPath: string, options?: LinkOptions): Promise { + if(!this.isLinkingSupported()){ + throw new CustomError("Linking is not supported on this platform", "LinkingNotSupported"); + } + const sharedPath = await this.getSharedFolder(folderPath, options?.intermediateFolder); if (await this.isFolderSymlink(folderPath)) { diff --git a/src/renderer/services/version-folder-linker.service.ts b/src/renderer/services/version-folder-linker.service.ts index 0b5a5c07..102a6754 100644 --- a/src/renderer/services/version-folder-linker.service.ts +++ b/src/renderer/services/version-folder-linker.service.ts @@ -21,7 +21,7 @@ export class VersionFolderLinkerService { return VersionFolderLinkerService.instance; } - private readonly KNOWN_ERROR_CODES = ["EPERM", "EACCES", "ENOSPC"]; + private readonly KNOWN_ERROR_CODES = ["EPERM", "EACCES", "ENOSPC", "LinkingNotSupported"]; private readonly ipcService: IpcService; private readonly progress: ProgressBarService;