@@ -28,14 +28,12 @@ public class DebugService
28
28
private const string PsesGlobalVariableNamePrefix = "__psEditorServices_" ;
29
29
30
30
private PowerShellContext powerShellContext ;
31
+ private RemoteFileManager remoteFileManager ;
31
32
32
33
// TODO: This needs to be managed per nested session
33
34
private Dictionary < string , List < Breakpoint > > breakpointsPerFile =
34
35
new Dictionary < string , List < Breakpoint > > ( ) ;
35
36
36
- private Dictionary < RunspaceDetails , Dictionary < string , string > > remoteFileMappings =
37
- new Dictionary < RunspaceDetails , Dictionary < string , string > > ( ) ;
38
-
39
37
private int nextVariableId ;
40
38
private List < VariableDetailsBase > variables ;
41
39
private VariableContainerDetails globalScopeVariables ;
@@ -56,12 +54,31 @@ public class DebugService
56
54
/// The PowerShellContext to use for all debugging operations.
57
55
/// </param>
58
56
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 )
59
74
{
60
- Validate . IsNotNull ( " powerShellContext" , powerShellContext ) ;
75
+ Validate . IsNotNull ( nameof ( powerShellContext ) , powerShellContext ) ;
61
76
62
77
this . powerShellContext = powerShellContext ;
63
78
this . powerShellContext . DebuggerStop += this . OnDebuggerStop ;
64
79
this . powerShellContext . BreakpointUpdated += this . OnBreakpointUpdated ;
80
+
81
+ this . remoteFileManager = remoteFileManager ;
65
82
}
66
83
67
84
#endregion
@@ -91,12 +108,13 @@ public async Task<BreakpointDetails[]> SetLineBreakpoints(
91
108
{
92
109
// Make sure we're using the remote script path
93
110
string scriptPath = scriptFile . FilePath ;
94
- if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
111
+ if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote &&
112
+ this . remoteFileManager != null )
95
113
{
96
114
string mappedPath =
97
- this . GetRemotePathMapping (
98
- this . powerShellContext . CurrentRunspace ,
99
- scriptPath ) ;
115
+ this . remoteFileManager . GetMappedPath (
116
+ scriptPath ,
117
+ this . powerShellContext . CurrentRunspace ) ;
100
118
101
119
if ( mappedPath == null )
102
120
{
@@ -764,13 +782,14 @@ private async Task FetchStackFrames()
764
782
StackFrameDetails . Create ( callStackFrames [ i ] , autoVariables , localVariables ) ;
765
783
766
784
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 &&
768
787
! string . Equals ( stackFrameScriptPath , StackFrameDetails . NoFileScriptPath ) )
769
788
{
770
789
this . stackFrameDetails [ i ] . ScriptPath =
771
- Workspace . MapRemotePathToLocal (
790
+ this . remoteFileManager . GetMappedPath (
772
791
stackFrameScriptPath ,
773
- this . powerShellContext . CurrentRunspace . ConnectionString ) ;
792
+ this . powerShellContext . CurrentRunspace ) ;
774
793
}
775
794
}
776
795
}
@@ -960,34 +979,6 @@ private string FormatInvalidBreakpointConditionMessage(string condition, string
960
979
return $ "'{ condition } ' is not a valid PowerShell expression. { message } ";
961
980
}
962
981
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
-
991
982
#endregion
992
983
993
984
#region Events
@@ -1003,56 +994,14 @@ private async void OnDebuggerStop(object sender, DebuggerStopEventArgs e)
1003
994
await this . FetchStackFramesAndVariables ( ) ;
1004
995
1005
996
// 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 )
1008
1000
{
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 ) ;
1056
1005
}
1057
1006
1058
1007
// Notify the host that the debugger is stopped
@@ -1082,12 +1031,13 @@ private void OnBreakpointUpdated(object sender, BreakpointUpdatedEventArgs e)
1082
1031
List < Breakpoint > breakpoints ;
1083
1032
1084
1033
string scriptPath = lineBreakpoint . Script ;
1085
- if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
1034
+ if ( this . powerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote &&
1035
+ this . remoteFileManager != null )
1086
1036
{
1087
1037
string mappedPath =
1088
- this . GetRemotePathMapping (
1089
- this . powerShellContext . CurrentRunspace ,
1090
- scriptPath ) ;
1038
+ this . remoteFileManager . GetMappedPath (
1039
+ scriptPath ,
1040
+ this . powerShellContext . CurrentRunspace ) ;
1091
1041
1092
1042
if ( mappedPath == null )
1093
1043
{
0 commit comments