/// <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); } }
void DoTransfer() { try { PscpClient client = new PscpClient(this.Options, this.Request.Session); int estSizeKB = Int32.MaxValue; FileTransferResult res = client.CopyFiles( this.Request.SourceFiles, this.Request.TargetFile, (complete, cancelAll, s) => { string msg; if (s.PercentComplete > 0) { estSizeKB = Math.Min(estSizeKB, s.BytesTransferred * 100 / s.PercentComplete); string units = estSizeKB > 1024 * 10 ? "MB" : "KB"; int divisor = units == "MB" ? 1024 : 1; msg = string.Format( "{0}, ({1} of {2} {3}, {4})", s.Filename, s.BytesTransferred / divisor, estSizeKB / divisor, units, s.TimeLeft); } else { // < 1% completed msg = string.Format("{0}, ({1} KB, {2})", s.Filename, s.BytesTransferred, s.TimeLeft); } this.UpdateStatus(s.PercentComplete, Status.Running, msg); }); this.EndTime = DateTime.Now; switch (res.StatusCode) { case ResultStatusCode.Success: double duration = (EndTime.Value - StartTime.Value).TotalSeconds; this.UpdateStatus(100, Status.Complete, String.Format("Duration {0:#,###} s", duration)); break; case ResultStatusCode.RetryAuthentication: case ResultStatusCode.Error: this.UpdateStatus(this.PercentComplete, Status.Error, res.ErrorMsg); break; } } catch (ThreadAbortException) { this.UpdateStatus(this.PercentComplete, Status.Canceled, ""); } catch (Exception ex) { Log.Error("Error running transfer, id=" + this.Id, ex); this.UpdateStatus(0, Status.Error, ex.Message); } }
/// <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; } }