private void StoreRemoteFile(
     string localFilePath,
     byte[] fileContent,
     RemotePathMappings pathMappings)
 {
     File.WriteAllBytes(localFilePath, fileContent);
     pathMappings.AddOpenedLocalPath(localFilePath);
 }
        /// <summary>
        /// For a remote or local cache path, get the corresponding local or
        /// remote file path.
        /// </summary>
        /// <param name="filePath">
        /// The remote or local file path.
        /// </param>
        /// <param name="runspaceDetails">
        /// The runspace from which the remote file was fetched.
        /// </param>
        /// <returns>The mapped file path.</returns>
        public string GetMappedPath(
            string filePath,
            RunspaceDetails runspaceDetails)
        {
            RemotePathMappings remotePathMappings = this.GetPathMappings(runspaceDetails);

            return(remotePathMappings.GetMappedPath(filePath));
        }
        private RemotePathMappings GetPathMappings(RunspaceDetails runspaceDetails)
        {
            RemotePathMappings remotePathMappings = null;

            if (!this.filesPerRunspace.TryGetValue(runspaceDetails, out remotePathMappings))
            {
                remotePathMappings = new RemotePathMappings(runspaceDetails, this);
                this.filesPerRunspace.Add(runspaceDetails, remotePathMappings);
            }

            return(remotePathMappings);
        }
        /// <summary>
        /// Opens a remote file, fetching its contents if necessary.
        /// </summary>
        /// <param name="remoteFilePath">
        /// The remote file path to be opened.
        /// </param>
        /// <param name="runspaceDetails">
        /// The runspace from which where the remote file will be fetched.
        /// </param>
        /// <returns>
        /// The local file path where the remote file's contents have been stored.
        /// </returns>
        public async Task <string> FetchRemoteFile(
            string remoteFilePath,
            RunspaceDetails runspaceDetails)
        {
            string localFilePath = null;

            if (!string.IsNullOrEmpty(remoteFilePath))
            {
                try
                {
                    RemotePathMappings pathMappings = this.GetPathMappings(runspaceDetails);
                    localFilePath = this.GetMappedPath(remoteFilePath, runspaceDetails);

                    if (!pathMappings.IsRemotePathOpened(remoteFilePath))
                    {
                        // Does the local file already exist?
                        if (!File.Exists(localFilePath))
                        {
                            // Load the file contents from the remote machine and create the buffer
                            PSCommand command = new PSCommand();
                            command.AddCommand("Microsoft.PowerShell.Management\\Get-Content");
                            command.AddParameter("Path", remoteFilePath);
                            command.AddParameter("Raw");
                            command.AddParameter("Encoding", "Byte");

                            byte[] fileContent =
                                (await this.powerShellContext.ExecuteCommand <byte[]>(command, false, false))
                                .FirstOrDefault();

                            if (fileContent != null)
                            {
                                this.StoreRemoteFile(localFilePath, fileContent, pathMappings);
                            }
                            else
                            {
                                this.logger.Write(
                                    LogLevel.Warning,
                                    $"Could not load contents of remote file '{remoteFilePath}'");
                            }
                        }
                    }
                }
                catch (IOException e)
                {
                    this.logger.Write(
                        LogLevel.Error,
                        $"Caught {e.GetType().Name} while attempting to get remote file at path '{remoteFilePath}'\r\n\r\n{e.ToString()}");
                }
            }

            return(localFilePath);
        }
        private RemotePathMappings GetPathMappings(RunspaceDetails runspaceDetails)
        {
            RemotePathMappings remotePathMappings = null;
            string             computerName       = runspaceDetails.SessionDetails.ComputerName;

            if (!this.filesPerComputer.TryGetValue(computerName, out remotePathMappings))
            {
                remotePathMappings = new RemotePathMappings(runspaceDetails, this);
                this.filesPerComputer.Add(computerName, remotePathMappings);
            }

            return(remotePathMappings);
        }
        private string StoreRemoteFile(
            string remoteFilePath,
            byte[] fileContent,
            RunspaceDetails runspaceDetails)
        {
            RemotePathMappings pathMappings  = this.GetPathMappings(runspaceDetails);
            string             localFilePath = pathMappings.GetMappedPath(remoteFilePath);

            this.StoreRemoteFile(
                localFilePath,
                fileContent,
                pathMappings);

            return(localFilePath);
        }
        /// <summary>
        /// Creates a temporary file with the given name and contents
        /// corresponding to the specified runspace.
        /// </summary>
        /// <param name="fileName">
        /// The name of the file to be created under the session path.
        /// </param>
        /// <param name="fileContents">
        /// The contents of the file to be created.
        /// </param>
        /// <param name="runspaceDetails">
        /// The runspace for which the temporary file relates.
        /// </param>
        /// <returns>The full temporary path of the file if successful, null otherwise.</returns>
        public string CreateTemporaryFile(string fileName, string fileContents, RunspaceDetails runspaceDetails)
        {
            string temporaryFilePath = Path.Combine(this.processTempPath, fileName);

            try
            {
                File.WriteAllText(temporaryFilePath, fileContents);

                RemotePathMappings pathMappings = this.GetPathMappings(runspaceDetails);
                pathMappings.AddOpenedLocalPath(temporaryFilePath);
            }
            catch (IOException e)
            {
                this.logger.LogError(
                    $"Caught {e.GetType().Name} while attempting to write temporary file at path '{temporaryFilePath}'\r\n\r\n{e.ToString()}");

                temporaryFilePath = null;
            }

            return(temporaryFilePath);
        }