Răsfoiți Sursa

Bug 1495: WinSCP .NET assembly fails when finding WinSCP executable in its installation folder

https://winscp.net/tracker/1495

Source commit: f76e7f69326aaf17d1c136f085001e55ff19c529
Martin Prikryl 8 ani în urmă
părinte
comite
3884ab3e43
2 a modificat fișierele cu 28 adăugiri și 17 ștergeri
  1. 1 1
      dotnet/GlobalSuppressions.cs
  2. 27 16
      dotnet/internal/ExeSessionProcess.cs

+ 1 - 1
dotnet/GlobalSuppressions.cs

@@ -160,4 +160,4 @@ using System.Diagnostics.CodeAnalysis;
 [assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "WinSCP.SessionLogReader.#LogContents()")]
 [assembly: SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "WinSCP.Session.#SessionOptionsToSwitches(WinSCP.SessionOptions,System.Boolean,System.String&,System.String&)")]
 [assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#RegGetValue(System.UIntPtr,System.String,System.String,WinSCP.RegistryFlags,WinSCP.RegistryType&,System.IntPtr,System.UInt32&)")]
-[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#GetInstallationPath(Microsoft.Win32.RegistryHive)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#GetInstallationPath(Microsoft.Win32.RegistryHive,Microsoft.Win32.RegistryKey)")]

+ 27 - 16
dotnet/internal/ExeSessionProcess.cs

@@ -796,8 +796,8 @@ namespace WinSCP
                 else
                 {
                     if (!TryFindExecutableInPath(GetAssemblyPath(), out executablePath) &&
-                        !TryFindExecutableInPath(GetInstallationPath(RegistryHive.CurrentUser), out executablePath) &&
-                        !TryFindExecutableInPath(GetInstallationPath(RegistryHive.LocalMachine), out executablePath) &&
+                        !TryFindExecutableInPath(GetInstallationPath(RegistryHive.CurrentUser, Registry.CurrentUser), out executablePath) &&
+                        !TryFindExecutableInPath(GetInstallationPath(RegistryHive.LocalMachine, Registry.LocalMachine), out executablePath) &&
                         !TryFindExecutableInPath(GetDefaultInstallationPath(), out executablePath))
                     {
                         throw new SessionLocalException(_session,
@@ -825,26 +825,37 @@ namespace WinSCP
             return Path.Combine(programFiles, "WinSCP");
         }
 
-        private static string GetInstallationPath(RegistryHive hive)
+        private static string GetInstallationPath(RegistryHive hive, RegistryKey rootKey)
         {
-            // In .NET 4 we can use RegistryKey.OpenBaseKey(hive, RegistryView.Registry32);
-            const string uninstallKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall\winscp3_is1";
-            const string appPathValue = @"Inno Setup: App Path";
+            OperatingSystem OS = Environment.OSVersion;
+            string result;
+            // Windows XP does not have the RegGetValue. We do not care about 64-bit XP.
+            if ((OS.Version.Major < 5) || ((OS.Version.Major == 5) && (OS.Version.Minor <= 1)))
+            {
+                RegistryKey key = rootKey.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall\winscp3_is1");
+                result = (key != null) ? (string)key.GetValue("Inno Setup: App Path") : null;
+            }
+            else
+            {
+                // In .NET 4 we can use RegistryKey.OpenBaseKey(hive, RegistryView.Registry32);
+                const string uninstallKey = @"Software\Microsoft\Windows\CurrentVersion\Uninstall\winscp3_is1";
+                const string appPathValue = @"Inno Setup: App Path";
 
-            string result = null;
+                result = null;
 
-            IntPtr data = IntPtr.Zero;
-            RegistryType type;
-            uint len = 0;
-            RegistryFlags flags = RegistryFlags.RegSz | RegistryFlags.SubKeyWow6432Key;
-            UIntPtr key = (UIntPtr)((uint)hive);
+                IntPtr data = IntPtr.Zero;
+                RegistryType type;
+                uint len = 0;
+                RegistryFlags flags = RegistryFlags.RegSz | RegistryFlags.SubKeyWow6432Key;
+                UIntPtr key = (UIntPtr)((uint)hive);
 
-            if (UnsafeNativeMethods.RegGetValue(key, uninstallKey, appPathValue, flags, out type, data, ref len) == 0)
-            {
-                data = Marshal.AllocHGlobal((int)len);
                 if (UnsafeNativeMethods.RegGetValue(key, uninstallKey, appPathValue, flags, out type, data, ref len) == 0)
                 {
-                    result = Marshal.PtrToStringUni(data);
+                    data = Marshal.AllocHGlobal((int)len);
+                    if (UnsafeNativeMethods.RegGetValue(key, uninstallKey, appPathValue, flags, out type, data, ref len) == 0)
+                    {
+                        result = Marshal.PtrToStringUni(data);
+                    }
                 }
             }