1

I'm trying to run an application that reads an environment variable that contains a JSON with about 22k characters. The project setup tells me to use $(cat ./path/to/file) to correctly configure it, but as I'm using windows, this commands do not work.

I've tried copying the contents of the file to the variable using the GUI Environment Variable, but its input truncates the value to a certain limit which is not even on half of the file. After this I tried setting the variable using the Powershell with the command:

$env:myvar = iex '$(type path/to/file)'

and then saving the result with:

[System.Environment]::SetEnvironmentVariable('MYVAR', $env:MYVAR, [System.EnvironmentVariableTarget]::Machine)

After these commands, Powershell is able to print the result correctly but CMD still prints only part of the value when I echo it.

This is very odd because the regedit shows the correct value as suggested here.

The application still can't process the value because it is not complete.

Is there any fix for this?

  • 4
    "a[n] environment variable that contains a JSON with about 22k characters." is _never_ going to work on Windows (env var values must fit in <8192 bytes each and <32768 bytes in total per process) – Mathias R. Jessen Jan 12 '21 at 20:26
  • the total bytes in process might be the problem. But if each env var must be less than ~8k, how is regedit showing the correct full value? – Leonardo Meinerz Ramos Jan 12 '21 at 20:58
  • 2
    "application that reads an environment variable" - what application, and can it read this data in some other way than (ab)using an environment variable? – Bill_Stewart Jan 12 '21 at 21:37
  • Why dont you install Wsl(Windows Subsystem for Linux) and use linux commands – Justaus3r Jan 12 '21 at 21:57
  • @MathiasR.Jessen, these limits aren't quite correct as such - please see my answer. – mklement0 Jan 12 '21 at 23:39
  • As an aside: [`Invoke-Expression` should generally be avoided](https://blogs.msdn.microsoft.com/powershell/2011/06/03/invoke-expression-considered-harmful/); in your case, use `$env:myvar = Get-Content -Raw path/to/file` – mklement0 Jan 12 '21 at 23:41
  • @Bill_Stewart it is a web application using Spring Boot. I Guess it is not possible to configure this project on windows native shells like CMD and PowerShell. I managed to get the project running by executing it with Intellij and overriding the required environment variable within the IDE. – Leonardo Meinerz Ramos Jan 13 '21 at 13:55
  • @Bill_Stewart but no, I can't change the way the application reads the information because this is a huge project and would require many requests to the managers of the project :( – Leonardo Meinerz Ramos Jan 13 '21 at 13:58

2 Answers2

6

Note: This answer applies to Windows.

tl;dr

  • While you can store up to 32,766 characters in a single environment variable, the standard retrieval mechanisms in cmd.exe and PowerShell / .NET (as of v7.1 / 5.0) support only up to 4,095.

  • A workaround in PowerShell is possible, but ultimately it comes down to whether the target executable that is meant to read an environment-variable value supports reading values up to the technical maximum length.


  • The technical limit for the number of characters in a single environment variable is 32,766 (32KB = 32768, minus 2).

    • Starting with Windows Server 2008 / Windows Vista, there is no longer a limit on the overall size of the environment block - see the docs.
  • However, depending on how the environment-variable is retrieved, the limit may be lower:

    • Both cmd.exe and PowerShell, as of v7.1 / .NET 5.0, support retrieving at most 4,095 characters.

    • However, in PowerShell you can retrieve longer values, assuming the variable of interest is defined persistently in the registry, and assuming that you know whether it is defined at the machine or user level; e.g., for a MYVAR environment variable:

      • At the machine level:

         Get-ItemPropertyValue 'registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment' MYVAR 
        
      • At the user level:

         Get-ItemPropertyValue registry::HKEY_CURRENT_USER\Environment MYVAR
        
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

try the type command. It is the windows equivalent of the unix cat command. This means storing the json inside of a seperate file and using the command "type <path_to_file>".