Skip to content

Commit

Permalink
Bug 1495: WinSCP .NET assembly fails when finding WinSCP executable i…
Browse files Browse the repository at this point in the history
…n its installation folder

https://winscp.net/tracker/1495
(cherry picked from commit 3884ab3)

Source commit: b4ac9bcdc62eb52b5381a715c9b51b230305a096
  • Loading branch information
martinprikryl committed Jan 28, 2018
1 parent 02c0a82 commit f713b90
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
2 changes: 1 addition & 1 deletion dotnet/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,4 @@
[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)")]
[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)")]
43 changes: 27 additions & 16 deletions dotnet/internal/ExeSessionProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -794,8 +794,8 @@ private string GetExecutablePath()
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,
Expand Down Expand Up @@ -823,26 +823,37 @@ private static string GetDefaultInstallationPath()
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);
}
}
}

Expand Down

0 comments on commit f713b90

Please sign in to comment.