diff --git a/.gitignore b/.gitignore index 1902cebe8..bc4045800 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # Binaries for programs and plugins *.exe +!app/elevator/elevator-*.exe *.dll *.so *.dylib diff --git a/app/appearance/langs/ar_SA.json b/app/appearance/langs/ar_SA.json index be87a7a15..314145364 100644 --- a/app/appearance/langs/ar_SA.json +++ b/app/appearance/langs/ar_SA.json @@ -1578,6 +1578,7 @@ "248": "العنوان المستهدف يقع في كتلة الحاوية ولا يمكن استخدامه كنقطة إسقاط", "249": "تعذر الوصول إلى البيانات بسبب خطأ في الإعدادات. الرجاء التحقق من الإعدادات وأذونات التخزين السحابية", "250": "تم تحديد معدل الطلب بواسطة التخزين السحابي. الرجاء التحقق من الإعدادات وأذونات التخزين السحابية", - "251": "‫مجموع الأصول غير المستخدمة [%d]، [%d] فقط منها مدرج هنا‬" + "251": "‫مجموع الأصول غير المستخدمة [%d]، [%d] فقط منها مدرج هنا‬", + "252": "\uD83D\uDEA8 قد يقوم Microsoft Defender بحذف النواة عن طريق الخطأ، وحذف البيانات وتقليل الأداء بشكل كبير. يوصى بإضافة مسار التثبيت ومسار مساحة العمل الخاصة بـ SiYuan إلى قائمة الاستثناءات " } } \ No newline at end of file diff --git a/app/appearance/langs/de_DE.json b/app/appearance/langs/de_DE.json index 3b060228d..aa7d3fb3e 100644 --- a/app/appearance/langs/de_DE.json +++ b/app/appearance/langs/de_DE.json @@ -1578,6 +1578,7 @@ "248": "Die Zielfüberschrift befindet sich im Containerblock und kann nicht als Ablagepunkt verwendet werden.", "249": "Aufgrund eines Konfigurationsfehlers kann nicht auf die Daten zugegriffen werden. Bitte überprüfen Sie die Einstellungen und die Berechtigungen für den Cloud-Speicher", "250": "Die Anfrage wurde vom Cloud-Speicher begrenzt. Bitte überprüfen Sie die Einstellungen und die Berechtigungen für den Cloud-Speicher", - "251": "Insgesamt ungenutzte Assets [%d], hier nur [%d] aufgeführt" + "251": "Insgesamt ungenutzte Assets [%d], hier nur [%d] aufgeführt", + "252": "\uD83D\uDEA8 Microsoft Defender könnte fälschlicherweise den Kernel löschen, Daten löschen und die Leistung erheblich verringern. Es wird empfohlen, den Installationspfad und den Arbeitsbereich von SiYuan zur Ausschlussliste hinzuzufügen " } } diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json index 891d9c726..3de970008 100644 --- a/app/appearance/langs/en_US.json +++ b/app/appearance/langs/en_US.json @@ -1578,6 +1578,7 @@ "248": "The target heading is located in the container block and cannot be used as a drop point", "249": "Unable to access data due to configuration error. Please check the settings and cloud storage permissions", "250": "Request has been rate-limited by cloud storage. Please check the settings and cloud storage permissions", - "251": "Total unused assets [%d], only [%d] listed here" + "251": "Total unused assets [%d], only [%d] listed here", + "252": "\uD83D\uDEA8 Microsoft Defender may mistakenly delete the kernel, delete data, and significantly reduce performance. It is recommended to add the SiYuan installation path and workspace path to the exclusion list " } } diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json index 3da7ce6e2..d167ff408 100644 --- a/app/appearance/langs/es_ES.json +++ b/app/appearance/langs/es_ES.json @@ -1578,6 +1578,7 @@ "248": "El rumbo de destino está ubicado en el bloque contenedor y no puede usarse como punto de entrega", "249": "No se puede acceder a los datos debido a un error de configuración. Por favor, verifique las configuraciones y permisos de almacenamiento en la nube", "250": "La solicitud ha sido limitada por el almacenamiento en la nube. Por favor, verifique las configuraciones y permisos de almacenamiento en la nube", - "251": "Total de activos no utilizados [%d], solo [%d] listados aquí" + "251": "Total de activos no utilizados [%d], solo [%d] listados aquí", + "252": "\uD83D\uDEA8 Microsoft Defender puede eliminar por error el núcleo, eliminar datos y reducir significativamente el rendimiento. Se recomienda agregar la ruta de instalación y el espacio de trabajo de SiYuan a la lista de exclusiones " } } diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json index 452cb8b07..9260a99da 100644 --- a/app/appearance/langs/fr_FR.json +++ b/app/appearance/langs/fr_FR.json @@ -1578,6 +1578,7 @@ "248": "Le cap cible est situé dans le bloc conteneur et ne peut pas être utilisé comme point de dépôt", "249": "Impossible d'accéder aux données en raison d'une erreur de configuration. Veuillez vérifier les paramètres et les autorisations de stockage cloud", "250": "La demande a été limitée par le stockage cloud. Veuillez vérifier les paramètres et les autorisations de stockage cloud", - "251": "Total des actifs inutilisés [%d], seulement [%d] listés ici" + "251": "Total des actifs inutilisés [%d], seulement [%d] listés ici", + "252": "\uD83D\uDEA8 Microsoft Defender peut supprimer par erreur le noyau, supprimer des données et réduire considérablement les performances. Il est recommandé d'ajouter le chemin d'installation et l'espace de travail de SiYuan à la liste des exclusions " } } diff --git a/app/appearance/langs/he_IL.json b/app/appearance/langs/he_IL.json index 1b9dde164..faaa866cd 100644 --- a/app/appearance/langs/he_IL.json +++ b/app/appearance/langs/he_IL.json @@ -1578,6 +1578,7 @@ "248": "הכותרת היעד ממוקמת בבלוק המיכל ואינה יכולה לשמש כנקודת זרימה", "249": "אין אפשרות לגשת לנתונים עקב שגיאת תצורה. אנא בדוק את ההגדרות והרשאות האחסון בענן", "250": "הבקשה הוגבלה על ידי אחסון הענן. אנא בדוק את ההגדרות והרשאות האחסון בענן", - "251": "סך כל הנכסים שלא נעשה בהם שימוש [%d], רק [%d] מופיעים כאן" + "251": "סך כל הנכסים שלא נעשה בהם שימוש [%d], רק [%d] מופיעים כאן", + "252": "\uD83D\uDEA8 Microsoft Defender עלול למחוק בטעות את הליבה, למחוק נתונים ולהפחית משמעותית את הביצועים. מומלץ להוסיף את נתיב ההתקנה ונתיב סביבת העבודה של SiYuan לרשימת החריגים " } } diff --git a/app/appearance/langs/it_IT.json b/app/appearance/langs/it_IT.json index 67fb9e2c0..26b031a6b 100644 --- a/app/appearance/langs/it_IT.json +++ b/app/appearance/langs/it_IT.json @@ -1578,6 +1578,7 @@ "248": "L'intestazione di destinazione si trova nel blocco contenitore e non può essere utilizzata come punto di rilascio", "249": "Impossibile accedere ai dati a causa di un errore di configurazione. Si prega di controllare attentamente le impostazioni e le autorizzazioni di archiviazione cloud", "250": "La richiesta è stata limitata dall'archiviazione cloud. Si prega di controllare attentamente le impostazioni e le autorizzazioni di archiviazione cloud", - "251": "Totale risorse inutilizzate [%d], qui elencate solo [%d]" + "251": "Totale risorse inutilizzate [%d], qui elencate solo [%d]", + "252": "\uD83D\uDEA8 Microsoft Defender potrebbe eliminare erroneamente il kernel, eliminare i dati e ridurre significativamente le prestazioni. Si consiglia di aggiungere il percorso di installazione e lo spazio di lavoro di SiYuan all'elenco delle esclusioni " } } diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json index d28aeb5de..44856dc22 100644 --- a/app/appearance/langs/ja_JP.json +++ b/app/appearance/langs/ja_JP.json @@ -1578,6 +1578,7 @@ "248": "目標の見出しがコンテナブロック内にあるためドロップできません", "249": "設定エラーのためデータにアクセスできません。設定を一つずつ確認し、クラウドストレージの権限を確認してください", "250": "リクエストがクラウドストレージによって制限されました。設定を一つずつ確認し、クラウドストレージの権限を確認してください", - "251": "未使用のアセットの合計 [%d]、ここにリストされているのは [%d] のみ" + "251": "未使用のアセットの合計 [%d]、ここにリストされているのは [%d] のみ", + "252": "\uD83D\uDEA8 Microsoft Defender はカーネルを誤って削除したり、データを削除したり、パフォーマンスを大幅に低下させ��可能性があります。SiYuan のインストールパスとワークスペースパスを除外リストに追加することをお勧めします " } } diff --git a/app/appearance/langs/pl_PL.json b/app/appearance/langs/pl_PL.json index a4d3b2a3a..6ce6e45e9 100644 --- a/app/appearance/langs/pl_PL.json +++ b/app/appearance/langs/pl_PL.json @@ -1578,6 +1578,7 @@ "248": "Docelowy nagłówek znajduje się w bloku kontenera i nie może być użyty jako punkt upuszczenia", "249": "Z powodu błędu konfiguracji nie można uzyskać dostępu do danych. Proszę dokładnie sprawdzić ustawienia i uprawnienia do przechowywania w chmurze", "250": "Żądanie zostało ograniczone przez przechowywanie w chmurze. Proszę dokładnie sprawdzić ustawienia i uprawnienia do przechowywania w chmurze", - "251": "Łączna liczba nieużywanych zasobów [%d], tutaj wymieniono tylko [%d]" + "251": "Łączna liczba nieużywanych zasobów [%d], tutaj wymieniono tylko [%d]", + "252": "\uD83D\uDEA8 Microsoft Defender może błędnie usunąć jądro, usunąć dane i znacznie obniżyć wydajność, zaleca się dodanie ścieżki instalacji i przestrzeni roboczej SiYuan do listy wykluczeń " } } diff --git a/app/appearance/langs/ru_RU.json b/app/appearance/langs/ru_RU.json index 0a74859de..e9d6a67a9 100644 --- a/app/appearance/langs/ru_RU.json +++ b/app/appearance/langs/ru_RU.json @@ -1578,6 +1578,7 @@ "248": "Целевой заголовок находится в контейнерном блоке и не может использоваться как пункт сброса", "249": "Из-за ошибки конфигурации невозможно получить доступ к данным. Пожалуйста, проверьте настройки и права доступа к облачному хранилищу", "250": "Запрос был ограничен облачным хранилищем. Пожалуйста, проверьте настройки и права доступа к облачному хранилищу", - "251": "Всего неиспользованных активов [%d], здесь перечислены только [%d]" + "251": "Всего неиспользованных активов [%d], здесь перечислены только [%d]", + "252": "\uD83D\uDEA8 Microsoft Defender может ошибочно удалить ядро, удалить данные и значительно снизить производительность, рекомендуется добавить путь установки и рабочее пространство SiYuan в список исключений " } } diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json index 76f98f90a..b0ab3776e 100644 --- a/app/appearance/langs/zh_CHT.json +++ b/app/appearance/langs/zh_CHT.json @@ -1483,7 +1483,7 @@ "153": "下載文件數 %d 下載分塊數 %d 接收位元組數 %s", "154": "雲端最多只能支持備份 12 個快照", "155": "雲端同步目錄已經重置為 [main]", - "156": "訪問鑑權失敗,請 或者重新打開", + "156": "訪問鑑權失敗,請或者重新打開", "157": "無法識別密鑰,請確認複製的密鑰字串是否正確", "158": "正在索引資料倉庫,遍歷資料 %s", "159": "正在索引資料倉庫,獲取最新文件 %v/%v", @@ -1578,6 +1578,7 @@ "248": "目標標題位於容器塊中,無法作為放置點", "249": "因配置錯誤導致無法存取數據,請仔細逐個核對配置項,並檢查雲端存儲相關權限配置", "250": "請求已被雲端存儲限流,請仔細逐個核對配置項,並檢查雲端存儲相關權限配置", - "251": "未引用資源一共 ${x} 個,這裡僅列出 ${y} 個" + "251": "未引用資源一共 ${x} 個,這裡僅列出 ${y} 個", + "252": "\uD83D\uDEA8 Microsoft Defender 可能會誤殺內核、誤刪數據和嚴重降低運行性能,建議將思源安裝路徑和工作空間路徑添加到排除列表 " } } diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json index 3e6223ccd..11fa29721 100644 --- a/app/appearance/langs/zh_CN.json +++ b/app/appearance/langs/zh_CN.json @@ -1483,7 +1483,7 @@ "153": "下载文件数 %d 下载分块数 %d 接收字节数 %s", "154": "云端最多只能支持备份 12 个快照", "155": "云端同步目录已经重置为 [main]", - "156": "访问鉴权失败,请 或者重新打开", + "156": "访问鉴权失败,请或者重新打开", "157": "无法识别密钥,请确认复制的密钥字符串是否正确", "158": "正在索引数据仓库,遍历数据 %s", "159": "正在索引数据仓库,获取最新文件 %v/%v", @@ -1578,6 +1578,7 @@ "248": "目标标题位于容器块中,无法作为放置点", "249": "因配置错误导致无法存取数据,请仔细逐个核对配置项,并检查云端存储相关权限配置", "250": "请求已被云端存储限流,请仔细逐个核对配置项,并检查云端存储相关权限配置", - "251": "未引用资源一共 [%d] 个,这里仅列出 [%d] 个" + "251": "未引用资源一共 [%d] 个,这里仅列出 [%d] 个", + "252": "\uD83D\uDEA8 Microsoft Defender 可能会误杀内核、误删数据和严重降低运行性能,建议将思源安装路径和工作空间路径添加到排除列表 " } } diff --git a/app/electron-builder-arm64.yml b/app/electron-builder-arm64.yml index 9136b2e13..daa827005 100644 --- a/app/electron-builder-arm64.yml +++ b/app/electron-builder-arm64.yml @@ -69,4 +69,6 @@ extraResources: filter: "!**/{.DS_Store,custom.css}" - from: "src/assets/fonts" to: "appearance/fonts" - filter: "!**/{.DS_Store}" \ No newline at end of file + filter: "!**/{.DS_Store}" + - from: "elevator/elevator-arm64.exe" + to: "elevator.exe" \ No newline at end of file diff --git a/app/electron-builder.yml b/app/electron-builder.yml index 7ba8628c2..76e1e3779 100644 --- a/app/electron-builder.yml +++ b/app/electron-builder.yml @@ -71,3 +71,5 @@ extraResources: filter: "!**/{.DS_Store}" - from: "pandoc/pandoc-windows-amd64.zip" to: "pandoc.zip" + - from: "elevator/elevator-amd64.exe" + to: "elevator.exe" diff --git a/app/elevator/README b/app/elevator/README new file mode 100644 index 000000000..8cd81b99d --- /dev/null +++ b/app/elevator/README @@ -0,0 +1 @@ +https://github.com/siyuan-note/elevator diff --git a/app/elevator/elevator-amd64.exe b/app/elevator/elevator-amd64.exe new file mode 100644 index 000000000..53668dd3a Binary files /dev/null and b/app/elevator/elevator-amd64.exe differ diff --git a/app/elevator/elevator-arm64.exe b/app/elevator/elevator-arm64.exe new file mode 100644 index 000000000..0e68afacb Binary files /dev/null and b/app/elevator/elevator-arm64.exe differ diff --git a/app/src/protyle/export/index.ts b/app/src/protyle/export/index.ts index 9dfa5de83..bd1083bcf 100644 --- a/app/src/protyle/export/index.ts +++ b/app/src/protyle/export/index.ts @@ -421,7 +421,7 @@ const renderPDF = async (id: string) => { alert(response.msg) return; } - document.title = '${window.siyuan.languages.export} PDF - ' + response.data.name + document.title = response.data.name window.siyuan = { config: { appearance: { mode: 0, codeBlockThemeDark: "${window.siyuan.config.appearance.codeBlockThemeDark}", codeBlockThemeLight: "${window.siyuan.config.appearance.codeBlockThemeLight}" }, diff --git a/kernel/api/router.go b/kernel/api/router.go index c53b672b0..60e943104 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -66,6 +66,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/system/importConf", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, importConf) ginServer.Handle("POST", "/api/system/getWorkspaceInfo", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, getWorkspaceInfo) ginServer.Handle("POST", "/api/system/reloadUI", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, reloadUI) + ginServer.Handle("POST", "/api/system/addMicrosoftDefenderExclusion", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, addMicrosoftDefenderExclusion) ginServer.Handle("POST", "/api/storage/setLocalStorage", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, setLocalStorage) ginServer.Handle("POST", "/api/storage/getLocalStorage", model.CheckAuth, getLocalStorage) diff --git a/kernel/api/system.go b/kernel/api/system.go index 7e91170e6..b0b5c4376 100644 --- a/kernel/api/system.go +++ b/kernel/api/system.go @@ -35,6 +35,21 @@ import ( "github.com/siyuan-note/siyuan/kernel/util" ) +func addMicrosoftDefenderExclusion(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + if !gulu.OS.IsWindows() { + return + } + + err := model.AddMicrosoftDefenderExclusion() + if nil != err { + ret.Code = -1 + ret.Msg = err.Error() + } +} + func reloadUI(c *gin.Context) { ret := gulu.Ret.NewResult() defer c.JSON(http.StatusOK, ret) diff --git a/kernel/conf/system.go b/kernel/conf/system.go index 5293eba24..52c910688 100644 --- a/kernel/conf/system.go +++ b/kernel/conf/system.go @@ -45,6 +45,8 @@ type System struct { LockScreenMode int `json:"lockScreenMode"` // 0:手动,1:手动+跟随系统 https://github.com/siyuan-note/siyuan/issues/9087 DisabledFeatures []string `json:"disabledFeatures"` + + MicrosoftDefenderExcluded bool `json:"microsoftDefenderExcluded"` // 是否已加入 Microsoft Defender 排除项 https://github.com/siyuan-note/siyuan/issues/13650 } func NewSystem() *System { diff --git a/kernel/job/cron.go b/kernel/job/cron.go index 511933f4f..03c979934 100644 --- a/kernel/job/cron.go +++ b/kernel/job/cron.go @@ -43,6 +43,7 @@ func StartCron() { go every(30*time.Second, model.FlushAssetsTextsJob) go every(30*time.Second, model.HookDesktopUIProcJob) go every(24*time.Hour, model.AutoPurgeRepoJob) + go every(30*time.Minute, model.AutoProcessMicrosoftDefender) } func every(interval time.Duration, f func()) { diff --git a/kernel/model/elevator.go b/kernel/model/elevator.go new file mode 100644 index 000000000..054cf8d5e --- /dev/null +++ b/kernel/model/elevator.go @@ -0,0 +1,22 @@ +// SiYuan - Refactor your thinking +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +//go:build !windows + +package model + +func AutoProcessMicrosoftDefender() { +} diff --git a/kernel/model/elevator_windows.go b/kernel/model/elevator_windows.go new file mode 100644 index 000000000..8710b896a --- /dev/null +++ b/kernel/model/elevator_windows.go @@ -0,0 +1,128 @@ +// SiYuan - Refactor your thinking +// Copyright (c) 2020-present, b3log.org +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +//go:build windows + +package model + +import ( + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "syscall" + + "github.com/88250/gulu" + "github.com/siyuan-note/logging" + "github.com/siyuan-note/siyuan/kernel/util" + "golang.org/x/sys/windows" +) + +func AddMicrosoftDefenderExclusion() (err error) { + if !gulu.OS.IsWindows() { + return + } + + if !isUsingMicrosoftDefender() { + return + } + + installPath := filepath.Dir(util.WorkingDir) + psArgs := []string{"-Command", "Add-MpPreference", "-ExclusionPath", installPath, ",", util.WorkspaceDir} + if isAdmin() { + cmd := exec.Command("powershell", psArgs...) + gulu.CmdAttr(cmd) + output, cmdErr := cmd.CombinedOutput() + if nil != cmdErr { + logging.LogErrorf("add Windows Defender exclusion path [%s] failed: %s, %s", installPath, cmdErr, string(output)) + err = cmdErr + return + } + } else { + elevator := filepath.Join(util.WorkingDir, "elevator.exe") + if "dev" == util.Mode || !gulu.File.IsExist(elevator) { + elevator = filepath.Join(util.WorkingDir, "elevator", "elevator-"+runtime.GOARCH+".exe") + } + + if !gulu.File.IsExist(elevator) { + msg := fmt.Sprintf("not found elevator [%s]", elevator) + logging.LogWarnf(msg) + err = errors.New(msg) + return + } + + ps := []string{"powershell"} + ps = append(ps, psArgs...) + verbPtr, _ := syscall.UTF16PtrFromString("runas") + exePtr, _ := syscall.UTF16PtrFromString(elevator) + cwdPtr, _ := syscall.UTF16PtrFromString(util.WorkingDir) + argPtr, _ := syscall.UTF16PtrFromString(strings.Join(ps, " ")) + execErr := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, 1) + if execErr != nil { + logging.LogErrorf("add Windows Defender exclusion path [%s] failed: %s", installPath, execErr) + err = execErr + return + } + } + + util.PushClearAllMsg() + util.PushMsg(Conf.language(102), 5000) + return +} + +func AutoProcessMicrosoftDefender() { + checkMicrosoftDefender() +} + +func checkMicrosoftDefender() { + if !gulu.OS.IsWindows() || Conf.System.MicrosoftDefenderExcluded { + return + } + + elevator := filepath.Join(util.WorkingDir, "elevator.exe") + if "dev" == util.Mode || !gulu.File.IsExist(elevator) { + elevator = filepath.Join(util.WorkingDir, "elevator", "elevator-"+runtime.GOARCH+".exe") + } + + if !gulu.File.IsExist(elevator) { + logging.LogWarnf("not found elevator [%s]", elevator) + return + } + + if !isUsingMicrosoftDefender() { + return + } + + util.PushMsg(Conf.language(252), 0) +} + +func isUsingMicrosoftDefender() bool { + if !gulu.OS.IsWindows() { + return false + } + + cmd := exec.Command("powershell", "-Command", "Get-MpPreference") + gulu.CmdAttr(cmd) + return cmd.Run() == nil +} + +func isAdmin() bool { + _, err := os.Open("\\\\.\\PHYSICALDRIVE0") + return err == nil +}