@@ -28,14 +28,12 @@ public class DebugService
2828 private const string PsesGlobalVariableNamePrefix = "__psEditorServices_" ;
2929
3030 private PowerShellContext powerShellContext ;
31+ private RemoteFileManager remoteFileManager ;
3132
3233 // TODO: This needs to be managed per nested session
3334 private Dictionary < string , List < Breakpoint > > breakpointsPerFile =
3435 new Dictionary < string , List < Breakpoint > > ( ) ;
3536
36- private Dictionary < RunspaceDetails , Dictionary < string , string > > remoteFileMappings =
37- new Dictionary < RunspaceDetails , Dictionary < string , string > > ( ) ;
38-
3937 private int nextVariableId ;
4038 private List < VariableDetailsBase > variables ;
4139 private VariableContainerDetails globalScopeVariables ;
@@ -56,12 +54,31 @@ public class DebugService
5654 /// The PowerShellContext to use for all debugging operations.
5755 /// </param>
5856 public DebugService ( PowerShellContext powerShellContext )
57+ : this ( powerShellContext , null )
58+ {
59+ }
60+
61+ /// <summary>
62+ /// Initializes a new instance of the DebugService class and uses
63+ /// the given PowerShellContext for all future operations.
64+ /// </summary>
65+ /// <param name="powerShellContext">
66+ /// The PowerShellContext to use for all debugging operations.
67+ /// </param>
68+ /// <param name="remoteFileManager">
69+ /// A RemoteFileManager instance to use for accessing files in remote sessions.
70+ /// </param>
71+ public DebugService (
72+ PowerShellContext powerShellContext ,
73+ RemoteFileManager remoteFileManager )
5974 {
60- Validate . IsNotNull ( " powerShellContext" , powerShellContext ) ;
75+ Validate . IsNotNull ( nameof ( powerShellContext ) , powerShellContext ) ;
6176
6277 this . powerShellContext = powerShellContext ;
6378 this . powerShellContext . DebuggerStop += this . OnDebuggerStop ;
6479 this . powerShellContext . BreakpointUpdated += this . OnBreakpointUpdated ;
80+
81+ this . remoteFileManager = remoteFileManager ;
6582 }
6683
6784 #endregion
@@ -91,12 +108,13 @@ public async Task<BreakpointDetails[]> SetLineBreakpoints(
91108 {
92109 // Make sure we're using the remote script path
93110 string scriptPath = scriptFile . FilePath ;
94- if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
111+ if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote &&
112+ this . remoteFileManager != null )
95113 {
96114 string mappedPath =
97- this . GetRemotePathMapping (
98- this . powerShellContext . CurrentRunspace ,
99- scriptPath ) ;
115+ this . remoteFileManager . GetMappedPath (
116+ scriptPath ,
117+ this . powerShellContext . CurrentRunspace ) ;
100118
101119 if ( mappedPath == null )
102120 {
@@ -764,13 +782,14 @@ private async Task FetchStackFrames()
764782 StackFrameDetails . Create ( callStackFrames [ i ] , autoVariables , localVariables ) ;
765783
766784 string stackFrameScriptPath = this . stackFrameDetails [ i ] . ScriptPath ;
767- if ( this . powerShellContext . CurrentRunspace . Location == Session . RunspaceLocation . Remote &&
785+ if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote &&
786+ this . remoteFileManager != null &&
768787 ! string . Equals ( stackFrameScriptPath , StackFrameDetails . NoFileScriptPath ) )
769788 {
770789 this . stackFrameDetails [ i ] . ScriptPath =
771- Workspace . MapRemotePathToLocal (
790+ this . remoteFileManager . GetMappedPath (
772791 stackFrameScriptPath ,
773- this . powerShellContext . CurrentRunspace . ConnectionString ) ;
792+ this . powerShellContext . CurrentRunspace ) ;
774793 }
775794 }
776795 }
@@ -960,34 +979,6 @@ private string FormatInvalidBreakpointConditionMessage(string condition, string
960979 return $ "'{ condition } ' is not a valid PowerShell expression. { message } ";
961980 }
962981
963- private void AddRemotePathMapping ( RunspaceDetails runspaceDetails , string remotePath , string localPath )
964- {
965- Dictionary < string , string > runspaceMappings = null ;
966-
967- if ( ! this . remoteFileMappings . TryGetValue ( runspaceDetails , out runspaceMappings ) )
968- {
969- runspaceMappings = new Dictionary < string , string > ( ) ;
970- this . remoteFileMappings . Add ( runspaceDetails , runspaceMappings ) ;
971- }
972-
973- // Add mappings in both directions
974- runspaceMappings [ localPath . ToLower ( ) ] = remotePath ;
975- runspaceMappings [ remotePath . ToLower ( ) ] = localPath ;
976- }
977-
978- private string GetRemotePathMapping ( RunspaceDetails runspaceDetails , string localPath )
979- {
980- string remotePath = null ;
981- Dictionary < string , string > runspaceMappings = null ;
982-
983- if ( this . remoteFileMappings . TryGetValue ( runspaceDetails , out runspaceMappings ) )
984- {
985- runspaceMappings . TryGetValue ( localPath . ToLower ( ) , out remotePath ) ;
986- }
987-
988- return remotePath ;
989- }
990-
991982 #endregion
992983
993984 #region Events
@@ -1003,56 +994,14 @@ private async void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
1003994 await this . FetchStackFramesAndVariables ( ) ;
1004995
1005996 // If this is a remote connection, get the file content
1006- string localScriptPath = null ;
1007- if ( this . powerShellContext . CurrentRunspace . Location == Session . RunspaceLocation . Remote )
997+ string localScriptPath = e . InvocationInfo . ScriptName ;
998+ if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote &&
999+ this . remoteFileManager != null )
10081000 {
1009- string remoteScriptPath = e . InvocationInfo . ScriptName ;
1010- if ( ! string . IsNullOrEmpty ( remoteScriptPath ) )
1011- {
1012- localScriptPath =
1013- Workspace . MapRemotePathToLocal (
1014- remoteScriptPath ,
1015- this . powerShellContext . CurrentRunspace . ConnectionString ) ;
1016-
1017- // TODO: Catch filesystem exceptions!
1018-
1019- // Does the local file already exist?
1020- if ( ! File . Exists ( localScriptPath ) )
1021- {
1022- // Load the file contents from the remote machine and create the buffer
1023- PSCommand command = new PSCommand ( ) ;
1024- command . AddCommand ( "Microsoft.PowerShell.Management\\ Get-Content" ) ;
1025- command . AddParameter ( "Path" , remoteScriptPath ) ;
1026- command . AddParameter ( "Raw" ) ;
1027- command . AddParameter ( "Encoding" , "Byte" ) ;
1028-
1029- byte [ ] fileContent =
1030- ( await this . powerShellContext . ExecuteCommand < byte [ ] > ( command , false , false ) )
1031- . FirstOrDefault ( ) ;
1032-
1033- if ( fileContent != null )
1034- {
1035- File . WriteAllBytes ( localScriptPath , fileContent ) ;
1036- }
1037- else
1038- {
1039- Logger . Write (
1040- LogLevel . Warning ,
1041- $ "Could not load contents of remote file '{ remoteScriptPath } '") ;
1042- }
1043-
1044- // Add the file mapping so that breakpoints can be passed through
1045- // to the real file in the remote session
1046- this . AddRemotePathMapping (
1047- this . powerShellContext . CurrentRunspace ,
1048- remoteScriptPath ,
1049- localScriptPath ) ;
1050- this . AddRemotePathMapping (
1051- this . powerShellContext . CurrentRunspace ,
1052- localScriptPath ,
1053- remoteScriptPath ) ;
1054- }
1055- }
1001+ localScriptPath =
1002+ await this . remoteFileManager . FetchRemoteFile (
1003+ e . InvocationInfo . ScriptName ,
1004+ this . powerShellContext . CurrentRunspace ) ;
10561005 }
10571006
10581007 // Notify the host that the debugger is stopped
@@ -1082,12 +1031,13 @@ private void OnBreakpointUpdated(object sender, BreakpointUpdatedEventArgs e)
10821031 List < Breakpoint > breakpoints ;
10831032
10841033 string scriptPath = lineBreakpoint . Script ;
1085- if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
1034+ if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote &&
1035+ this . remoteFileManager != null )
10861036 {
10871037 string mappedPath =
1088- this . GetRemotePathMapping (
1089- this . powerShellContext . CurrentRunspace ,
1090- scriptPath ) ;
1038+ this . remoteFileManager . GetMappedPath (
1039+ scriptPath ,
1040+ this . powerShellContext . CurrentRunspace ) ;
10911041
10921042 if ( mappedPath == null )
10931043 {
0 commit comments