diff --git a/src/Extension/RemoteDebuggerLauncher/PackageConstants.cs b/src/Extension/RemoteDebuggerLauncher/PackageConstants.cs
index 22741ae..705652e 100644
--- a/src/Extension/RemoteDebuggerLauncher/PackageConstants.cs
+++ b/src/Extension/RemoteDebuggerLauncher/PackageConstants.cs
@@ -181,13 +181,18 @@ public static class SecureShell
public const string DefaultKnownHostsFileName = "known_hosts";
/// SSH key scanner arguments.
- public const string KeyScanArguments = "-4 -p {1} {0}";
+ /// No space after {2} because SshForceIPv4 includes a trailing space.
+ public const string KeyScanArguments = "{2}-p {1} {0}";
+
+ /// Argument for SSH to force IPv4 usage.
+ public const string SshForceIPv4 = "-4 ";
/// SSH executable.
public const string SshExecutable = "ssh.exe";
/// The SSH arguments to add server fingerprint to known_hosts file.
- public const string SshArguments = "{0}@{1} -p {2} -i \"{3}\" \"echo DONE\"";
+ /// No space after {4} because SshForceIPv4 includes a trailing space.
+ public const string SshArguments = "{0}@{1} {4}-p {2} -i \"{3}\" \"echo DONE\"";
/// HTTPS Developer Certificate name.
public const string HttpsCertificateName = "DevCert.pfx";
diff --git a/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupService.cs b/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupService.cs
index bb18930..165e6e4 100644
--- a/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupService.cs
+++ b/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupService.cs
@@ -11,6 +11,7 @@
using System.IO;
using System.Text;
using System.Threading.Tasks;
+using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Threading;
using RemoteDebuggerLauncher.Infrastructure;
using Renci.SshNet;
@@ -106,7 +107,7 @@ public async Task AuthorizeKeyAsync(SecureShellKeySetupSettings settings)
var defaultKeysFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), PackageConstants.SecureShell.DefaultKeyPairFolder);
var knownHostsFilePath = Path.Combine(defaultKeysFolder, PackageConstants.SecureShell.DefaultKnownHostsFileName);
- var arguments = string.Format(PackageConstants.SecureShell.KeyScanArguments, settings.HostName, settings.HostPort);
+ var arguments = string.Format(PackageConstants.SecureShell.KeyScanArguments, settings.HostName, settings.HostPort, settings.ForceIPv4 ? PackageConstants.SecureShell.SshForceIPv4 : string.Empty);
var startInfo = new ProcessStartInfo(PackageConstants.SecureShell.KeyScanExecutable, arguments)
{
CreateNoWindow = true,
@@ -124,6 +125,8 @@ public async Task AuthorizeKeyAsync(SecureShellKeySetupSettings settings)
var stdError = await process.StandardError.ReadToEndAsync();
var exitCode = await process.WaitForExitAsync();
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+
if (exitCode == 0)
{
if (FileHelper.ContainsText(knownHostsFilePath, settings.HostName))
@@ -155,7 +158,7 @@ private async Task RegisterServerFingerprintWithConnectionAsync(SecureShel
const string SshDoneMarker = "DONE";
// open a pseudo console windows to run the ssh command
- var arguments = string.Format(PackageConstants.SecureShell.SshArguments, settings.UserName, settings.HostName, settings.HostPort, settings.PrivateKeyFile);
+ var arguments = string.Format(PackageConstants.SecureShell.SshArguments, settings.UserName, settings.HostName, settings.HostPort, settings.PrivateKeyFile, settings.ForceIPv4 ? PackageConstants.SecureShell.SshForceIPv4 : string.Empty);
var startInfo = new ProcessStartInfo(PackageConstants.SecureShell.SshExecutable, arguments)
{
CreateNoWindow = false,
diff --git a/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupSettings.cs b/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupSettings.cs
index 7ccc331..774eb6d 100644
--- a/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupSettings.cs
+++ b/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellKeySetupSettings.cs
@@ -1,4 +1,4 @@
-// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
//
// Copyright (c) Michael Koster. All rights reserved.
// Licensed under the MIT License.
@@ -17,6 +17,7 @@ namespace RemoteDebuggerLauncher.RemoteOperations
internal class SecureShellKeySetupSettings
{
private readonly bool forceIPv4;
+
public SecureShellKeySetupSettings(SetupSshViewModel viewModel)
{
HostName = viewModel.HostName;
@@ -67,5 +68,10 @@ public SecureShellKeySetupSettings(SetupSshViewModel viewModel)
/// Gets the private key file.
///
public string PrivateKeyFile { get; }
+
+ ///
+ /// Gets a value indicating whether to force IPv4 usage.
+ ///
+ public bool ForceIPv4 => forceIPv4;
}
}
diff --git a/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellPassphraseDialog.xaml b/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellPassphraseDialog.xaml
deleted file mode 100644
index 861164a..0000000
--- a/src/Extension/RemoteDebuggerLauncher/RemoteOperations/SecureShellPassphraseDialog.xaml
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file