public static CaselessDictionary.CaselessDictionary<string> HarvestEnvVarsFromBatchFile(string BatchFileName, string BatchFileParameters, EPathOverride PathOverride)
		{
			if (!File.Exists(BatchFileName))
			{
				throw new Exception(string.Format("Tools.DotNETCommon.HarvestEnvVars.HarvestEnvVars.HarvestEnvVarsFromBatchFile: BatchFile {0} does not exist!", BatchFileName));
			}

			// Create a wrapper batch file that echoes environment variables to a text file
			string EnvOutputFileName      = Path.GetTempFileName();
			string EnvReaderBatchFileName = EnvOutputFileName + ".bat";
			try
			{
				var EnvVarsToXMLExePath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "EnvVarsToXML.exe");

				// Convert every path to short filenames to ensure we don't accidentally write out a non-ASCII batch file
				var ShortBatchFileName       = FileSystem.FileSystem.GetShortPathName(BatchFileName);
				var ShortEnvOutputFileName   = FileSystem.FileSystem.GetShortPathName(EnvOutputFileName);
				var ShortEnvVarsToXMLExePath = FileSystem.FileSystem.GetShortPathName(EnvVarsToXMLExePath);

				var EnvReaderBatchFileContent = new StringBuilder();

				// Run 'vcvars32.bat' (or similar x64 version) to set environment variables
				EnvReaderBatchFileContent.AppendFormat("call \"{0}\" {1}", ShortBatchFileName, BatchFileParameters).AppendLine();

				// Pipe all environment variables to a file where we can read them in.
				// We use a separate executable which runs after the batch file because we want to capture
				// the environment after it has been set, and there's no easy way of doing this, and parsing
				// the output of the set command is problematic when the vars contain non-ASCII characters.
				EnvReaderBatchFileContent.AppendFormat("\"{0}\" \"{1}\"", ShortEnvVarsToXMLExePath, ShortEnvOutputFileName).AppendLine();

				FileInfo TempFileInfo = new FileInfo(EnvReaderBatchFileName);
				if (TempFileInfo.Exists)
				{
					TempFileInfo.IsReadOnly = false;
					TempFileInfo.Delete();
					TempFileInfo.Refresh();
				}

				Directory.CreateDirectory(Path.GetDirectoryName(EnvReaderBatchFileName));
				File.WriteAllText(EnvReaderBatchFileName, EnvReaderBatchFileContent.ToString());
			}
			catch (Exception Ex)
			{
				throw new Exception(string.Format("Failed to create temporary batch file {0} to harvest environment variables (\"{1}\")", EnvReaderBatchFileName, Ex.Message), Ex);
			}

			// process needs to be disposed when done
			using (var BatchFileProcess = new Process())
			{
				// Run the batch file using cmd.exe with the /U option, to force Unicode output. Many locales have non-ANSI characters in system paths.
				var StartInfo = BatchFileProcess.StartInfo;
				StartInfo.FileName        = Path.Combine(Environment.SystemDirectory, "cmd.exe");
				StartInfo.Arguments       = String.Format("/U /C \"{0}\"", EnvReaderBatchFileName);
				StartInfo.CreateNoWindow  = true;
				StartInfo.UseShellExecute = false;

				// Override path variable if it can be particularly long
				if (PathOverride == EPathOverride.User)
				{
					string NewPathVariable = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine) ?? "";
					if (String.IsNullOrEmpty(NewPathVariable))
					{
						NewPathVariable = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User);
					}
					else
					{
						NewPathVariable += ";" + Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User);
					}
					StartInfo.EnvironmentVariables["PATH"] = NewPathVariable;
				}

				// Try to launch the process, and produce a friendly error message if it fails.
				try
				{
					// Start the process up and then wait for it to finish
					BatchFileProcess.Start();
					BatchFileProcess.WaitForExit();
				}
				catch (Exception Ex)
				{
					throw new Exception(string.Format("Failed to start local process for action (\"{0}\"): {1} {2}", Ex.Message, StartInfo.FileName, StartInfo.Arguments), Ex);
				}
			}

			// Accept chars which are technically not valid XML - they were written out by XmlSerializer anyway!
			var Settings = new XmlReaderSettings();
			Settings.CheckCharacters  = false;

			List<Tools.DotNETCommonPrivate.HarvestEnvVars.EnvVar> EnvVars;
			try
			{
				using (var Stream = new StreamReader(EnvOutputFileName))
				using (var Reader = XmlReader.Create(Stream, Settings))
				{
					EnvVars = (List<Tools.DotNETCommonPrivate.HarvestEnvVars.EnvVar>)EnvVarListSerializer.Deserialize(Reader);
				}
			}
			catch (Exception Ex)
			{
				throw new Exception(string.Format("Failed to read environment variables from XML file: {0}", EnvOutputFileName), Ex);
			}

			// Clean up the temporary files we created earlier on, so the temp directory doesn't fill up
			// with these guys over time
			try
			{
				File.Delete(EnvOutputFileName);
			}
			catch (Exception)
			{
				// Unable to delete the temporary file.  Not a big deal.
			}

			try
			{
				File.Delete(EnvReaderBatchFileName);
			}
			catch (Exception)
			{
				// Unable to delete the temporary file.  Not a big deal.
			}

			var Result = new CaselessDictionary.CaselessDictionary<string>();
			foreach (var Var in EnvVars)
			{
				Result.Add(Var.Key, Var.Value);
			}

			return Result;
		}
        public static CaselessDictionary.CaselessDictionary <string> HarvestEnvVarsFromBatchFile(string BatchFileName, string BatchFileParameters, EPathOverride PathOverride)
        {
            if (!File.Exists(BatchFileName))
            {
                throw new Exception(string.Format("Tools.DotNETCommon.HarvestEnvVars.HarvestEnvVars.HarvestEnvVarsFromBatchFile: BatchFile {0} does not exist!", BatchFileName));
            }

            // Create a wrapper batch file that echoes environment variables to a text file
            string EnvOutputFileName      = Path.GetTempFileName();
            string EnvReaderBatchFileName = EnvOutputFileName + ".bat";

            try
            {
                var EnvVarsToXMLExePath = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation()), "EnvVarsToXML.exe");

                // Convert every path to short filenames to ensure we don't accidentally write out a non-ASCII batch file
                var ShortBatchFileName       = FileSystem.FileSystem.GetShortPathName(BatchFileName);
                var ShortEnvOutputFileName   = Path.Combine("%~dp0%", Path.GetFileName(EnvOutputFileName));
                var ShortEnvVarsToXMLExePath = FileSystem.FileSystem.GetShortPathName(EnvVarsToXMLExePath);

                var EnvReaderBatchFileContent = new StringBuilder();

                // Run 'vcvars32.bat' (or similar x64 version) to set environment variables
                EnvReaderBatchFileContent.AppendFormat("call \"{0}\" {1}", ShortBatchFileName, BatchFileParameters).AppendLine();

                // Pipe all environment variables to a file where we can read them in.
                // We use a separate executable which runs after the batch file because we want to capture
                // the environment after it has been set, and there's no easy way of doing this, and parsing
                // the output of the set command is problematic when the vars contain non-ASCII characters.
                EnvReaderBatchFileContent.AppendFormat("\"{0}\" \"{1}\"", ShortEnvVarsToXMLExePath, ShortEnvOutputFileName).AppendLine();

                FileInfo TempFileInfo = new FileInfo(EnvReaderBatchFileName);
                if (TempFileInfo.Exists)
                {
                    TempFileInfo.IsReadOnly = false;
                    TempFileInfo.Delete();
                    TempFileInfo.Refresh();
                }

                Directory.CreateDirectory(Path.GetDirectoryName(EnvReaderBatchFileName));
                File.WriteAllText(EnvReaderBatchFileName, EnvReaderBatchFileContent.ToString());
            }
            catch (Exception Ex)
            {
                throw new Exception(string.Format("Failed to create temporary batch file {0} to harvest environment variables (\"{1}\")", EnvReaderBatchFileName, Ex.Message), Ex);
            }

            // process needs to be disposed when done
            using (var BatchFileProcess = new Process())
            {
                // Run the batch file using cmd.exe with the /U option, to force Unicode output. Many locales have non-ANSI characters in system paths.
                var StartInfo = BatchFileProcess.StartInfo;
                StartInfo.FileName        = Path.Combine(Environment.SystemDirectory, "cmd.exe");
                StartInfo.Arguments       = String.Format("/U /C \"{0}\"", EnvReaderBatchFileName);
                StartInfo.CreateNoWindow  = true;
                StartInfo.UseShellExecute = false;

                // Override path variable if it can be particularly long
                if (PathOverride == EPathOverride.User)
                {
                    string NewPathVariable = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine) ?? "";
                    if (String.IsNullOrEmpty(NewPathVariable))
                    {
                        NewPathVariable = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User);
                    }
                    else
                    {
                        NewPathVariable += ";" + Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.User);
                    }
                    StartInfo.EnvironmentVariables["PATH"] = NewPathVariable;
                }

                // Try to launch the process, and produce a friendly error message if it fails.
                try
                {
                    // Start the process up and then wait for it to finish
                    BatchFileProcess.Start();
                    BatchFileProcess.WaitForExit();
                }
                catch (Exception Ex)
                {
                    throw new Exception(string.Format("Failed to start local process for action (\"{0}\"): {1} {2}", Ex.Message, StartInfo.FileName, StartInfo.Arguments), Ex);
                }
            }

            // Accept chars which are technically not valid XML - they were written out by XmlSerializer anyway!
            var Settings = new XmlReaderSettings();

            Settings.CheckCharacters = false;

            List <Tools.DotNETCommonPrivate.HarvestEnvVars.EnvVar> EnvVars;

            try
            {
                using (var Stream = new StreamReader(EnvOutputFileName))
                    using (var Reader = XmlReader.Create(Stream, Settings))
                    {
                        EnvVars = (List <Tools.DotNETCommonPrivate.HarvestEnvVars.EnvVar>)EnvVarListSerializer.Deserialize(Reader);
                    }
            }
            catch (Exception Ex)
            {
                throw new Exception(string.Format("Failed to read environment variables from XML file: {0}", EnvOutputFileName), Ex);
            }

            // Clean up the temporary files we created earlier on, so the temp directory doesn't fill up
            // with these guys over time
            try
            {
                File.Delete(EnvOutputFileName);
            }
            catch (Exception)
            {
                // Unable to delete the temporary file.  Not a big deal.
            }

            try
            {
                File.Delete(EnvReaderBatchFileName);
            }
            catch (Exception)
            {
                // Unable to delete the temporary file.  Not a big deal.
            }

            var Result = new CaselessDictionary.CaselessDictionary <string>();

            foreach (var Var in EnvVars)
            {
                Result.Add(Var.Key, Var.Value);
            }

            return(Result);
        }