Beispiel #1
0
        /// <summary>
        /// Attempts to copy local files from the local filesystem to the selected remote target path
        /// </summary>
        /// <param name="files">An array containing full paths to files and or folders to copy</param>
        /// <param name="target">The target path on the remote system</param>
        /// <param name="callback">A callback to fire on success or error. On failure the files parameter will be null</param>
        public void BeginCopyFiles(string[] files, string target, TransferUpdateCallback callback)
        {
            if (String.IsNullOrEmpty(m_Session.Username))
            {
                if (m_Login.ShowDialog(SuperPuTTY.MainForm) == System.Windows.Forms.DialogResult.OK)
                {
                    m_Session.Username = m_Login.Username;
                    m_Session.Password = m_Login.Password;
                }
            }

            // put the copy operation in the background since it could take a long long time
            m_PscpThread = new Thread(delegate()
            {
                Process processCopyToRemote = new Process();
                try
                {
                    processCopyToRemote.EnableRaisingEvents = true;
                    processCopyToRemote.StartInfo.RedirectStandardError = true;
                    processCopyToRemote.StartInfo.RedirectStandardInput = true;
                    processCopyToRemote.StartInfo.RedirectStandardOutput = true;
                    processCopyToRemote.StartInfo.FileName = SuperPuTTY.Settings.PscpExe;
                    processCopyToRemote.StartInfo.CreateNoWindow = true;
                    // process the various options from the session object and convert them into arguments pscp can understand
                    string args = "-r -agent "; // default arguments
                    args += (!String.IsNullOrEmpty(m_Session.PuttySession)) ? "-load \"" + m_Session.PuttySession + "\" " : "";
                    //args += "-l " + Session.Username + " ";
                    args += (!String.IsNullOrEmpty(m_Session.Password) && m_Session.Password.Length > 0) ? "-pw " + m_Session.Password + " " : "";
                    args += "-P " + m_Session.Port + " ";
                    args += "\"" + files[0] + "\" ";
                    args += (!String.IsNullOrEmpty(m_Session.Username)) ? m_Session.Username + "@" : "";
                    args += m_Session.Host + ":" + target;
                    Logger.Log("Args: '{0} {1}'", processCopyToRemote.StartInfo.FileName, args);
                    processCopyToRemote.StartInfo.Arguments = args;
                    processCopyToRemote.StartInfo.UseShellExecute = false;

                    processCopyToRemote.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e)
                    {
                        if (!String.IsNullOrEmpty(e.Data))
                        {
                            Match match = Regex.Match(e.Data.TrimEnd(), ".*|.*|.*|.*|.*");
                            if (match.Success)
                            {
                                if (callback != null)
                                {
                                    FileTransferStatus status = new FileTransferStatus();
                                    string[] update = e.Data.TrimEnd().Split('|');
                                    status.Filename = update[0].Trim();
                                    status.BytesTransferred = int.Parse(update[1].Replace("kB", "").Trim());
                                    status.TransferRate = float.Parse(update[2].Replace("kB/s", "").Trim());
                                    status.TimeLeft = update[3].Replace("ETA:", "").Trim();
                                    status.PercentComplete = int.Parse(update[4].Replace("%", "").Trim());
                                    //Logger.Log("File Transfer Data: " + e.Data);
                                    callback(status.PercentComplete.Equals(100), false, status);
                                }
                            }
                            else
                            {
                                Logger.Log("Unable to parse OutputData: {0}", e.Data.TrimEnd());
                            }
                        }
                    };

                    processCopyToRemote.Start();
                    processCopyToRemote.BeginOutputReadLine();
                    processCopyToRemote.WaitForExit();
                }
                catch (ThreadAbortException)
                {
                    if(!processCopyToRemote.HasExited)
                        processCopyToRemote.Kill();
                }
            });

            m_PscpThread.IsBackground = true;
            m_PscpThread.Name = "File Upload";
            m_PscpThread.Start();
        }
Beispiel #2
0
        /// <summary>
        /// Copy files
        /// </summary>
        /// <param name="sourceFiles"></param>
        /// <param name="target"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        public FileTransferResult CopyFiles(List<BrowserFileInfo> sourceFiles, BrowserFileInfo target, TransferUpdateCallback callback)
        {
            lock(this)
            {
                /// Known Issues:
                /// - If a large exe (or other file that the OS will virus scan) is tranfered, the operation will timeout.
                ///   After completion, the OS seems to block on the final write (while scanning).  During this time the process looks like it's
                ///   hanging and the timeout logic kicks in.  Hacked in "completed" logic into inlineOut/Err handlers but this is awkward

                FileTransferResult result = new FileTransferResult();

                string args = ToArgs(this.Session, this.Session.Password, sourceFiles, target);
                string argsToLog = ToArgs(this.Session, "XXXXX", sourceFiles, target);
                ScpLineParser parser = new ScpLineParser();
                RunPscp(
                    result, args, argsToLog,
                    (line) =>
                    {
                        bool completed = false;
                        if (callback != null)
                        {
                            FileTransferStatus status;
                            if (parser.TryParseTransferStatus(line, out status))
                            {
                                completed = status.PercentComplete == 100;
                                callback(completed, false, status);
                            }
                        }
                        return completed;
                    },
                    null, null);

                return result;
            }
        }