From b2145e822543faa3cac1fb67397160ceb9e9a00f Mon Sep 17 00:00:00 2001 From: Harry-hq Date: Tue, 24 Feb 2026 15:50:54 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Harry-hq --- PCL.Core/App/Config.cs | 1 + .../Modules/Minecraft/ModLaunch.vb | 20 +++++++++++++++++++ .../Pages/PageInstance/PageInstanceSetup.xaml | 16 +++++++++------ .../PageInstance/PageInstanceSetup.xaml.vb | 4 +++- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/PCL.Core/App/Config.cs b/PCL.Core/App/Config.cs index 493680fde..4ad074da4 100644 --- a/PCL.Core/App/Config.cs +++ b/PCL.Core/App/Config.cs @@ -626,5 +626,6 @@ partial class HideConfigGroup [ConfigItem("VersionModpackVersion", "", ConfigSource.GameInstance)] public partial ArgConfig ModpackVersion { get; } [ConfigItem("VersionModpackSource", "", ConfigSource.GameInstance)] public partial ArgConfig ModpackSource { get; } [ConfigItem("VersionModpackId", "", ConfigSource.GameInstance)] public partial ArgConfig ModpackId { get; } + [ConfigItem("VersionAdvanceEnv", "", ConfigSource.GameInstance)] public partial ArgConfig EnvVariables { get; } } } diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index 0af3d0920..c300581e5 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -2313,6 +2313,25 @@ NextInstance: End If End Sub + Private Sub _ApplyInstanceEnvVariables(startInfo As ProcessStartInfo, instance As McInstance) '自定义环境变量列表处理 + Try + Dim envRaw As String = Setup.Get("VersionAdvanceEnv", instance:=instance) + If String.IsNullOrWhiteSpace(envRaw) Then Return + + Dim parts As String() = envRaw.Split({" "c}, StringSplitOptions.RemoveEmptyEntries) + For Each part In parts + Dim eq As Integer = part.IndexOf("="c) + If eq > 0 Then + Dim k As String = part.Substring(0, eq) + Dim v As String = part.Substring(eq + 1) + ' 覆盖或新增环境变量 + startInfo.EnvironmentVariables(k) = v + End If + Next + Catch ex As Exception + Log(ex, "解析/注入自定义环境变量失败", LogLevel.Feedback) + End Try + End Sub Private Sub McLaunchRun(Loader As LoaderTask(Of Integer, Process)) Dim noJavaw As Boolean = Setup.Get("LaunchAdvanceNoJavaw") AndAlso McLaunchJavaSelected.Installation.JavawExePath IsNot Nothing @@ -2325,6 +2344,7 @@ NextInstance: Paths.Add(ShortenPath(McLaunchJavaSelected.Installation.JavaFolder)) StartInfo.EnvironmentVariables("Path") = Join(Paths.Distinct.ToList, ";") StartInfo.EnvironmentVariables("appdata") = ShortenPath(McFolderSelected) + _ApplyInstanceEnvVariables(StartInfo, McInstanceSelected) '设置其他参数 StartInfo.WorkingDirectory = ShortenPath(McInstanceSelected.PathIndie) diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml index ff31ce9b1..404dba552 100644 --- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml +++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml @@ -206,7 +206,8 @@ - + + @@ -227,14 +228,17 @@ - - + + + + + - - + - + Date: Wed, 25 Feb 2026 11:34:14 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Harry-hq --- Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index c300581e5..ee99ef8cc 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -2322,10 +2322,10 @@ NextInstance: For Each part In parts Dim eq As Integer = part.IndexOf("="c) If eq > 0 Then - Dim k As String = part.Substring(0, eq) - Dim v As String = part.Substring(eq + 1) + Dim tempK As String = part.Substring(0, eq) + Dim tempV As String = part.Substring(eq + 1) ' 覆盖或新增环境变量 - startInfo.EnvironmentVariables(k) = v + startInfo.EnvironmentVariables(tempK) = tempV End If Next Catch ex As Exception From 1a1b92780d60bda33cfc07c9ad80ef0df7282bde Mon Sep 17 00:00:00 2001 From: Harry-hq Date: Thu, 26 Feb 2026 22:32:38 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=B0=86=E5=8F=8C=E5=BC=95=E5=8F=B7?= =?UTF-8?q?=E9=87=8C=E7=9A=84=E7=A9=BA=E6=A0=BC=E8=A7=86=E4=B8=BA=E5=80=BC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E7=9A=84=E4=B8=80=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Harry-hq --- .../Modules/Minecraft/ModLaunch.vb | 29 ++++++++++++++++++- .../Pages/PageInstance/PageInstanceSetup.xaml | 2 +- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index ee99ef8cc..1a5a62c08 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -2318,7 +2318,34 @@ NextInstance: Dim envRaw As String = Setup.Get("VersionAdvanceEnv", instance:=instance) If String.IsNullOrWhiteSpace(envRaw) Then Return - Dim parts As String() = envRaw.Split({" "c}, StringSplitOptions.RemoveEmptyEntries) + + Dim parts As New List(Of String) + Dim current As New Text.StringBuilder() + Dim inQuotes As Boolean = False + Dim i As Integer = 0 + + While i < envRaw.Length + Dim c As Char = envRaw(i) + If c = """"c Then + inQuotes = Not inQuotes + ElseIf c = " "c AndAlso Not inQuotes Then + ' 环境变量值字符串结束判断 + If current.Length > 0 Then + parts.Add(current.ToString()) + current.Clear() + End If + Else + ' 其他字符处理 + current.Append(c) + End If + i += 1 + End While + + ' 添加最后一个环境变量 + If current.Length > 0 Then + parts.Add(current.ToString()) + End If + For Each part In parts Dim eq As Integer = part.IndexOf("="c) If eq > 0 Then diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml index 404dba552..07976a675 100644 --- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml +++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml @@ -207,7 +207,7 @@ - + From 280e5cfe6d0df3d1c1619d8668d9ece955f9cd4f Mon Sep 17 00:00:00 2001 From: Harry-hq Date: Fri, 27 Feb 2026 21:46:10 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Harry-hq --- .../Modules/Minecraft/ModLaunch.vb | 115 +++++++++++++----- .../Pages/PageInstance/PageInstanceSetup.xaml | 9 +- 2 files changed, 89 insertions(+), 35 deletions(-) diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index 1a5a62c08..535ed2354 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -2313,50 +2313,103 @@ NextInstance: End If End Sub - Private Sub _ApplyInstanceEnvVariables(startInfo As ProcessStartInfo, instance As McInstance) '自定义环境变量列表处理 + Private Sub _ApplyInstanceEnvVariables(startInfo As ProcessStartInfo, instance As McInstance) + ' 自定义环境变量列表处理(增强版:支持跨行值,值需用双引号包裹) Try Dim envRaw As String = Setup.Get("VersionAdvanceEnv", instance:=instance) If String.IsNullOrWhiteSpace(envRaw) Then Return - - Dim parts As New List(Of String) - Dim current As New Text.StringBuilder() - Dim inQuotes As Boolean = False Dim i As Integer = 0 - While i < envRaw.Length - Dim c As Char = envRaw(i) - If c = """"c Then - inQuotes = Not inQuotes - ElseIf c = " "c AndAlso Not inQuotes Then - ' 环境变量值字符串结束判断 - If current.Length > 0 Then - parts.Add(current.ToString()) - current.Clear() + ' 跳过空白字符(空格、制表符等,但不包括换行,因为换行作为分隔符由后续逻辑处理) + While i < envRaw.Length AndAlso Char.IsWhiteSpace(envRaw(i)) AndAlso envRaw(i) <> ControlChars.Cr AndAlso envRaw(i) <> ControlChars.Lf + i += 1 + End While + If i >= envRaw.Length Then Exit While + + ' 跳过注释行(以 # 开头) + If envRaw(i) = "#"c Then + While i < envRaw.Length AndAlso envRaw(i) <> ControlChars.Cr AndAlso envRaw(i) <> ControlChars.Lf + i += 1 + End While + ' 跳过换行符 + If i < envRaw.Length AndAlso envRaw(i) = ControlChars.Cr Then i += 1 + If i < envRaw.Length AndAlso envRaw(i) = ControlChars.Lf Then i += 1 + Continue While + End If + + ' 解析键名(直到遇到 = 或行尾) + Dim keyStart As Integer = i + While i < envRaw.Length AndAlso envRaw(i) <> "="c + i += 1 + End While + If i >= envRaw.Length Then Exit While ' 没有等号,终止 + Dim key As String = envRaw.Substring(keyStart, i - keyStart).Trim() + i += 1 ' 跳过 '=' + + ' 解析值(可能跨行,引号内保留所有字符) + Dim valueStart As Integer = i + Dim inQuotes As Boolean = False + While i < envRaw.Length + If envRaw(i) = """"c Then + inQuotes = Not inQuotes + ElseIf Not inQuotes AndAlso (envRaw(i) = ControlChars.Cr OrElse envRaw(i) = ControlChars.Lf) Then + ' 不在引号内遇到换行,值结束 + Exit While End If + i += 1 + End While + Dim value As String = envRaw.Substring(valueStart, i - valueStart) + + ' 去除值首尾的引号(如果存在),否则仅去除首尾空白 + If value.Length >= 2 AndAlso value(0) = """"c AndAlso value(value.Length - 1) = """"c Then + value = value.Substring(1, value.Length - 2) Else - ' 其他字符处理 - current.Append(c) + value = value.Trim() End If - i += 1 - End While - - ' 添加最后一个环境变量 - If current.Length > 0 Then - parts.Add(current.ToString()) - End If - For Each part In parts - Dim eq As Integer = part.IndexOf("="c) - If eq > 0 Then - Dim tempK As String = part.Substring(0, eq) - Dim tempV As String = part.Substring(eq + 1) - ' 覆盖或新增环境变量 - startInfo.EnvironmentVariables(tempK) = tempV + ' 键名合法性检查 + If String.IsNullOrEmpty(key) Then + Log($"环境变量键名为空,跳过", LogLevel.Debug) + McLaunchLog("环境变量键名为空,跳过") + ElseIf key.Contains(" "c) OrElse key.Contains("="c) Then + Log($"环境变量键名包含非法字符(空格或等号),跳过: {key}", LogLevel.Debug) + McLaunchLog($"环境变量键名包含非法字符(空格或等号),跳过: {key}") + Else + ' 追加 PATH + If key.Equals("PATH", StringComparison.OrdinalIgnoreCase) Then + Dim existingPath = startInfo.EnvironmentVariables("PATH") + If String.IsNullOrEmpty(existingPath) Then + startInfo.EnvironmentVariables("PATH") = value + Else + ' 确保分号分隔 + If existingPath.EndsWith(";") Then + startInfo.EnvironmentVariables("PATH") = existingPath & value + Else + startInfo.EnvironmentVariables("PATH") = existingPath & ";" & value + End If + End If + Log($"追加或覆盖环境变量 PATH: {value}", LogLevel.Debug) + McLaunchLog($"追加或覆盖环境变量 PATH: {value}") + Else + ' 覆盖或新增其他变量 + startInfo.EnvironmentVariables(key) = value + ' 值脱敏记录(防止敏感信息泄露) + Dim safeValue = If(value.Length > 20, value.Substring(0, 20) & "...", value) + Log($"设置环境变量 {key} = {safeValue}", LogLevel.Debug) + McLaunchLog($"已设置环境变量: {key} = {safeValue}") + End If End If - Next + + ' 跳过值后空白字符 + While i < envRaw.Length AndAlso (Char.IsWhiteSpace(envRaw(i)) OrElse envRaw(i) = ControlChars.Cr OrElse envRaw(i) = ControlChars.Lf) + i += 1 + End While + End While + Catch ex As Exception Log(ex, "解析/注入自定义环境变量失败", LogLevel.Feedback) + McLaunchLog("解析/注入自定义环境变量失败") End Try End Sub Private Sub McLaunchRun(Loader As LoaderTask(Of Integer, Process)) diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml index 07976a675..b73b6dd66 100644 --- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml +++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceSetup.xaml @@ -204,7 +204,7 @@ - + @@ -228,9 +228,10 @@ - - - + + +