|
12 | 12 | using System.Linq;
|
13 | 13 | using System.Management.Automation;
|
14 | 14 | using System.Management.Automation.Runspaces;
|
| 15 | +using System.Text; |
15 | 16 | using System.Threading.Tasks;
|
16 | 17 |
|
17 | 18 | namespace Microsoft.PowerShell.EditorServices.Session
|
@@ -77,6 +78,15 @@ public class RemoteFileManager
|
77 | 78 | Get-EventSubscriber -SourceIdentifier PSESRemoteSessionOpenFile -EA Ignore | Remove-Event
|
78 | 79 | ";
|
79 | 80 |
|
| 81 | + private const string SetRemoteContentsScript = @" |
| 82 | + param( |
| 83 | + [string] $RemoteFilePath, |
| 84 | + [byte[]] $Content |
| 85 | + ) |
| 86 | +
|
| 87 | + Set-Content -Path $RemoteFilePath -Value $Content -Encoding Byte -Force 2>&1 |
| 88 | + "; |
| 89 | + |
80 | 90 | #endregion
|
81 | 91 |
|
82 | 92 | #region Constructors
|
@@ -185,6 +195,61 @@ public async Task<string> FetchRemoteFile(
|
185 | 195 | return localFilePath;
|
186 | 196 | }
|
187 | 197 |
|
| 198 | + /// <summary> |
| 199 | + /// Saves the contents of the file under the temporary local |
| 200 | + /// file cache to its corresponding remote file. |
| 201 | + /// </summary> |
| 202 | + /// <param name="localFilePath"> |
| 203 | + /// The local file whose contents will be saved. It is assumed |
| 204 | + /// that the editor has saved the contents of the local cache |
| 205 | + /// file to disk before this method is called. |
| 206 | + /// </param> |
| 207 | + /// <returns>A Task to be awaited for completion.</returns> |
| 208 | + public async Task SaveRemoteFile(string localFilePath) |
| 209 | + { |
| 210 | + string remoteFilePath = |
| 211 | + this.GetMappedPath( |
| 212 | + localFilePath, |
| 213 | + this.powerShellContext.CurrentRunspace); |
| 214 | + |
| 215 | + Logger.Write( |
| 216 | + LogLevel.Verbose, |
| 217 | + $"Saving remote file {remoteFilePath} (local path: {localFilePath})"); |
| 218 | + |
| 219 | + byte[] localFileContents = null; |
| 220 | + try |
| 221 | + { |
| 222 | + localFileContents = File.ReadAllBytes(localFilePath); |
| 223 | + } |
| 224 | + catch (IOException e) |
| 225 | + { |
| 226 | + Logger.WriteException( |
| 227 | + "Failed to read contents of local copy of remote file", |
| 228 | + e); |
| 229 | + |
| 230 | + return; |
| 231 | + } |
| 232 | + |
| 233 | + PSCommand saveCommand = new PSCommand(); |
| 234 | + saveCommand |
| 235 | + .AddScript(SetRemoteContentsScript) |
| 236 | + .AddParameter("RemoteFilePath", remoteFilePath) |
| 237 | + .AddParameter("Content", localFileContents); |
| 238 | + |
| 239 | + StringBuilder errorMessages = new StringBuilder(); |
| 240 | + |
| 241 | + await this.powerShellContext.ExecuteCommand<object>( |
| 242 | + saveCommand, |
| 243 | + errorMessages, |
| 244 | + false, |
| 245 | + false); |
| 246 | + |
| 247 | + if (errorMessages.Length > 0) |
| 248 | + { |
| 249 | + Logger.Write(LogLevel.Error, $"Remote file save failed due to an error:\r\n\r\n{errorMessages}"); |
| 250 | + } |
| 251 | + } |
| 252 | + |
188 | 253 | /// <summary>
|
189 | 254 | /// Creates a temporary file with the given name and contents
|
190 | 255 | /// corresponding to the specified runspace.
|
|
0 commit comments