浏览代码

Bug 2055: Make Session.ExecutablePath return detected or actual executable path when not set

https://winscp.net/tracker/2055

Source commit: 1e53d0a9e6caaafbb509ba848e46510b0b62e6f3
Martin Prikryl 3 年之前
父节点
当前提交
9a8c1d5771
共有 2 个文件被更改,包括 69 次插入34 次删除
  1. 26 1
      dotnet/Session.cs
  2. 43 33
      dotnet/internal/ExeSessionProcess.cs

+ 26 - 1
dotnet/Session.cs

@@ -70,7 +70,7 @@ namespace WinSCP
     [ComSourceInterfaces(typeof(ISessionEvents))]
     [ComSourceInterfaces(typeof(ISessionEvents))]
     public sealed class Session : IDisposable, IReflect
     public sealed class Session : IDisposable, IReflect
     {
     {
-        public string ExecutablePath { get { return _executablePath; } set { CheckNotOpened(); _executablePath = value; } }
+        public string ExecutablePath { get { return GetExecutablePath(); } set { CheckNotOpened(); _executablePath = value; } }
 #if !NETSTANDARD
 #if !NETSTANDARD
         public string ExecutableProcessUserName { get { return _executableProcessUserName; } set { CheckNotOpened(); _executableProcessUserName = value; } }
         public string ExecutableProcessUserName { get { return _executableProcessUserName; } set { CheckNotOpened(); _executableProcessUserName = value; } }
         public SecureString ExecutableProcessPassword { get { return _executableProcessPassword; } set { CheckNotOpened(); _executableProcessPassword = value; } }
         public SecureString ExecutableProcessPassword { get { return _executableProcessPassword; } set { CheckNotOpened(); _executableProcessPassword = value; } }
@@ -2519,6 +2519,31 @@ namespace WinSCP
             }
             }
         }
         }
 
 
+        private string GetExecutablePath()
+        {
+            string result;
+            if (_process != null)
+            {
+                result = _process.ExecutablePath;
+            }
+            else
+            {
+                // Same as ExeSessionProcess.GetExecutablePath,
+                // except that it does not throw when user-provided "executable path" does not exist
+
+                if (!string.IsNullOrEmpty(_executablePath))
+                {
+                    result = _executablePath;
+                }
+                else
+                {
+                    result = ExeSessionProcess.FindExecutable(this);
+                }
+            }
+            return result;
+        }
+
+
 #if !NETSTANDARD
 #if !NETSTANDARD
         private static string GetTypeLibKey(Type t)
         private static string GetTypeLibKey(Type t)
         {
         {

+ 43 - 33
dotnet/internal/ExeSessionProcess.cs

@@ -27,6 +27,7 @@ namespace WinSCP
         public int ExitCode { get { return _process.ExitCode; } }
         public int ExitCode { get { return _process.ExitCode; } }
         public PipeStream StdOut { get; set; }
         public PipeStream StdOut { get; set; }
         public Stream StdIn { get; set; }
         public Stream StdIn { get; set; }
+        public string ExecutablePath { get; }
 
 
         public static ExeSessionProcess CreateForSession(Session session)
         public static ExeSessionProcess CreateForSession(Session session)
         {
         {
@@ -46,9 +47,9 @@ namespace WinSCP
 
 
             using (_logger.CreateCallstack())
             using (_logger.CreateCallstack())
             {
             {
-                string executablePath = GetExecutablePath();
+                ExecutablePath = GetExecutablePath();
 
 
-                _logger.WriteLine("EXE executable path resolved to {0}", executablePath);
+                _logger.WriteLine("EXE executable path resolved to {0}", ExecutablePath);
 
 
                 string assemblyFilePath = _logger.GetAssemblyFilePath();
                 string assemblyFilePath = _logger.GetAssemblyFilePath();
                 FileVersionInfo assemblyVersion = null;
                 FileVersionInfo assemblyVersion = null;
@@ -57,7 +58,7 @@ namespace WinSCP
                     assemblyVersion = FileVersionInfo.GetVersionInfo(assemblyFilePath);
                     assemblyVersion = FileVersionInfo.GetVersionInfo(assemblyFilePath);
                 }
                 }
 
 
-                CheckVersion(executablePath, assemblyVersion);
+                CheckVersion(ExecutablePath, assemblyVersion);
 
 
                 string configSwitch;
                 string configSwitch;
                 if (_session.DefaultConfigurationInternal)
                 if (_session.DefaultConfigurationInternal)
@@ -117,8 +118,8 @@ namespace WinSCP
                 }
                 }
 
 
                 _process = new Process();
                 _process = new Process();
-                _process.StartInfo.FileName = executablePath;
-                _process.StartInfo.WorkingDirectory = Path.GetDirectoryName(executablePath);
+                _process.StartInfo.FileName = ExecutablePath;
+                _process.StartInfo.WorkingDirectory = Path.GetDirectoryName(ExecutablePath);
                 _process.StartInfo.Arguments = arguments;
                 _process.StartInfo.Arguments = arguments;
                 _process.StartInfo.UseShellExecute = false;
                 _process.StartInfo.UseShellExecute = false;
                 _process.Exited += ProcessExited;
                 _process.Exited += ProcessExited;
@@ -924,29 +925,39 @@ namespace WinSCP
                 }
                 }
                 else
                 else
                 {
                 {
-                    if (!TryFindExecutableInPath(GetAssemblyPath(), out executablePath) &&
-                        !TryFindExecutableInPath(GetEntryAssemblyPath(), out executablePath) &&
+                    executablePath = FindExecutable(_session);
+                }
+                return executablePath;
+            }
+        }
+
+        // Should be moved to Session class
+        internal static string FindExecutable(Session session)
+        {
+            Logger logger = session.Logger;
+            string executablePath;
+            if (!TryFindExecutableInPath(logger, GetAssemblyPath(logger), out executablePath) &&
+                !TryFindExecutableInPath(logger, GetEntryAssemblyPath(logger), out executablePath) &&
 #if !NETSTANDARD
 #if !NETSTANDARD
-                        !TryFindExecutableInPath(GetInstallationPath(RegistryHive.CurrentUser), out executablePath) &&
-                        !TryFindExecutableInPath(GetInstallationPath(RegistryHive.LocalMachine), out executablePath) &&
+                !TryFindExecutableInPath(logger, GetInstallationPath(RegistryHive.CurrentUser), out executablePath) &&
+                !TryFindExecutableInPath(logger, GetInstallationPath(RegistryHive.LocalMachine), out executablePath) &&
 #endif
 #endif
-                        !TryFindExecutableInPath(GetDefaultInstallationPath(), out executablePath))
-                    {
-                        string entryAssemblyDesc = string.Empty;
-                        Assembly entryAssembly = Assembly.GetEntryAssembly();
-                        if (entryAssembly != null)
-                        {
-                            entryAssemblyDesc = $", nor the entry assembly {entryAssembly.GetName().Name} ({GetEntryAssemblyPath()})";
-                        }
-                        throw _logger.WriteException(
-                            new SessionLocalException(_session,
-                                string.Format(CultureInfo.CurrentCulture,
-                                    "The {0} executable was not found at location of the assembly {1} ({2}){3}, nor in an installation path. You may use Session.ExecutablePath property to explicitly set path to {0}.",
-                                    ExeExecutableFileName, Assembly.GetExecutingAssembly().GetName().Name, GetAssemblyPath(), entryAssemblyDesc)));
-                    }
+                !TryFindExecutableInPath(logger, GetDefaultInstallationPath(), out executablePath))
+            {
+                string entryAssemblyDesc = string.Empty;
+                Assembly entryAssembly = Assembly.GetEntryAssembly();
+                if (entryAssembly != null)
+                {
+                    entryAssemblyDesc = $", nor the entry assembly {entryAssembly.GetName().Name} ({GetEntryAssemblyPath(logger)})";
                 }
                 }
-                return executablePath;
+                throw logger.WriteException(
+                    new SessionLocalException(session,
+                        string.Format(CultureInfo.CurrentCulture,
+                            "The {0} executable was not found at location of the assembly {1} ({2}){3}, nor in an installation path. You may use Session.ExecutablePath property to explicitly set path to {0}.",
+                            ExeExecutableFileName, Assembly.GetExecutingAssembly().GetName().Name, GetAssemblyPath(logger), entryAssemblyDesc)));
             }
             }
+
+            return executablePath;
         }
         }
 
 
         private static string GetDefaultInstallationPath()
         private static string GetDefaultInstallationPath()
@@ -973,7 +984,7 @@ namespace WinSCP
         }
         }
 #endif
 #endif
 
 
-        private bool TryFindExecutableInPath(string path, out string result)
+        private static bool TryFindExecutableInPath(Logger logger, string path, out string result)
         {
         {
             if (string.IsNullOrEmpty(path))
             if (string.IsNullOrEmpty(path))
             {
             {
@@ -985,25 +996,25 @@ namespace WinSCP
                 if (File.Exists(executablePath))
                 if (File.Exists(executablePath))
                 {
                 {
                     result = executablePath;
                     result = executablePath;
-                    _logger.WriteLine("Executable found in {0}", executablePath);
+                    logger.WriteLine("Executable found in {0}", executablePath);
                 }
                 }
                 else
                 else
                 {
                 {
                     result = null;
                     result = null;
-                    _logger.WriteLine("Executable not found in {0}", executablePath);
+                    logger.WriteLine("Executable not found in {0}", executablePath);
                 }
                 }
             }
             }
             return (result != null);
             return (result != null);
         }
         }
 
 
-        private string GetAssemblyPath()
+        private static string GetAssemblyPath(Logger logger)
         {
         {
-            return DoGetAssemblyPath(_logger.GetAssemblyFilePath());
+            return DoGetAssemblyPath(logger.GetAssemblyFilePath());
         }
         }
 
 
-        private string GetEntryAssemblyPath()
+        private static string GetEntryAssemblyPath(Logger logger)
         {
         {
-            return DoGetAssemblyPath(_logger.GetEntryAssemblyFilePath());
+            return DoGetAssemblyPath(logger.GetEntryAssemblyFilePath());
         }
         }
 
 
         private static string DoGetAssemblyPath(string codeBasePath)
         private static string DoGetAssemblyPath(string codeBasePath)
@@ -1155,8 +1166,7 @@ namespace WinSCP
 
 
         public void WriteStatus()
         public void WriteStatus()
         {
         {
-            string executablePath = GetExecutablePath();
-            _logger.WriteLine("{0} - exists [{1}]", executablePath, File.Exists(executablePath));
+            _logger.WriteLine("{0} - exists [{1}]", ExecutablePath, File.Exists(ExecutablePath));
         }
         }
 
 
         public void RequestCallstack()
         public void RequestCallstack()