1

Goal

We are using environment variables like %logonserver% and %userdomain% in our .NET application's configuration files, to support configuration freedom to application managers. When parsing the configuration file a call to Environment.ExpandEnvironmentVariables resolves the actual value.

Problem

However it seems it can not expand environment variables with substitutions like:

  • %logonserver:~2% (skips the first two characters)
  • %logonserver:\\=% (replaces the backslashes with an empty string)

When I call Environment.ExpandEnvironmentVariables("%logonserver:~2%") the method just returns the same string: %logonserver:~2%, instead of the expanded and substituted variable like a command line call would: echo %logonserver:~2%.

Questions

  1. Is there anything I'm doing wrong?
  2. What's an alternative to accomplish this goal in .net?

Thanks in advance.

Herman Cordes
  • 4,628
  • 9
  • 51
  • 87

2 Answers2

1
  1. You make nothing wrong. All the stuff after the colon : is a special feature of the command shell that won't be mimic by .Net or the Win32 API (simply check this code).

  2. There are two possibilities:

    • Take the string till the :, add a percent sign % and give this to ExpandEnvironmentVariables(). Then write your own parser to apply the needed actions after the colon : to be done on the returned string to mimic the behavior of the console.

    • Start a process with a hidden console window, take its output and input streams and send your environments variables with echo commands to it and let the parsing be done by the console.

Community
  • 1
  • 1
Oliver
  • 43,366
  • 8
  • 94
  • 151
1

You may be able to use something like this (your mileage may very depending on use case, but this works in certain scenarios):

private static string ExpandEnvironmentVariablesWithSubstitution(string value)
{
    string result = string.Empty;
    var process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = "cmd",
            Arguments = string.Concat("/c echo ", value),
            UseShellExecute = false,
            CreateNoWindow = true,
            RedirectStandardOutput = true
        }
    };
    process.OutputDataReceived += (s, e) => result = string.IsNullOrWhiteSpace(e.Data) ? result: e.Data;
    process.Start();
    process.BeginOutputReadLine();
    process.WaitForExit();
    process.CancelOutputRead();
    if (!process.HasExited)
        process.Kill();
    return result;
}
grenade
  • 31,451
  • 23
  • 97
  • 126