private static void CopyContainer(CloudBlobDirectory sourceDirectory, CloudBlobDirectory destDirectory) { // This function copies an entire Storage container using the data movement library. // See https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.storage.datamovement.copydirectoryoptions?view=azure-dotnet for the API // and https://docs.microsoft.com/en-us/azure/storage/common/storage-use-data-movement-library for a general overview. ProgressRecorder recorder = new ProgressRecorder(); Stopwatch stopWatch = Stopwatch.StartNew(); CopyDirectoryOptions copyDirectoryOptions = new CopyDirectoryOptions { // Needs to be true to copy the contents of the directory / container. If this is false the contents will // not be copied. Recursive = true }; // Copy all files under root folder DirectoryTransferContext context = new DirectoryTransferContext { ProgressHandler = recorder }; TransferStatus copyStatus = TransferManager.CopyDirectoryAsync(sourceDirectory, destDirectory, CopyMethod.ServiceSideAsyncCopy, copyDirectoryOptions, context).Result; stopWatch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = stopWatch.Elapsed; // Format and display the TimeSpan value. string elapsedTime = string.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine($"Elapsed:{elapsedTime} T File transferred: {copyStatus.NumberOfFilesTransferred} total bytes:{copyStatus.BytesTransferred}, failed: {copyStatus.NumberOfFilesFailed}, skipped:{copyStatus.NumberOfFilesSkipped}"); }
private static async Task BlobDirectoryCopySample() { var sourceBlobDir = await Util.GetCloudBlobDirectoryAsync("sourcecontainer", "dir1"); var destBlobDir = await Util.GetCloudBlobDirectoryAsync("targetcontainer", "dir2"); var options = new CopyDirectoryOptions() { Recursive = true, }; var context = new DirectoryTransferContext(); context.FileTransferred += FileTransferredCallback; context.FileFailed += FileFailedCallback; context.FileSkipped += FileSkippedCallback; TransferManager.Configurations.ParallelOperations = 50; Console.WriteLine("Transfer started"); try { Task task = TransferManager.CopyDirectoryAsync(sourceBlobDir, destBlobDir, false, options, context); await task; } catch (Exception e) { Console.WriteLine("The transfer is cancelled: {0}", e.Message); } Console.WriteLine("The transfer is completed."); }
private async static Task CopyDirectoryAsync(string jobId, CloudBlobDirectory sourceDirectory, CloudBlobDirectory destinationDirectory, CopyDirectoryOptions copyDirectoryOptions, TransferContext transferContext, TransferCheckpoint transferCheckpoint, CancellationTokenSource cancellationTokenSource) { // Start the transfer try { await TransferManager.CopyDirectoryAsync( sourceBlobDir : sourceDirectory, destBlobDir : destinationDirectory, isServiceCopy : false, options : copyDirectoryOptions, context : transferContext, cancellationToken : cancellationTokenSource.Token); // Store the transfer checkpoint to record the completed copy operation transferCheckpoint = transferContext.LastCheckpoint; } catch (TransferException) { // Swallow all transfer exceptions here. Files skipped in the OverwriteCallback throw an exception here // even in an Incremental copy where the source is skipped because it and destination are identical // Instead all exceptions from transfers are handled in the FileFailed event handler. } catch (Exception ex) { // Fatal or other exceptions resulting in the transfer being cancelled will still appear here // Save a Checkpoint so we can restart the transfer transferCheckpoint = transferContext.LastCheckpoint; SaveTransferCheckpoint(jobId, transferCheckpoint); throw new Exception("Error in CopyDirectoryAsync(): " + ex.Message); } }
private async static Task CopyDirectoryAsync(CloudBlobDirectory sourceDirectory, CloudBlobDirectory destinationDirectory, CopyDirectoryOptions copyDirectoryOptions, TransferContext transferContext, TransferCheckpoint transferCheckpoint, CancellationTokenSource cancellationTokenSource) { // Start the transfer try { await TransferManager.CopyDirectoryAsync( sourceBlobDir : sourceDirectory, destBlobDir : destinationDirectory, isServiceCopy : true, options : copyDirectoryOptions, context : transferContext, cancellationToken : cancellationTokenSource.Token); // Store the transfer checkpoint. transferCheckpoint = transferContext.LastCheckpoint; } catch (TransferException te) { // Swallow Exceptions from skipped files in Overwrite Callback // Log any other Transfer Exceptions if (te.ErrorCode != TransferErrorCode.SubTransferFails) { StringBuilder sb = new StringBuilder(); sb.AppendLine("Transfer Error: " + te.Message); sb.AppendLine("Transfer Error Code: " + te.ErrorCode); await _log.WriteLineAsync(sb.ToString()); } } }
public void TestFileShareSnapshotsCopyToBase() { int fileCount = 3; string snapshotFile = "snapshotFile"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); sourceDataInfo.IsFileShareSnapshot = true; DMLibDataHelper.AddMultipleFiles(sourceDataInfo.RootNode, snapshotFile, fileCount, 1024); SourceAdaptor.Cleanup(); SourceAdaptor.CreateIfNotExists(); SourceAdaptor.GenerateData(sourceDataInfo); CloudFileDataAdaptor fileAdaptor = (SourceAdaptor as CloudFileDataAdaptor); CloudFileDirectory SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, sourceDataInfo.RootNode) as CloudFileDirectory; CloudFileDirectory DestObject = fileAdaptor.fileHelper.FileClient.GetShareReference(fileAdaptor.ShareName).GetRootDirectoryReference(); // transfer File and finished succssfully Task <TransferStatus> task = TransferManager.CopyDirectoryAsync( SourceObject, DestObject, DMLibTestContext.IsAsync, new CopyDirectoryOptions() { Recursive = true }, new DirectoryTransferContext() { ShouldOverwriteCallbackAsync = TransferContext.ForceOverwrite }); Test.Assert(task.Wait(15 * 60 * 100), "Tansfer finished in time."); Test.Assert(task.Result.NumberOfFilesFailed == 0, "No Failed File."); Test.Assert(task.Result.NumberOfFilesSkipped == 0, "No Skipped File."); Test.Assert(task.Result.NumberOfFilesTransferred == fileCount, string.Format("Transferred file :{0} == {1}", task.Result.NumberOfFilesTransferred, fileCount)); // verify that Files in Share Snapshot is transferred IEnumerable <IListFileItem> sourceFiles = SourceObject.ListFilesAndDirectories(HelperConst.DefaultFileOptions); foreach (IListFileItem item in sourceFiles) { if (item is CloudFile) { CloudFile srcFile = item as CloudFile; CloudFile destFile = DestObject.GetFileReference(srcFile.Name); srcFile.FetchAttributes(); destFile.FetchAttributes(); Test.Assert(srcFile.Properties.ContentMD5 == destFile.Properties.ContentMD5, string.Format("File {0} MD5 :{1} == {2}", srcFile.Name, srcFile.Properties.ContentMD5, destFile.Properties.ContentMD5)); } } }
public async Task <List <BlobInfo> > CopyDirectory( IBlobContainer sourceContainerName, string sourceDirectoryPath, IBlobContainer destinationContainerName, string destinationDirectoryPath, IBlobStorageService.CopyDirectoryOptions?options = null) { _logger.LogInformation( "Copying directory from {0}/{1} to {2}/{3}", sourceContainerName, sourceDirectoryPath, destinationContainerName, destinationDirectoryPath ); var sourceContainer = await GetCloudBlobContainer(sourceContainerName); var destinationContainer = await GetCloudBlobContainer( destinationContainerName, connectionString : options?.DestinationConnectionString ); var sourceDirectory = sourceContainer.GetDirectoryReference(sourceDirectoryPath); var destinationDirectory = destinationContainer.GetDirectoryReference(destinationDirectoryPath); var copyDirectoryOptions = new CopyDirectoryOptions { Recursive = true }; var filesTransferred = new List <BlobInfo>(); var context = new DirectoryTransferContext(); context.FileTransferred += (sender, args) => FileTransferredCallback(sender, args, filesTransferred); context.FileFailed += FileFailedCallback; context.FileSkipped += FileSkippedCallback; context.SetAttributesCallbackAsync += options?.SetAttributesCallbackAsync; context.ShouldTransferCallbackAsync += options?.ShouldTransferCallbackAsync; context.ShouldOverwriteCallbackAsync += options?.ShouldOverwriteCallbackAsync; await TransferManager.CopyDirectoryAsync( sourceDirectory, destinationDirectory, CopyMethod.ServiceSideAsyncCopy, copyDirectoryOptions, context ); return(filesTransferred); }
private Task <TransferStatus> CopyDirectory(dynamic sourceObject, dynamic destObject, TransferItem item) { CopyDirectoryOptions copyDirectoryOptions = item.Options as CopyDirectoryOptions; DirectoryTransferContext transferContext = item.TransferContext as DirectoryTransferContext; CancellationToken cancellationToken = item.CancellationToken; if (cancellationToken == null || cancellationToken == CancellationToken.None) { return(TransferManager.CopyDirectoryAsync(sourceObject, destObject, item.IsServiceCopy, copyDirectoryOptions, transferContext)); } else { return(TransferManager.CopyDirectoryAsync(sourceObject, destObject, item.IsServiceCopy, copyDirectoryOptions, transferContext, cancellationToken)); } }
public void TestFileShareSnapshotsDest() { string failError1 = "Failed to validate destination"; string failError2 = "Cannot perform this operation on a share representing a snapshot."; //Prepare Data string snapshotFile = "snapshotFile"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFile(sourceDataInfo.RootNode, snapshotFile, 1024); SourceAdaptor.GenerateData(sourceDataInfo); DMLibDataInfo DestDataInfo = new DMLibDataInfo(string.Empty); DestDataInfo.IsFileShareSnapshot = true; DestAdaptor.GenerateData(DestDataInfo); CloudBlobDirectory SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, sourceDataInfo.RootNode) as CloudBlobDirectory; CloudFileDirectory DestObject = DestAdaptor.GetTransferObject(DestDataInfo.RootPath, DestDataInfo.RootNode) as CloudFileDirectory; // transfer File and failed with expected Error Task <TransferStatus> task = TransferManager.CopyDirectoryAsync( SourceObject, DestObject, DMLibTestContext.IsAsync, new CopyDirectoryOptions() { Recursive = true }, new DirectoryTransferContext() { ShouldOverwriteCallbackAsync = TransferContext.ForceOverwrite }); try { task.Wait(15 * 60 * 100); } catch (Exception e) { Test.Assert(e.InnerException.Message.Contains(failError1), "Tansfer Exception should contain:" + failError1); Test.Assert(e.InnerException.InnerException.Message.Contains(failError2), "Tansfer Exception should contain:" + failError2); } }
/// <summary> /// Moves a folder with its contents to the path given /// </summary> /// <param name="folder"></param> /// <param name="path"></param> /// <returns></returns> public async Task <BlobDto> MoveFolder(BlobDto folder, string path) { var container = await GetContainer(); if (path[path.Length - 1] != '/') { path = path + "/"; } string newPath = $"{path}{folder.Name}"; var sourceBlobDir = container.GetDirectoryReference(folder.Path); var destBlobDir = container.GetDirectoryReference(newPath); TransferManager.Configurations.ParallelOperations = 64; // Setup the transfer context and track the upoload progress DirectoryTransferContext context = new DirectoryTransferContext { ProgressHandler = new Progress <TransferStatus>((progress) => { Console.WriteLine("Bytes uploaded: {0}", progress.BytesTransferred); }) }; var copyDirOptions = new CopyDirectoryOptions { Recursive = true, IncludeSnapshots = true }; await TransferManager.CopyDirectoryAsync(sourceBlobDir, destBlobDir, true, copyDirOptions, context); await DeleteFile(folder.Path); folder.Path = newPath; folder.StoragePath = destBlobDir.Uri.ToString(); folder.DateModified = DateTime.UtcNow; return(folder); }
public async Task RunAsync(CancellationToken cancellationToken = default(CancellationToken)) { var copyDirectoryOptions = new CopyDirectoryOptions { Recursive = true }; var directoryTransferContext = new DirectoryTransferContext { //ProgressHandler = new Progress<TransferStatus>(progress => Log.Trace(() => $"Progress: transferred: {progress.NumberOfFilesTransferred}, failed: {progress.NumberOfFilesFailed}, skipped: {progress.NumberOfFilesSkipped}, bytes transferred: {progress.BytesTransferred}")) }; directoryTransferContext.FileTransferred += (sender, args) => Log.Trace(() => $"Transferred {(args.Source as CloudFile)?.Name} -> {(args.Destination as CloudFile)?.Name}"); directoryTransferContext.FileSkipped += (sender, args) => Log.Trace(() => $"Skipped {(args.Source as CloudFile)?.Name} -> {(args.Destination as CloudFile)?.Name}"); directoryTransferContext.FileFailed += (sender, args) => Log.Error(() => $"Failed {(args.Source as CloudFile)?.Name} -> {(args.Destination as CloudFile)?.Name}"); Log.Info(() => $"Starting server side copy from {this.sourceDirectory.Uri} to {this.targetDirectory.Uri}"); var status = await TransferManager.CopyDirectoryAsync(sourceDirectory, targetDirectory, true, copyDirectoryOptions, directoryTransferContext, cancellationToken); Log.Info(() => $"Finished server side copy, transferred: {status.NumberOfFilesTransferred}, failed: {status.NumberOfFilesFailed}, skipped: {status.NumberOfFilesSkipped}, bytes transferred: {status.BytesTransferred}"); }
static void Main(string[] args) { ServicePointManager.DefaultConnectionLimit = Environment.ProcessorCount * 8; ServicePointManager.Expect100Continue = false; var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("FileStorageConnectionString")); var cloudFileClient = storageAccount.CreateCloudFileClient(); var fileShare = cloudFileClient.GetShareReference("myshare"); var rootDirectory = fileShare.GetRootDirectoryReference(); var directory = rootDirectory.GetDirectoryReference("sourcedir"); var cloudStorageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("BlobStorageConnectionString")); var cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient(); var containerReference = cloudBlobClient.GetContainerReference("myblobcontainer"); var cloudBlobDirectory = containerReference.GetDirectoryReference("targetdir"); var stopwatch = Stopwatch.StartNew(); TransferManager.CopyDirectoryAsync(directory, cloudBlobDirectory, true, new CopyDirectoryOptions { Recursive = true }, new DirectoryTransferContext()).Wait(); stopwatch.Stop(); Console.WriteLine($"{DateTime.Now.ToLongTimeString()}: Copy files took {stopwatch.ElapsedMilliseconds}ms"); Console.ReadLine(); }
/// <summary> /// Copy data between Azure storage. /// 1. Copy a CloudBlobDirectory /// 2. Cancel the transfer before it finishes with a CancellationToken /// 3. Store the transfer checkpoint into a file after transfer being cancelled /// 4. Reload checkpoint from the file /// 4. Resume the transfer with the loaded checkpoint /// </summary> private static async Task BlobDirectoryCopySample() { CloudBlobDirectory sourceBlobDir = await Util.GetCloudBlobDirectoryAsync(ContainerName, "blobdir"); CloudBlobDirectory destBlobDir = await Util.GetCloudBlobDirectoryAsync(ContainerName, "blobdir2"); // When source is CloudBlobDirectory: // 1. If recursive is set to true, data movement library matches the source blob name against SearchPattern as prefix. // 2. Otherwise, data movement library matches the blob with the exact name specified by SearchPattern. // // You can also replace the source directory with a CloudFileDirectory instance to copy data from Azure File Storage. If so: // 1. If recursive is set to true, SearchPattern is not supported. Data movement library simply transfer all azure files // under the source CloudFileDirectory and its sub-directories. // 2. Otherwise, data movement library matches the azure file with the exact name specified by SearchPattern. // // In the following case, data movement library will copy all blobs with the prefix "azure" in source blob directory. CopyDirectoryOptions options = new CopyDirectoryOptions() { SearchPattern = "azure", Recursive = true, }; DirectoryTransferContext context = new DirectoryTransferContext(); context.FileTransferred += FileTransferredCallback; context.FileFailed += FileFailedCallback; context.FileSkipped += FileSkippedCallback; // Create CancellationTokenSource used to cancel the transfer CancellationTokenSource cancellationSource = new CancellationTokenSource(); TransferCheckpoint checkpoint = null; TransferStatus trasferStatus = null; try { Task <TransferStatus> task = TransferManager.CopyDirectoryAsync(sourceBlobDir, destBlobDir, false /* isServiceCopy */, options, context, cancellationSource.Token); // Sleep for 1 seconds and cancel the transfer. // It may fail to cancel the transfer if transfer is done in 1 second. If so, no file will be copied after resume. Thread.Sleep(1000); Console.WriteLine("Cancel the transfer."); cancellationSource.Cancel(); trasferStatus = await task; } catch (Exception e) { Console.WriteLine("The transfer is cancelled: {0}", e.Message); } // Store the transfer checkpoint checkpoint = context.LastCheckpoint; // Serialize the checkpoint into a file #if DOTNET5_4 var formatter = new DataContractSerializer(typeof(TransferCheckpoint)); #else IFormatter formatter = new BinaryFormatter(); #endif string tempFileName = Guid.NewGuid().ToString(); using (var stream = new FileStream(tempFileName, FileMode.Create, FileAccess.Write, FileShare.None)) { formatter.Serialize(stream, checkpoint); } // Deserialize the checkpoint from the file using (var stream = new FileStream(tempFileName, FileMode.Open, FileAccess.Read, FileShare.None)) { checkpoint = formatter.Deserialize(stream) as TransferCheckpoint; } File.Delete(tempFileName); // Create a new TransferContext with the store checkpoint DirectoryTransferContext resumeContext = new DirectoryTransferContext(checkpoint); resumeContext.FileTransferred += FileTransferredCallback; resumeContext.FileFailed += FileFailedCallback; resumeContext.FileSkipped += FileSkippedCallback; // Record the overall progress ProgressRecorder recorder = new ProgressRecorder(); resumeContext.ProgressHandler = recorder; // Resume transfer from the stored checkpoint Console.WriteLine("Resume the cancelled transfer."); trasferStatus = await TransferManager.CopyDirectoryAsync(sourceBlobDir, destBlobDir, false /* isServiceCopy */, options, resumeContext); // Print out the final transfer state Console.WriteLine("Final transfer state: {0}", TransferStatusToString(trasferStatus)); }
/// <summary> /// Copies the content of one directory to another on the server side. /// Avoids having to download all items and reupload them to somewhere else on the client side. /// </summary> /// <param name="sourceDirectoryPath">The path to the directory containing the files to be transferred</param> /// <param name="destinationDirectoryPath">The path to the destination directory </param> /// <param name="transferEvent">Action callback for tracking progress of each file when transferring.</param> /// <returns>Result from the server side transfer.</returns> public async Task <ITransferResult> CopyDirectory(string sourceDirectoryPath, string destinationDirectoryPath, Action <Core.TransferEventType, ITransferEvent> transferEvent = null) { var sourceContainerName = GetContainerFromPath(sourceDirectoryPath); var destinationContainerName = GetContainerFromPath(destinationDirectoryPath); // Ensure destination folder exists if we've configured to create automatically. if (CreateFolderIfNotExists) { GetContainer(destinationContainerName, true); } var directoryTransferContext = new DirectoryTransferContext(); // Subscribe to the transfer events if an action method was passed. if (transferEvent != null) { directoryTransferContext.FileTransferred += (fileTransferSender, fileTransferredEventArgs) => { ITransferEvent i = (TransferEvent)fileTransferredEventArgs; transferEvent(Core.TransferEventType.Transferred, i); }; directoryTransferContext.FileFailed += (fileFailedSender, fileTransferredEventArgs) => { ITransferEvent i = (TransferEvent)fileTransferredEventArgs; transferEvent(Core.TransferEventType.Failed, i); }; directoryTransferContext.FileSkipped += (fileSkippedSender, fileTransferredEventArgs) => { ITransferEvent i = (TransferEvent)fileTransferredEventArgs; transferEvent(Core.TransferEventType.Skipped, i); }; } directoryTransferContext.ShouldOverwriteCallbackAsync = (source, destination) => Task.FromResult(true); var copyOptions = new CopyDirectoryOptions { BlobType = BlobType.AppendBlob, Recursive = true }; var sourceContainer = CloudBlobClient.GetContainerReference(sourceContainerName); var sourceRelativeUrl = GetPathWithoutContainer(sourceDirectoryPath); var sourceDirectory = sourceContainer.GetDirectoryReference(sourceRelativeUrl); var destinationContainer = CloudBlobClient.GetContainerReference(destinationContainerName); var destinationRelativeUrl = GetPathWithoutContainer(destinationDirectoryPath); var destinationDirectory = destinationContainer.GetDirectoryReference(destinationRelativeUrl); var transferTask = TransferManager.CopyDirectoryAsync(sourceDirectory, destinationDirectory, CopyMethod.ServiceSideSyncCopy, copyOptions, directoryTransferContext); var result = await transferTask; // Output the result from the transfer. return(new TransferResult { BytesTransferred = result.BytesTransferred, NumberOfFilesFailed = result.NumberOfFilesFailed, NumberOfFilesSkipped = result.NumberOfFilesSkipped, NumberOfFilesTransferred = result.NumberOfFilesTransferred }); }
async void RenameToolStripMenuItem_ClickAsync(object sender, EventArgs e) { TreeNode node = Containers.SelectedNode; if (node == null) { MessageBox.Show("Choose an item to rename first"); return; } CloudBlobDirectory sourceDir; CloudBlobDirectory targetDir; var options = new CopyDirectoryOptions { Recursive = true }; TreeNode parentNode = node.Parent; switch (node.ImageIndex) { case 0: new AskForm("Rename Container").ShowDialog(); if (Answer == null) { return; } if (!Answer.Any(n => n.IsLetter())) { MessageBox.Show("Russian is not allowed"); return; } ProgressBar.Visible = true; CloudBlobContainer sourceC = Client.GetContainerReference(node.Text); CloudBlobContainer targetC = Client.GetContainerReference(Answer); await targetC.CreateIfNotExistsAsync(); foreach (var blob in sourceC.ListBlobs()) { switch (blob) { case CloudBlobDirectory cbd: sourceDir = sourceC.GetDirectoryReference(blob.Uri.Directory()); targetDir = targetC.GetDirectoryReference(blob.Uri.Directory()); await TransferManager.CopyDirectoryAsync(sourceDir, targetDir, true, options, null); break; case CloudBlob cb: CloudBlob sourceBlob = sourceC.GetBlobReference(blob.Uri.File()); CloudBlob targetBlob = targetC.GetBlobReference(blob.Uri.File()); await TransferManager.CopyAsync(sourceBlob, targetBlob, true); break; } } await sourceC.DeleteIfExistsAsync(); break; case 1: switch (parentNode.ImageIndex) { case 0: CloudBlobContainer container = Client.GetContainerReference(parentNode.Text); sourceDir = container.GetDirectoryReference(node.Text); new AskForm("Rename Directory").ShowDialog(); if (Answer == null) { return; } ProgressBar.Visible = true; targetDir = container.GetDirectoryReference(Answer); await TransferManager.CopyDirectoryAsync(sourceDir, targetDir, true, options, null); await DeleteDirectory(sourceDir); break; case 1: (TreeNode containerNode, int count, string[] hier) = GetContainerNode(parentNode); Array.Reverse(hier); container = Client.GetContainerReference(containerNode.Text); sourceDir = container.GetDirectoryReference(hier[0]); for (int i = 0; i < count; i++) { sourceDir = sourceDir.GetDirectoryReference(hier[i + 1]); } sourceDir = sourceDir.GetDirectoryReference(node.Text); new AskForm("Rename Directory").ShowDialog(); if (Answer == null) { return; } ProgressBar.Visible = true; targetDir = sourceDir.Parent.GetDirectoryReference(Answer); await TransferManager.CopyDirectoryAsync(sourceDir, targetDir, true, options, null); await DeleteDirectory(sourceDir); break; } break; case 2: switch (parentNode.ImageIndex) { case 0: CloudBlobContainer container = Client.GetContainerReference(parentNode.Text); CloudBlob sourceBlob = container.GetBlobReference(node.Text); new AskForm("Rename Cloud Blob").ShowDialog(); if (Answer == null) { return; } ProgressBar.Visible = true; CloudBlob targetBlob = container.GetBlobReference(Answer); await TransferManager.CopyAsync(sourceBlob, targetBlob, true); await sourceBlob.DeleteIfExistsAsync(); break; case 1: (TreeNode containerNode, int count, string[] hier) = GetContainerNode(parentNode); Array.Reverse(hier); container = Client.GetContainerReference(containerNode.Text); sourceDir = container.GetDirectoryReference(hier[0]); for (int i = 0; i < count; i++) { sourceDir = sourceDir.GetDirectoryReference(hier[i + 1]); } sourceBlob = sourceDir.GetBlobReference(node.Text); new AskForm("Rename Cloud Blob").ShowDialog(); if (Answer == null) { return; } ProgressBar.Visible = true; targetBlob = sourceDir.GetBlobReference(Answer); await TransferManager.CopyAsync(sourceBlob, targetBlob, true); await sourceBlob.DeleteIfExistsAsync(); break; } break; } RefreshAll(); ProgressBar.Visible = false; }