Does Process.StartInfo.FileName accept long file names?

Looks like no.

If I convert the file name to its short value, Process.Start () works.

Process runScripts = new Process();
runScripts.StartInfo.FileName = @"C:\long file path\run.cmd";
runScripts.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
runScripts.StartInfo.UseShellExecute = true;
runScripts.StartInfo.RedirectStandardOutput = false;
runScripts.Start();

The above code does not work. But...

Process runScripts = new Process();
runScripts.StartInfo.FileName = @"C:\short\file\path\run.cmd";
runScripts.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
runScripts.StartInfo.UseShellExecute = true;
runScripts.StartInfo.RedirectStandardOutput = false;
runScripts.Start();

succeeds.

I managed to get around this by converting the long path name to the short path name. But I'm a little surprised to see this. Any reasons or background information about this?

Thanks.


Microsoft .NET Framework Version 2.0.50727 Update 1

+3
source share
9 answers

To reproduce your problem, I used the following program:

// file test.cs
using System;
using System.ComponentModel;
using System.Diagnostics;

public class Test
{
    public static int Main()
    {
        string error;
        try {
            ProcessStartInfo i = new ProcessStartInfo();
            i.FileName = @"C:\long file path\run.cmd";
            i.WindowStyle = ProcessWindowStyle.Hidden;
            i.UseShellExecute = true;
            i.RedirectStandardOutput = false;
            using (Process p = Process.Start(i)) {
                error = "No process object was returned from Process.Start";
                if (p != null) {
                    p.WaitForExit();
                    if (p.ExitCode == 0) {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.WriteLine("OK");
                        Console.ResetColor();
                        return 0;
                    }
                    error = "Process exit code was " + p.ExitCode;
                }
            }
        }
        catch (Win32Exception ex) {
            error = "(Win32Exception) " + ex.Message;
        }
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Whooops: " + error);
        Console.ResetColor();
        return 1;
    }
}

The code starts a new process (according to your sample code) and reports on various ways to execute it. You can compile the program from the command line:

c:\windows\Microsoft.NET\Framework\v2.0.50727\csc test.cs

(, test.cs , test.exe , test.cs)

, "C:\long file path\run.cmd" , :

Whooops: (Win32Exception) The system cannot find the file specified

"C:\long file path" run.cmd:

rem file run.cmd
echo I ran at %Time% > "%~dp0\run.out.txt"

. run.cmd test.exe (.. Run.cmd - , "C:\long file path\run.out.txt".

test.exe Vista x64 ( ), Windows XP SP3 x86 ( ), Windows Server 2008 x64 ( ) .

, ? , , , ( .NET , ).

+3

, , , , , , , :

    System.Diagnostics.Process runScripts = new System.Diagnostics.Process();
    runScripts.StartInfo.FileName = @"run.cmd";
    // new
    runScripts.StartInfo.WorkingDirectory = @"C:\long file path";
    runScripts.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
    runScripts.StartInfo.UseShellExecute = true;
    runScripts.StartInfo.RedirectStandardOutput = false;
    runScripts.Start();
+5

. .

string path = @"X:\Temp\long file path\run.cmd";
Process p = new Process();
p.StartInfo.FileName = path;

// Works with both true (default) and false.
p.StartInfo.UseShellExecute = true;
p.Start();

  string path = @"X:\Temp\long file path";
  string file = "run.cmd";

  Process p = new Process();
  p.StartInfo.FileName = file;
  p.StartInfo.WorkingDirectory = path;
  p.StartInfo.UseShellExecute = false; // only fails with false.
  p.Start();
  return;

( Process Monitor), ConsoleApplication.vshost.exe run.cmd \bin\Release, System32, System, Windows, System32\Wbem, ( ) , , , UseShellExecute = true.

+4

.

    private string StartProcessAndGetResult(string executableFile, string arguments)
    //NOTE executable file should be passed as string with a full path
    //For example: C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe
    //Without """ and @ signs
    {
        var result = String.Empty;
        var workingDirectory = Path.GetDirectoryName(executableFile);


        var processStartInfo = new ProcessStartInfo(executableFile, arguments)
                                   {
                                       WorkingDirectory = workingDirectory,
                                       UseShellExecute = false,
                                       ErrorDialog = false,
                                       CreateNoWindow = true,
                                       RedirectStandardOutput = true
                                   };
        var process = Process.Start(processStartInfo);
        if (process != null)
        {
            using (var streamReader = process.StandardOutput)
            {
                result = streamReader.ReadToEnd();
            }
        }
        return result;
    }

@ ( "" ) .

+2

Try

runScripts.StartInfo.FileName = @"""C:\long file path\run.cmd""";

, Process. , ?

+1

. Win32 , , descibe filenames, MAX_PATH (260 ), '\ 0'.

, #?

( , , , , .)

, "\\? \". ( , , , ) .

runScripts.StartInfo.FileName = @"\\?\C:\long file path\run.cmd";

MAX_PATH: http://msdn.microsoft.com/en-us/library/aa365247.aspx

/Leif

+1

()

, Process.Start . , , .

, , CreateProcess , .NET( , )

:

namespace SoTest
{
    class Program
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool CreateProcess([MarshalAs(UnmanagedType.LPTStr)] string lpApplicationName, StringBuilder lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes, SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, [MarshalAs(UnmanagedType.LPTStr)] string lpCurrentDirectory, STARTUPINFO lpStartupInfo, PROCESS_INFORMATION lpProcessInformation);

        static void Main(string[] args)
        {
            Process process = new Process();
            process.StartInfo.FileName = @"C:\my test folder\my test.bat";

            StringBuilder cmdLine = new StringBuilder();
            cmdLine.Append(process.StartInfo.FileName);
            STARTUPINFO lpStartupInfo = new STARTUPINFO();
            PROCESS_INFORMATION lpProcessInformation = new PROCESS_INFORMATION();

            // This fails
            //string workingDirectory = process.StartInfo.WorkingDirectory;
            string workingDirectory = @"C:\my test folder\";

            CreateProcess(null, cmdLine, null, null, true, 0, IntPtr.Zero, workingDirectory, lpStartupInfo, lpProcessInformation);
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    internal class PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;

        public PROCESS_INFORMATION()
        {
            this.hProcess = IntPtr.Zero;
            this.hThread = IntPtr.Zero;
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    internal class SECURITY_ATTRIBUTES
    {
        public int nLength;
        public long lpSecurityDescriptor;
        public bool bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal class STARTUPINFO
    {
        public int cb;
        public IntPtr lpReserved;
        public IntPtr lpDesktop;
        public IntPtr lpTitle;
        public int dwX;
        public int dwY;
        public int dwXSize;
        public int dwYSize;
        public int dwXCountChars;
        public int dwYCountChars;
        public int dwFillAttribute;
        public int dwFlags;
        public short wShowWindow;
        public short cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;

        public STARTUPINFO()
        {
            this.lpReserved = IntPtr.Zero;
            this.lpDesktop = IntPtr.Zero;
            this.lpTitle = IntPtr.Zero;
            this.lpReserved2 = IntPtr.Zero;
            this.hStdInput = IntPtr.Zero;
            this.hStdOutput = IntPtr.Zero;
            this.hStdError = IntPtr.Zero;
            this.cb = Marshal.SizeOf(this);
        }
    }       
}

SafeFileHandle , , . , .

+1

:

Process runScripts = new Process();
runScripts.StartInfo.FileName = @"""C:\long file path\run.cmd""";
runScripts.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
runScripts.StartInfo.UseShellExecute = true;
runScripts.StartInfo.RedirectStandardOutput = false;
runScripts.Start();

those. use quoted string for FileName when file_name has spaces.

0
source

Your code may fail for various reasons unrelated to the long / short path problem. You should add a precise description of the exception (including the call stack) to your question.

0
source

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


All Articles