Can Process.Start () take the PATH system into account?

I searched and experimented for a while with this, but I had no luck.

I am trying to create a console program to automate some tasks that I could not do with a BAT file. I want to call "signcode.exe" from the Windows SDK, the bin folder with all the tools on my PATH system, and I can call "signcode" from anywhere, but Process.Start ignores the path.

Current code:

 System.Diagnostics.Process sign = new System.Diagnostics.Process(); sign.StartInfo.FileName = signCommand.Substring(0, signCommand.IndexOf(' ')); // signtool.exe sign.StartInfo.Arguments = signCommand.Substring(signCommand.IndexOf(' ') + 1); // /sign /a file1 file2 // sign.StartInfo.EnvironmentVariables["Path"] = Environment.GetEnvironmentVariable("PATH"); // This doesn't work either sign.StartInfo.UseShellExecute = false; sign.StartInfo.RedirectStandardOutput = true; sign.StartInfo.RedirectStandardError = true; sign.Start(); // Throws Win32Exception - The system cannot find the file specified 

I have confirmed that StartInfo.EnvironmentVariables ["Path"] matches my system path and contains the Windows SDK folder. Manual configuration also does not work.

I even tried setting TempPath, as shown on the MSDN page, for the EnvironmentVariables property , but that didn't work either. I wonder why you could install this if it has no effect.

If System.Diagnostics.Process cannot use the path, are there any other functions that I could use? I would also like to see the output of the command in my console application.

Here are some additional debugging values:

 Console.WriteLine("Sign Filename = '{0}'", sign.StartInfo.FileName); Sign Filename = 'signtool.exe' Console.WriteLine("Sign Arguments = '{0}'", sign.StartInfo.Arguments); Sign Arguments = '/sign /f C:\Visual Studio\Projects\MGInsight\MGInsight\APPARENTINC.pfx /t http://timestamp.comodoca.com/authenticode "C:\Visual Studio\Projects\MGInsight\MGInsight\Publish\Application Files\\MGInsight_0_9_1_85\MGInsight.exe" "C:\Visual Studio\Projects\MGInsight\MGInsight\Publish\Application Files\\MGInsight_0_9_1_85\XPXScanner.dll" "C:\Visual Studio\Projects\MGInsight\MGInsight\Publish\Application Files\\MGInsight_0_9_1_85\NetworkCalculations.dll"' Console.WriteLine("Sign Path = '{0}'", sign.StartInfo.EnvironmentVariables["Path"]); Sign Path = 'C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;"C:\Program Files\Intel\WiFi\bin\";"C:\Program Files\Common Files\Intel\WirelessCommon\";"C:\Program Files (x86)\cwRsync\bin";"C:\Program Files (x86)\Git\cmd";"C:\Program Files (x86)\Git\bin";"C:\Program Files (x86)\Zend\ZendServer\bin";"C:\Program Files (x86)\Zend\ZendServer\share\ZendFramework\bin";"C:\Program Files\Java\jre6\bin";"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\";"C:\Program Files\Microsoft Windows Performance Toolkit\";C:\MinGW\bin;"C:\Program Files (x86)\Microsoft\ILMerge";"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin";C:\Program Files (x86)\Nmap' 

The path "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin" is where signtool.exe is, and I can run it from the command line just by typing signtool , but if I run this application from of the same invitation, he will not register this path.

+6
source share
7 answers

I am sure Process.Start respects PATH.

  • Are you sure your signCommand value is correct?
  • Is the directory value specified in PATH using quotation marks? The documents mention that such values ​​will not be respected.

Note that FileName can also be the full path to the executable.

+5
source

Adding mhutch to the answer: it really takes PATH into account, but I noticed that you really need to restart Visual Studio to select any path changes. This is kind of sneaky.

+14
source

Well, I think the problem was related to what mhutch said from the MSDN docs:

 If you have a path variable declared in your system using quotes, you must fully qualify that path when starting any process found in that location. Otherwise, the system will not find the path. For example, if c:\mypath is not in your path, and you add it using quotation marks: path = %path%;"c:\mypath", you must fully qualify any process in c:\mypath when starting it. 

I saw it from the beginning, but it seemed strange, so I did not pay attention to it. Not sure why this is the case, but it seems.

I tried to copy the signtool.exe file to C: \ sign \ tool \ bin and added it to my path, and then my code worked, so I think because I have quotes in this path due to spaces, I SOL and you will have to manually search for the path to the path to the Windows SDK if there is no way to add something with spaces to the path without using quotes.

+2
source

If you recently updated PATH, be sure to restart Visual Studio. Environment variables load when Visual Studio starts. Note that this applies to DEBUG mode execution.

+2
source

I believe that you are looking for the ProcessStartInfo.WorkingDirectory property .

+1
source

The file name StartInfo is actually the full path to the executable file.

For example, on my x264 wrapper, it looks like this:

 x264Start.FileName = Directory.GetCurrentDirectory() + @"\Tools\x264\x264x86-r1995.exe"; 

I would like to test the code by adding try {}, catch {} to it and writing down the actual file name that you are trying to call into debugging if you have an error.

Otherwise add something like below:

  if (File.exists(sign.FileName)) { sign.Start(); } else { Console.WriteLine("Can't find {0}", sign.FileName); throw new Exception("File doesn't exist"); } 

EDIT: A complete example has been added - it searches for CCleaner and then starts it with the "/ AUTO" switch. Just tested and works great.

  // detect if 64-bit system string programFiles = ""; if (Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE").Contains("64")) { Console.WriteLine("#info# x64 detected"); programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); } else { Console.WriteLine("#info# x86 detected"); programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86); } // search string[] dirs = Directory.GetDirectories(programFiles, "CCleaner", SearchOption.AllDirectories); string[] exes = Directory.GetFiles(programFiles, "CCleaner64.exe", SearchOption.AllDirectories); //debug only foreach (string s in dirs) { Console.WriteLine(s); } foreach (string s in exes) { Console.WriteLine(s); } // access directly ProcessStartInfo CCleaner = new ProcessStartInfo(exes[0], "/AUTO"); Process.Start(CCleaner); 
+1
source

Your code seems to take my path into account.

It's hard to say what might be wrong in your case, but you can try running your command through cmd.exe :

 sign.StartInfo.FileName = "cmd"; sign.StartInfo.Arguments = "/c signtool.exe ..."; 
0
source

Source: https://habr.com/ru/post/900742/


All Articles