public void SetInfo(string p, SyncStat f) { FileSystemInfo pfi = new FileInfo(p); if ((f.Attributes & FileAttributes.Directory) == FileAttributes.Directory) { pfi = new DirectoryInfo(p); } pfi.CreationTimeUtc = f.CreationTimeUtc; pfi.LastWriteTimeUtc = f.LastWriteTimeUtc; pfi.Attributes = f.Attributes; // it appears that you can no longer set the times on a file if the read only bit is set even though we set it. }
public void SetInfo(string p, SyncStat f) { Pipeline pipe = session.Runspace.CreatePipeline(); string cc = @" $f=get-item -force ""{0}"" $f.CreationTimeUtc=[System.DateTime]::FromFileTimeUtc(""{1}"") $f.LastWriteTimeUtc=[System.DateTime]::FromFileTimeUtc(""{2}"") $f.Attributes=""{3}"" "; string command = string.Format(cc, p, f.CreationTimeUtc.ToFileTimeUtc(), f.LastWriteTimeUtc.ToFileTimeUtc(), f.Attributes ); pipe.Commands.AddScript(command); pipe.Invoke(); pipe.Dispose(); }
protected void copy(string srcFile, string dstFile, ProgressRecord prog) { Int64 bytesxfered = 0; Int32 block = 0; Byte[] b; SyncStat srcInfo = src.GetInfo(srcFile); // check for reparse point. SyncStat dstInfo; try { dstInfo = dst.GetInfo(dstFile); } catch { dstInfo = new SyncStat(); } // do some clever compare do { WriteDebug("Do Block copy: " + block); bool copyBlock = true; if (dstInfo.Exists) { // doesn't look very clever to me string srcHash; try { srcHash = src.HashBlock(srcFile, block); // we should worry if this throws an error } catch (Exception e) { // uh oh throw (new IOException("Unable to read Source", e)); } try { string dstHash = dst.HashBlock(dstFile, block); if (srcHash.Equals(dstHash)) { copyBlock = false; } } catch { copyBlock = true; } } WriteDebug("will copy block: " + copyBlock); if (copyBlock) { // try // { b = src.ReadBlock(srcFile, block); // throw error report file failure dst.WriteBlock(dstFile, block, b); // } catch (Exception e) // { // WriteWarning("Copy Error: " + srcFile + " -> " + dstFile); // WriteWarning("Attributes: " + srcInfo.Attributes); // throw new IOException("Error Copying File",e); // } } if (bytesxfered + LocalIO.g_blocksize > srcInfo.Length) { bytesxfered = srcInfo.Length; } else { bytesxfered += LocalIO.g_blocksize; } // update progress if (prog != null) { prog.PercentComplete = 100; // Console.WriteLine(String.Format("{0} {1}", bytesxfered, srcInfo.Length)); // add b/s and eta if (srcInfo.Length != 0) { prog.PercentComplete = (int)(100 * bytesxfered / srcInfo.Length); } WriteProgress(prog); } block++; } while (bytesxfered < srcInfo.Length); }
// Override the ProcessRecord method to process // the supplied user name and write out a // greeting to the user by calling the WriteObject // method. protected override void ProcessRecord() { Collection <string> filelist; ProgressRecord prog = null; try { // string curPath = this.SessionState.Path.CurrentFileSystemLocation.ToString(); //System.IO.Directory.GetCurrentDirectory(); // Determine if path and target are rel or abs string abssrc; string absdst; // this decision tree is getting a bit large // also check for UNC paths if (!path.Contains(":\\") && !(path.StartsWith("\\\\"))) { if (fromsession != null) { src = new RemoteIO(fromsession); } else { src = new LocalIO(this.SessionState); } // relative path abssrc = System.IO.Path.Combine(src.GetCwd(), path); // cannot have unc relative paths } else { if (path.StartsWith("\\\\")) { if (credential != null) { if (fromsession != null) { // but maybe we're supplying credentials for the destination? check dst UNC abs path if (target.StartsWith("\\\\") && ToSession == null) { src = new RemoteIO(fromsession); } else { WriteDebug("only local unc paths..."); throw new ArgumentException("Only Local UNC Paths can have Credentials"); } } else { src = new LocalIO(this.SessionState, credential, path); } } else { if (fromsession != null) { src = new RemoteIO(fromsession); } else { src = new LocalIO(this.SessionState); } } } else { if (fromsession != null) { src = new RemoteIO(fromsession); } else { src = new LocalIO(this.SessionState); } } // ProviderInfo pi; abssrc = GetUnresolvedProviderPathFromPSPath(path); } // I can't do a remote session authentication (maybe yet) if (!target.Contains(":\\") && !(target.StartsWith("\\\\"))) { if (tosession != null) { dst = new RemoteIO(tosession); } else { dst = new LocalIO(this.SessionState); } string dstcwd = dst.GetCwd(); if (dstcwd.Length == 0) { throw new DirectoryNotFoundException("Cannot get destination CWD"); } WriteDebug("Dst cwd:" + dstcwd); absdst = System.IO.Path.Combine(dstcwd, target); } else { if (target.StartsWith("\\\\")) { if (credential != null) { if (tosession != null) { if (path.StartsWith("\\\\") && FromSession == null) { dst = new RemoteIO(tosession); } else { throw new ArgumentException("Only Local UNC Paths can have Credentials"); } } else { dst = new LocalIO(this.SessionState, credential, path); } } else { if (tosession != null) { dst = new RemoteIO(tosession); } else { dst = new LocalIO(this.SessionState); } } } else { if (tosession != null) { dst = new RemoteIO(tosession); } else { dst = new LocalIO(this.SessionState); } } absdst = GetUnresolvedProviderPathFromPSPath(target); } WriteDebug("SOURCE: " + abssrc); SyncStat srcType = src.GetInfo(abssrc); if (!srcType.Exists) { throw (new System.IO.FileNotFoundException()); // fatal error, goodbye } if (srcType.isDir()) { if (!abssrc.EndsWith("\\")) { abssrc += "\\"; } if (!absdst.EndsWith("\\")) { absdst += "\\"; } try { SyncStat ss = dst.GetInfo(absdst); // throws a cast exception if (!ss.Exists) { WriteVerbose(absdst); dst.MakeDir(absdst); } else { WriteVerbose("Target Dir Exists " + absdst); WriteDebug("Directory exists"); // check for delete if (delete) { WriteDebug("will delete"); Collection <string> dstfilelist = dst.ReadDir(absdst); for (int i = dstfilelist.Count - 1; i >= 0; i--) // foreach (string file in dstfilelist) { string file = dstfilelist[i]; if (progress) { prog = new ProgressRecord(1, file, "Deleting"); } string srcfile = ""; string relfile = ""; string dstfile = ""; try { relfile = MakeRelativePath(absdst, file); // WriteDebug(String.Format("MakeRelativePath {0} -> {1} = {2}\n", file, absdst, relfile)); srcfile = System.IO.Path.Combine(abssrc, relfile); dstfile = System.IO.Path.Combine(absdst, relfile); SyncStat sss = src.GetInfo(srcfile); // throws if not found /* * if (!sss.Exists) * { * WriteVerbose("Deleting: " + relfile); * WriteDebug("abs :" + dstfile); * dst.Delete(dstfile); * } */ } catch (Exception e) { // must delete files first. WriteVerbose("Deleting: " + relfile); WriteDebug("abs :" + dstfile); try { dst.Delete(dstfile); } catch (Exception ex) { WriteDebug("Cannot delete: " + ex.ToString()); } WriteDebug("file not found: " + srcfile + " : " + e.ToString()); } } } } } catch (Exception e) // remote throws different exception to local { WriteDebug(e.Message); WriteDebug(e.StackTrace); WriteDebug(String.Format("exception MakeDir {0}", absdst)); WriteVerbose(absdst); dst.MakeDir(absdst); } filelist = src.ReadDir(abssrc); } else { filelist = new Collection <string> { abssrc }; abssrc = System.IO.Path.GetDirectoryName(abssrc); if (!abssrc.EndsWith("\\")) { abssrc += "\\"; } } // Determine if src is file or dir // is target absolute or relative // get dst cwd if (!absdst.EndsWith("\\")) { absdst += "\\"; } WriteDebug(String.Format("Arguments {0} -> {1}\n", abssrc, absdst)); if (progress) { prog = new ProgressRecord(1, abssrc, "Copying"); } int count = 0; foreach (string file in filelist) { bool include = true; // add include / exclude if (includeList != null) { include = false; foreach (string m in includeList) { if (LikeOperator.LikeString(file, m, Microsoft.VisualBasic.CompareMethod.Text)) { include = true; } } } if (excludeList != null) { foreach (string m in excludeList) { if (LikeOperator.LikeString(file, m, Microsoft.VisualBasic.CompareMethod.Text)) { include = false; } } } count++; if (include) { if (progress) { prog = new ProgressRecord(1, file, "Copying"); } try { string relfile = MakeRelativePath(abssrc, file); WriteDebug(String.Format("MakeRelativePath {0} -> {1} = {2}\n", file, abssrc, relfile)); string dstfile = System.IO.Path.Combine(absdst, relfile); SyncStat srcInfo = src.GetInfo(file); // may throw // sometimes getting nulls if (srcInfo.isReparsePoint()) { // TODO: copy reparse point to dst } else if (srcInfo.isDir()) { WriteDebug(String.Format("src isDir: {0}", file)); try { SyncStat ss = dst.GetInfo(dstfile); if (!ss.Exists) { WriteVerbose(relfile); dst.MakeDir(dstfile); } else { WriteVerbose(String.Format("{0}/{1} SKIPPING {2}", count, filelist.Count, relfile)); WriteDebug("Directory Exists"); } } catch (Exception) { WriteVerbose(relfile); dst.MakeDir(dstfile); } } else { // FileInfo srcfInfo = (FileInfo)srcInfo; WriteDebug(String.Format("Compare and Copy from {1} to {0}", dstfile, file)); // check if dst exists // compare relfile SyncStat dstInfo; try { dstInfo = dst.GetInfo(dstfile); // don't care if throws if (!dstInfo.Exists) { WriteVerbose(relfile); WriteDebug("COPY NEW"); if (progress) { prog = new ProgressRecord(1, file, "Copying"); prog.StatusDescription = String.Format("Copying {0}/{1}", count, filelist.Count); } copy(file, dstfile, prog); } else if (srcInfo.Length != dstInfo.Length) { WriteVerbose(relfile); WriteDebug("COPY UPDATE (length)"); if (progress) { prog = new ProgressRecord(1, file, "Copying"); prog.StatusDescription = String.Format("Copying {0}/{1}", count, filelist.Count); } copy(file, dstfile, prog); } else if (Checksum) // if checksum specified check on chksum rather than length and date. but different length should be a dead giveaway. { // WriteVerbose(relfile); WriteDebug("UPDATE (checksum)"); if (progress) { prog = new ProgressRecord(1, file, "Checking"); prog.StatusDescription = String.Format("Checking {0}/{1}", count, filelist.Count); prog.PercentComplete = 0; WriteProgress(prog); } // these can be done simultaneously... especially if one or both are on a remote machine. string srcHash = src.HashTotal(file); if (progress) { prog.PercentComplete = 50; WriteProgress(prog); } string dstHash = dst.HashTotal(dstfile); if (progress) { prog.PercentComplete = 100; WriteProgress(prog); } if (!srcHash.Equals(dstHash)) { WriteVerbose(relfile); WriteDebug(String.Format("COPY UPDATE. file hash mismatch: {0} <-> {1}", srcHash, dstHash)); // WriteDebug("COPY update hash"); if (progress) { prog = new ProgressRecord(1, file, "Copying"); prog.StatusDescription = String.Format("Copying {0}/{1}", count, filelist.Count); } copy(file, dstfile, prog); } else { WriteVerbose(String.Format("{0}/{1} SKIPPING {2}", count, filelist.Count, relfile)); WriteDebug("File hash match"); } } else if (srcInfo.LastWriteTimeUtc > dstInfo.LastWriteTimeUtc) { WriteVerbose(relfile); WriteDebug("COPY UPDATE (date)"); if (progress) { prog = new ProgressRecord(1, file, "Copying"); prog.StatusDescription = String.Format("Copying {0}/{1}", count, filelist.Count); } copy(file, dstfile, prog); } else { if (progress && this.MyInvocation.BoundParameters.ContainsKey("Verbose")) { prog.RecordType = ProgressRecordType.Completed; } WriteVerbose(String.Format("{0}/{1} SKIPPING {2}", count, filelist.Count, relfile)); WriteDebug("Date-length match"); } } catch (Exception e) { WriteDebug("CHECK : " + file + " : " + e.GetType().ToString() + " : " + e.Message); // could be a destination not exist WriteVerbose(relfile); WriteDebug("COPY NEW"); if (progress) { WriteDebug("Setup Progress"); prog = new ProgressRecord(1, file, "Copying"); prog.StatusDescription = String.Format("Copying {0}/{1}", count, filelist.Count); } copy(file, dstfile, prog); /* * WriteVerbose(String.Format("{0} -> {1}\n", relfile, absdst)); * WriteVerbose(e.Message); * WriteVerbose(e.StackTrace); * * ErrorRecord er = new ErrorRecord(e, "CopyNew", ErrorCategory.InvalidOperation, null); * WriteError(er); * * WriteDebug(e.Message); * WriteDebug(e.StackTrace); * WriteDebug("COPY NEW Exception"); */ } } //optional sync attributes and dates dst.SetInfo(dstfile, srcInfo); // TODO: copy acl } catch (Exception e) { // WriteWarning("" + file + " : " + e.Message); // WriteWarning(e.StackTrace); ErrorRecord er = new ErrorRecord(e, "FileCopy", ErrorCategory.ReadError, null); WriteError(er); } if (progress && !this.MyInvocation.BoundParameters.ContainsKey("Verbose")) { prog.PercentComplete = 100; prog.StatusDescription = String.Format("Copying {0}/{1}", count, filelist.Count); WriteProgress(prog); } } } } catch (Exception e) { WriteWarning("Fatal Error"); WriteDebug(e.Message); WriteDebug(e.StackTrace); ErrorRecord er = new ErrorRecord(e, "TopLevel", ErrorCategory.ObjectNotFound, null); WriteError(er); } }