diff --git a/src/MaaWpfGui/Configuration/GUI.cs b/src/MaaWpfGui/Configuration/GUI.cs
index c284bd2d82..72b74526fb 100644
--- a/src/MaaWpfGui/Configuration/GUI.cs
+++ b/src/MaaWpfGui/Configuration/GUI.cs
@@ -51,6 +51,10 @@ namespace MaaWpfGui.Configuration
public string WindowTitlePrefix { get; set; } = string.Empty;
+ public string FoundBadModules { get; set; } = string.Empty;
+
+ public string SuppressedBadModules { get; set; } = string.Empty;
+
// ReSharper disable once UnusedMember.Global
public void OnPropertyChanged(string propertyName, object before, object after)
{
diff --git a/src/MaaWpfGui/Main/Bootstrapper.cs b/src/MaaWpfGui/Main/Bootstrapper.cs
index 503a07022d..01de401148 100644
--- a/src/MaaWpfGui/Main/Bootstrapper.cs
+++ b/src/MaaWpfGui/Main/Bootstrapper.cs
@@ -37,6 +37,7 @@ using MaaWpfGui.Services.Managers;
using MaaWpfGui.Services.RemoteControl;
using MaaWpfGui.Services.Web;
using MaaWpfGui.States;
+using MaaWpfGui.Utilities;
using MaaWpfGui.ViewModels.UI;
using MaaWpfGui.ViewModels.UserControl.Settings;
using MaaWpfGui.Views.UI;
@@ -237,6 +238,11 @@ namespace MaaWpfGui.Main
}
}
+ protected override void OnLaunch()
+ {
+ BadModules.CheckAndWarnBadInjectedModules();
+ }
+
private static bool HandleMultipleInstances()
{
// 设置互斥量的名称
diff --git a/src/MaaWpfGui/NativeMethods.txt b/src/MaaWpfGui/NativeMethods.txt
index 4f0c5c8778..07929c9816 100644
--- a/src/MaaWpfGui/NativeMethods.txt
+++ b/src/MaaWpfGui/NativeMethods.txt
@@ -24,3 +24,7 @@ TD_ERROR_ICON
TD_WARNING_ICON
TD_INFORMATION_ICON
SHGetStockIconInfo
+
+//BadInjectedDllChecker
+GetModuleHandle
+GetModuleFileName
diff --git a/src/MaaWpfGui/Res/Localizations/en-us.xaml b/src/MaaWpfGui/Res/Localizations/en-us.xaml
index 5bc646e4c4..b72eca1be0 100644
--- a/src/MaaWpfGui/Res/Localizations/en-us.xaml
+++ b/src/MaaWpfGui/Res/Localizations/en-us.xaml
@@ -1367,4 +1367,11 @@ If you want to run multiple MAA at the same time, please copy the whole MAA and
Immortal MAA truly immortal.
Clear any I.S. at N15 difficulty or above with MAA
+
+
+ Compatibility Warning
+ The following DLL(s) injected into MAA may crash MAA or corrupt MAA user interface:
+ If you encounter such issues with MAA, please try adding MAA to the exclusion list of the relevant software, or uninstall the related software and check if the problem persists.
+ Do not show this warning again
+
diff --git a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml
index 40c0c47cc3..b65a673202 100644
--- a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml
+++ b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml
@@ -1371,4 +1371,11 @@ C:\\leidian\\LDPlayer9。\n
仙术牛牛真仙术。
使用牛牛通关任意肉鸽 N15 以上难度
+
+
+ 悲报
+ 以下注入到 MAA 的 DLL 可能会导致 MAA 闪退或界面渲染异常:
+ 如果您注意到 MAA 存在相关问题,请尝试将 MAA 加入相关软件的排除名单,或卸载相关软件后检查问题是否仍然存在。
+ 不再显示此警告
+
diff --git a/src/MaaWpfGui/Utilities/BadModules.cs b/src/MaaWpfGui/Utilities/BadModules.cs
new file mode 100644
index 0000000000..7f5f0529f6
--- /dev/null
+++ b/src/MaaWpfGui/Utilities/BadModules.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using MaaWpfGui.Configuration;
+using MaaWpfGui.Helper;
+using Windows.Win32;
+
+namespace MaaWpfGui.Utilities
+{
+ internal class BadModules
+ {
+ private static string[] names = ["NahimicOSD.dll", "AudioDevProps2.dll"];
+
+ public static unsafe string[] GetBadInjectedModules()
+ {
+ var result = new List();
+ char[]? buffer = null;
+ foreach (var name in names)
+ {
+ var hmod = PInvoke.GetModuleHandle(name);
+ if (!hmod.IsInvalid)
+ {
+ buffer ??= new char[65536];
+ fixed (char* ptr = buffer)
+ {
+ if (PInvoke.GetModuleFileName(hmod, ptr, 65536) > 0)
+ {
+ result.Add(new string(ptr));
+ }
+ }
+ }
+ }
+
+ return result.ToArray();
+ }
+
+ private class WPFWin32Window : System.Windows.Forms.IWin32Window, System.Windows.Interop.IWin32Window
+ {
+ public IntPtr Handle => _helper.Handle;
+
+ private System.Windows.Interop.WindowInteropHelper _helper;
+
+ public WPFWin32Window(System.Windows.Window w)
+ {
+ _helper = new System.Windows.Interop.WindowInteropHelper(w);
+ }
+ }
+
+ public static void CheckAndWarnBadInjectedModules()
+ {
+ var allBadModules = GetBadInjectedModules();
+ var prevFound = ConfigFactory.Root.GUI.FoundBadModules.Split(";", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+ var suppressed = ConfigFactory.Root.GUI.SuppressedBadModules.Split(";", StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+ var newFoundBadModules = allBadModules.Where(x => !prevFound.Contains(x, StringComparer.InvariantCultureIgnoreCase)).ToArray();
+ var notSuppressedBadModules = allBadModules.Where(x => !suppressed.Contains(x, StringComparer.InvariantCultureIgnoreCase)).ToArray();
+ ConfigFactory.Root.GUI.FoundBadModules = string.Join(";", [.. prevFound, .. newFoundBadModules]);
+
+ if (notSuppressedBadModules.Length > 0)
+ {
+ var sb = new StringBuilder();
+ sb.AppendLine(LocalizationHelper.GetString("BadModules.Warning.Prolog"));
+ sb.AppendLine();
+ foreach (var module in allBadModules)
+ {
+ sb.AppendLine(module);
+ }
+
+ sb.AppendLine();
+
+ sb.Append(LocalizationHelper.GetString("BadModules.Warning.Epilog"));
+
+ var page = new TaskDialogPage
+ {
+ Caption = "MAA",
+ Heading = LocalizationHelper.GetString("BadModules.Warning.Heading"),
+ Text = sb.ToString(),
+ Icon = TaskDialogIcon.Warning,
+ Buttons = { TaskDialogButton.OK },
+ SizeToContent = true,
+ };
+
+ if (newFoundBadModules.Length == 0)
+ {
+ // only show the "Do not show again" checkbox on the second time
+ page.Verification = new()
+ {
+ Text = LocalizationHelper.GetString("BadModules.Warning.DoNotShowAgain"),
+ Checked = false,
+ };
+ }
+
+ TaskDialog.ShowDialog(new WPFWin32Window(System.Windows.Application.Current.MainWindow), page);
+
+ if (page.Verification?.Checked ?? false)
+ {
+ ConfigFactory.Root.GUI.SuppressedBadModules = string.Join(";", allBadModules);
+ }
+ }
+ }
+ }
+}