Skip to content

Commit

Permalink
Merge pull request #26 from SuessLabs/feature/PLinkPackage
Browse files Browse the repository at this point in the history
Embedded PLink
  • Loading branch information
DamianSuess authored May 3, 2022
2 parents 1b2cdeb + 7700503 commit ce507b6
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 46 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ TestResult.xml
/[Dd]ocs/backup
/[Tt]ests
/[Tt]ools
/src/VsLinuxDebugger/plink.exe
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Now developers can build, deploy and debug projects on their remote Linux (Ubunt
![VS Menu](docs/ScreenShot-MenuItems.png)

* Build and upload to remote devices (_yes, this is a real pain_)
* Remote debugging (_P-Link only_)
* Remote debugging (_[P-Link](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) only_)
* VS Linux Debugger will automatically detect and install `vsdbg` for you!

### Customize your connections
Expand Down Expand Up @@ -77,6 +77,7 @@ To contribute, please pick off an item from the project or issue page. We'd love

## References

* [PuTTY PLink](http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html)
* [Extension Docs](https://docs.microsoft.com/en-us/visualstudio/extensibility/creating-a-settings-category?view=vs-2022)
* [Extension Sample](https://github.com/microsoft/VSSDK-Extensibility-Samples/tree/master/Options)
* [Offroad Debugging](https://github.com/Microsoft/MIEngine/wiki/Offroad-Debugging-of-.NET-Core-on-Linux---OSX-from-Visual-Studio)
3 changes: 0 additions & 3 deletions src/VsLinuxDebugger/Commands.Impl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,10 @@ private UserOptions ToUserOptions()
HostIp = Settings.HostIp,
HostPort = Settings.HostPort,

LocalPlinkEnabled = Settings.LocalPlinkEnabled,
LocalPLinkPath = Settings.LocalPLinkPath,

RemoteDebugDisplayGui = Settings.RemoteDebugDisplayGui,
RemoteDeployBasePath = Settings.RemoteDeployBasePath,
////RemoteDeployDebugPath = Settings.RemoteDeployDebugPath,
////RemoteDeployReleasePath = Settings.RemoteDeployReleasePath,
RemoteDotNetPath = Settings.RemoteDotNetPath,
RemoteVsDbgPath = Settings.RemoteVsDbgPath,

Expand Down
107 changes: 77 additions & 30 deletions src/VsLinuxDebugger/Core/LaunchBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,36 +84,7 @@ public string GenerateLaunchJson(bool vsdbgLogging = false)
{
string adapter, adapterArgs;

//// var sshEndpoint = $"{_opts.UserName}@{_opts.HostIp}:{_opts.HostPort}";
var sshEndpoint = $"{_opts.UserName}@{_opts.HostIp}";

var vsdbgLogPath = "";
if (vsdbgLogging)
vsdbgLogPath = $" --engineLogging={LinuxPath.Combine(RemoteDeployProjectFolder, "_vsdbg.log")}";

if (!_opts.LocalPlinkEnabled)
{
//// SSH Key alt-args:
//// $"-i \"{_opts.UserPrivateKeyPath}\" -o \"StrictHostKeyChecking no\" {RemoteUserName}@{RemoteHostIp} {_opts.RemoteVsDbgPath} --interpreter=vscode {vsdbgLogPath}")
var sshPassword = !_opts.UserPrivateKeyEnabled
? $"-pw {_opts.UserPass}"
: $"-i {_opts.UserPrivateKeyPath} -o \"StrictHostKeyChecking no\"";

adapter = "ssh.exe";
adapterArgs = $"{sshPassword} {sshEndpoint} {_opts.RemoteVsDbgPath} --interpreter=vscode {vsdbgLogPath}";
}
else
{
// TODO: Consider packing PLink.exe
//// "%LocalAppData%\\microsoft\\visualstudio\\16.0_c1d3f8c1\\extensions\\cruad2hg.efs\\plink.exe";
//// var plinkPath = Path.Combine(GetExtensionDirectory(), "plink.exe").Trim('"');

adapter = _opts.LocalPLinkPath;
adapterArgs = $"-ssh -pw {RemoteUserPass} {RemoteUserName}@{RemoteHostIp} -batch -T {RemoteVsDbgPath} {vsdbgLogPath}";

//// adapterArgs = $"-ssh -pw {RemoteUserPass} {RemoteUserName}@{RemoteHostIp} -batch -T {RemoteVsDbgPath} --interpreter=vscode {vsdbgLogPath}";
//// adapterArgs = $"-ssh -pw {_options.UserPass} {_options.UserName}@{_options.HostIp}:{_options.HostPort} -batch -T {_options.RemoteVsDbgPath} --interpreter=vscode";
}
(adapter, adapterArgs) = GetAdapter(vsdbgLogging);

var obj = new Launch(
RemoteDotNetPath,
Expand Down Expand Up @@ -147,5 +118,81 @@ public string GenerateLaunchJson(bool vsdbgLogging = false)

return outputPath;
}

private (string adapterPath, string adapterArgs) GetAdapter(bool vsdbgLogging = false)
{
// NOTE: Removed ":{RemoteHostPort}" because it failed to launch with PLink
// var sshEndpoint = $"{_opts.UserName}@{_opts.HostIp}:{_opts.HostPort}";
var sshEndpoint = $"{RemoteUserName}@{RemoteHostIp}";

var vsdbgLogPath = "";
if (vsdbgLogging)
vsdbgLogPath = $" --engineLogging={LinuxPath.Combine(RemoteDeployProjectFolder, "_vsdbg.log")}";

////if (!_opts.LocalPlinkEnabled)
////{
//// adapter = "ssh.exe";
//// adapterArgs = $"{sshPassword} {sshEndpoint} {_opts.RemoteVsDbgPath} --interpreter=vscode {vsdbgLogPath}";
////}
////else
////{

string plinkPath = string.Empty;

// Adapter Path:
// PLink.exe - Use manual path or embedded
if (!string.IsNullOrEmpty(_opts.LocalPLinkPath) && File.Exists(_opts.LocalPLinkPath))
{
plinkPath = _opts.LocalPLinkPath;
}
else
{
plinkPath = Path.Combine(GetExtensionDirectory(), "plink.exe").Trim('"');
}

// Adapter Arguments:
// NOTE:
// 1. SSH Private Key ("-i PPK") fails with PLINK. Must use manual password until this is resolved.
// 2. Strict Host Key Checking is disabled by default; this doesn't need set.
//
// REF: https://linuxhint.com/ssh-stricthostkeychecking/
// $"-i \"{_opts.UserPrivateKeyPath}\" -o \"StrictHostKeyChecking no\" {RemoteUserName}@{RemoteHostIp} {_opts.RemoteVsDbgPath} --interpreter=vscode {vsdbgLogPath}")
//
//// var strictKeyChecking = " -o \"StrictHostKeyChecking no\"";
//// strictKeyChecking = "";
////
////var sshPassword = !_opts.UserPrivateKeyEnabled
//// ? $"-pw {RemoteUserPass}"
//// : $"-i \"{_opts.UserPrivateKeyPath}{strictKeyChecking}\"";
//
var sshPassword = $"-pw {RemoteUserPass}";

// TODO: Figure out why "-i <keyfile>" isn't working.
if (string.IsNullOrEmpty(RemoteUserPass))
Logger.Output("You must provide a User Password to debug.");

var adapter = plinkPath;
var adapterArgs = $"-ssh {sshPassword} {sshEndpoint} -batch -T {RemoteVsDbgPath} {vsdbgLogPath}";
//// adapterArgs = $"-ssh {sshPassword} {sshEndpoint} -batch -T {RemoteVsDbgPath} --interpreter=vscode {vsdbgLogPath}";

return (adapter, adapterArgs);
}

/// <summary>Attempt to get the extension's local directory.</summary>
/// <returns>Path of this VSIX or empty string.</returns>
private string GetExtensionDirectory()
{
var path = string.Empty;
try
{
var uri = new Uri(typeof(LaunchBuilder).Assembly.CodeBase, UriKind.Absolute);
path = Path.GetDirectoryName(uri.LocalPath);
}
catch (Exception)
{
}

return path;
}
}
}
5 changes: 4 additions & 1 deletion src/VsLinuxDebugger/Core/RemoteDebugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace VsLinuxDebugger.Core
{
public class RemoteDebugger
{
private const string DebugAdapterHost = "DebugAdapterHost.Launch";
private const string DebugAdapterLaunchJson = "/LaunchJson:";

private bool _buildSuccessful;
private TaskCompletionSource<bool> _buildTask = null;
private DTE _dte;
Expand Down Expand Up @@ -179,7 +182,7 @@ private void BuildDebugAttacher()
Logger.Output($"- DebugAdapterHost.Launch /LaunchJson:\"{_launchJsonPath}\"");

DTE2 dte2 = (DTE2)Package.GetGlobalService(typeof(SDTE));
dte2.ExecuteCommand("DebugAdapterHost.Launch", $"/LaunchJson:\"{_launchJsonPath}\"");
dte2.ExecuteCommand(DebugAdapterHost, $"{DebugAdapterLaunchJson}\"{_launchJsonPath}\"");

// launchConfigName = "Debug on Linux";
// DebugAdapterHost.Launch /LaunchJson:LaunchTester\Properties\launch.json /ConfigurationName:"{launchConfigName}"
Expand Down
3 changes: 0 additions & 3 deletions src/VsLinuxDebugger/DebuggerPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,10 @@ public sealed partial class DebuggerPackage : AsyncPackage
public string HostIp => _optionsPage.HostIp;
public int HostPort => _optionsPage.HostPort;

public bool LocalPlinkEnabled => _optionsPage.PLinkEnabled;
public string LocalPLinkPath => _optionsPage.PLinkPath;

public bool RemoteDebugDisplayGui => _optionsPage.RemoteDebugDisplayGui;
public string RemoteDeployBasePath => _optionsPage.RemoteDeployBasePath;
////public string RemoteDeployDebugPath => $"{_optionsPage.RemoteDeployBasePath}/TMP";
////public string RemoteDeployReleasePath => $"{_optionsPage.RemoteDeployBasePath}/TMP";
public string RemoteDotNetPath => _optionsPage.RemoteDotNetPath;
public string RemoteVsDbgPath => _optionsPage.RemoteVsDbgPath;

Expand Down
6 changes: 3 additions & 3 deletions src/VsLinuxDebugger/OptionsPages/OptionsPage.DotNet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Xeno.VsLinuxDebug.OptionsPages
{
public partial class OptionsPage : DialogPage
{
private const string Experimental = "Expermimental";
private const string Experimental = "Warning Expermimental";
private const string RemoteDebugger = "Remote Debugger";

[Category(Experimental)]
Expand All @@ -17,7 +17,7 @@ public partial class OptionsPage : DialogPage

[Category(RemoteDebugger)]
[DisplayName("Upload to folder")]
[Description("Folder for to transfer files to. For HOME folder, use './VLSDbg' and not '~/VLSDbg'")]
[Description("Folder for to transfer files to. For HOME folder, use './VSLinuxDbg' and not '~/VSLinuxDbg'")]
public string RemoteDeployBasePath { get; set; } = $"./VSLinuxDbg"; // "VSLDebugger"

[Category(RemoteDebugger)]
Expand All @@ -27,7 +27,7 @@ public partial class OptionsPage : DialogPage

[Category(RemoteDebugger)]
[DisplayName("Visual Studio Debugger Path")]
[Description("Remote Machine Visual Studio Debugger Path (Samples: `vsdbg`, `/.vsdbg/vsdbg`, `~/.vs-debugger/vs2022/vsdbg`")]
[Description("Remote Machine Visual Studio Debugger Path (Samples: `vsdbg`, `~/vsdbg/vsdbg`, `~/.vs-debugger/vs2022/vsdbg`")]
public string RemoteVsDbgPath { get; set; } = "~/vsdbg/vsdbg";

[Category(Experimental)]
Expand Down
14 changes: 9 additions & 5 deletions src/VsLinuxDebugger/OptionsPages/OptionsPage.Local.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ public partial class OptionsPage : DialogPage
////[Description("Publish the solution instead of building. Apply setting for ASP.NET/Blazor projects.")]
////public bool Publish { get; set; } = false;

[Category(Local)]
[DisplayName("PLink: Enable Plink instead of SSH")]
[Description("Set to TRUE to debug with PLINK.EXE and FALSE for SSH.")]
public bool PLinkEnabled { get; set; } = false;
////[Category(Local)]
////[DisplayName("PLink: Enable Plink instead of SSH")]
//// <summary>
//// [Category(Local)]
//// </summary> to TRUE to debug with PLINK.EXE and FALSE for SSH.")]
//// <summary>
//// [Category(Local)]
//// </summary>Enabled { get; set; } = false;

[Category(Local)]
[DisplayName("PLink: Local Path")]
[DisplayName("PLink Local Path (blank to use embedded)")]
[Description(@"Full path to local PLINK.EXE file. (i.e. 'C:\temp\putty\plink.exe')")]
public string PLinkPath { get; set; } = "";

Expand Down
17 changes: 17 additions & 0 deletions src/VsLinuxDebugger/VsLinuxDebugger.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,21 @@
<Target Name="AfterBuild">
</Target>
-->

<!-- Download PLink.exe to package with project -->
<PropertyGroup>
<PLinkUrl>https://the.earth.li/~sgtatham/putty/latest/w64/plink.exe</PLinkUrl>
</PropertyGroup>
<Target Name="DownloadContentFiles" BeforeTargets="Build">
<DownloadFile SourceUrl="$(PLinkUrl)"
DestinationFolder="$(MSBuildProjectDirectory)">
<Output TaskParameter="DownloadedFile" ItemName="Content" />
</DownloadFile>
</Target>
<ItemGroup>
<Content Include="plink.exe" Condition="Exists('plink.exe')">
<IncludeInVSIX>true</IncludeInVSIX>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

0 comments on commit ce507b6

Please sign in to comment.