为什么 Windows 对环境变量有限制?

为什么 Windows 对环境变量有限制?

1024 个字符限制的技术原因是什么

在过去 3 年使用 Linux 之后,很多 Windows 7 Pro 问题一直困扰着我的日常工作。最无聊的是文件名限制和环境变量忘记。我知道 MSDN 说组合系统 ENV 的限制是 1024,但为什么呢?我设置了一个很大的用户路径变量。它工作正常,除非我让它运行一段时间。然后它会突然停止识别 PATH 值,直到我重新启动。

Windows 如何存储会导致此强加限制的 ENV 值?该值如何通过正常使用而损坏?

微软 https://support.microsoft.com/en-us/kb/906469

更新 为了完整起见,我将描述我遇到上述问题的情况。我通常通过系统设置中的环境对话框设置用户环境路径。我在开发过程中运行的诸如 msbuild、vstest.console.exe、tf.exe 之类的东西。我几乎只在 ConEmu 中使用 PowerShell v4。几个小时或一天的正常运行时间后,这些命令会突然停止响应。重置或通过环境对话框或命令行更改值不会恢复功能。虽然回显 $env:PATH 将显示正确的值。重新启动是我发现的唯一解决方案。

答案1

1024 个字符限制的技术原因是什么

您提到的限制不是 1024 字节。正如您链接的文章中解释的那样,这是一个错误,有可用的修补程序。

文章明确指出限制为 2048 字节对于CreateEnvironmentBlock函数

此外,该漏洞仅存在于两个旧版本的 Windows(XP 和 Server 2003)中。

当应用程序调用 CreateEnvironmentBlock 函数来检索基于 Microsoft Windows Server 2003 或基于 Microsoft Windows XP 的计算机上的环境变量时,返回的路径环境变量将被截断为 1,024 字节。即使环境变量的最大大小为 2,048 字节,也会出现此行为。此问题导致应用程序无法获取正确的环境变量。

来源在基于 Windows Server 2003 或 Windows XP 的计算机上,返回的路径环境变量被截断为 1,024 个字节


那么限制是2048个字符吗?

实际限制为 32,760 个字符。但是,在实践中你不太可能达到这个理论上的最大值。

  • 由于环境变量需要适合批处理器的命令行缓冲区,因此批处理文件受到最大命令行长度的限制。

在运行 Microsoft Windows XP 或更高版本的计算机上,命令提示符中可使用的字符串的最大长度为 8191 个字符。

命令提示符会忽略从父进程继承的任何环境变量,并且这些变量的长度超过其自身的 8191 个字符的限制。

  • 设置环境注册表项在解析该注册表项并根据该注册表项构建环境块的代码中具有 2048 个字符的限制。

资料来源如下。


PATH这个值( )在正常使用过程中会如何被破坏?

正如后面所解释的,如果系统PATH修改为长度超过 1920 个字符,就会出现这种情况。

您在问题中没有提供足够的信息来准确诊断为什么会发生这种情况。


我有一个很大的用户PATH变量集

环境变量有一个特定的限制PATH

为了使用户PATH变量成功与系统PATH变量合并,系统PATH变量必须小于 1920 个字符。

发现在 Windows Server 2003 上,一旦系统 PATH 超过 1920 个字符,用户PATH环境变量就不再与其合并来设置进程PATH环境变量,即使整个系统PATH(即使更大)都将包含在进程PATH变量中。

来源echo %PATH% 是否仅扩展到系统变量还是也扩展到用户变量?回答大卫·赫弗南


文件路径有哪些限制?

最大路径长度限制

在 Windows API 中(以下段落中讨论的一些例外),路径的最大长度为 MAX_PATH,定义为 260 个字符。

  • 本地路径的结构如下:驱动器号、冒号、反斜杠、以反斜杠分隔的名称部分以及终止空字符。

  • 例如,驱动器 D 上的最大路径是,D:\some 256-character path string<NUL>其中<NUL>表示当前系统代码页的不可见终止空字符。(此处使用字符<>是为了视觉清晰,不能作为有效路径字符串的一部分。)

注意:Windows API 中的文件 I/O 函数在将名称转换为 NT 样式名称的过程中会将“/”转换为“”,但使用“\?”前缀时除外,如下节所述。

Windows API 有许多函数也有 Unicode 版本,以允许扩展长度的路径,最大总路径长度为 32,767 个字符。

  • 这种类型的路径由用反斜杠分隔的组件组成,每个组件的长度不超过 lpMaximumComponentLength函数参数中返回的值GetVolumeInformation (该值通常为 255 个字符)。要指定扩展长度的路径,请使用“\?”前缀。例如,“\?\D:\very long path”。

注意:最大路径长度 32,767 个字符是近似值,因为“\?”前缀可能会在运行时被系统扩展为更长的字符串,并且此扩展适用于总长度。

来源命名文件、路径和命名空间


环境变量的最大长度是多少?

环境变量的理论最大长度约为 32,760 个字符。然而,在实践中你不太可能达到这个理论最大值。

  • 所有环境变量必须位于单个环境块中,该环境块本身的限制为 32767 个字符。

  • 但是该计数是所有环境变量名称和值的总和,因此,如果您删除所有环境变量,然后设置一个名为 X 的变量,并使用 32,760 个字符这个非常大的值,那么我猜,您可能会达到理论上的最大长度。

  • 当然,在实践中,您必须与块中的所有其他变量共享环境块,因此 SetEnvironmentVariable使用 32,760 个字符的字符串的随机调用不太可能成功。

但这不是你唯一的实际限制。

  • 这还取决于您如何设置变量;即环境变量设置技术在调用之前经过的代码SetEnvironmentVariable

  • 如果您使用批处理文件,那么您将受到最大命令行长度的限制,因为环境变量需要适合批处理器的命令行缓冲区。

  • 另一方面,也许您正在设置环境注册表项,在这种情况下,您会在解析该注册表项并根据它构建环境块的代码中遇到 2048 个字符的限制。

  • 在以交互方式设置环境变量的对话框中也有一个限制,我碰巧不知道它的数值。

来源环境变量的最大长度是多少?作者为 Raymond Chen(微软员工)。


命令提示符 ( Cmd.exe) 命令行字符串限制

在运行 Microsoft Windows XP 或更高版本的计算机上,命令提示符下可使用的字符串的最大长度为 8191 个字符。在运行 Microsoft Windows 2000 或 Windows NT 4.0 的计算机上,命令提示符下可使用的字符串的最大长度为 2047 个字符。

此限制适用于命令行、其他进程继承的单个环境变量(例如 PATH 变量)以及所有环境变量扩展。如果您使用命令提示符运行批处理文件,则此限制也适用于批处理文件处理。

例子

以下列表为您提供了一些示例,说明此限制如何应用于您在命令提示符中运行的命令和在批处理文件中使用的命令。

  • 在命令提示符中,您在命令提示符中使用的以下命令行的总长度不能超过 2047 个或 8191 个字符(根据您的操作系统):

      cmd.exe /k ExecutableFile.exe parameter1, parameter2 ... parameterN
    
  • 在批处理文件中,您在批处理文件中使用的以下命令行的总长度不能超过 2047 个字符或 8191 个字符(根据您的操作系统):

      cmd.exe /k ExecutableFile.exe parameter1, parameter2 ... parameterN
    

当您使用命令提示符运行批处理文件时,此限制适用于批处理文件中包含的命令行。

  • 在命令提示符中,展开环境变量 2 和环境变量 3 后,环境变量 1 的总长度不能超过 2047 个字符或 8191 个字符(根据您的操作系统):

      c:> set EnvironmentVariable1=EnvironmentVariable2EnvironmentVariable3
    
  • 在批处理文件中,在命令行中扩展环境变量后,以下命令行的总长度不能超过 2047 个字符或 8191 个字符(根据您的操作系统而定):

      ExecutableFile.exe parameter1 parameter2
    
  • 尽管 Win32 对环境变量的限制是 32,767 个字符,但命令提示符会忽略从父进程继承的任何环境变量,并且这些变量的长度超过其自身的 2047 或 8191 个字符的限制(具体取决于操作系统)。请参阅SetEnvironmentVariable 函数

来源命令提示符 (Cmd.exe) 命令行字符串限制

相关内容