2016-05-05 7 views
3

Я пытаюсь скопировать контейнеры в Azure из одного места хранения в другое. Для этого я использую команду AzCopy. Сначала я получаю список всех контейнеров, а затем запускаю AzCopy на основе имени контейнера из командной строки, используя код C#.Использование командной строки из C# для копирования контейнера с использованием AzCopy

Проблема, с которой я столкнулся, заключается в том, что она копирует контейнеры из одного места в другое, но после 4 контейнеров кажется, что она застряла. И тест продолжает работать вечно. Когда я отменяю тест, я вижу, что все остальные контейнеры также копируются.

Мне было интересно, как я могу решить эту проблему после завершения теста, и все папки будут скопированы. Я попытался подождать после каждого звонка, чтобы убедиться, что для завершения вызова достаточно времени. Также попытался использовать cmd.WaitForExit(); после каждого звонка, но это просто застревает.

Любые предложения о том, чего я мог бы потерять, я хотел бы сделать, чтобы получить результат после каждого вызова, потому что прямо сейчас он выводит результат только после завершения всех команд. Также думал о том, как последовательно запускать вызовы командной строки, поэтому запускается только после завершения первого.

Любая помощь будет оценена!

namespace Test2 
{ 
[TestFixture] 
class ContainerList 
{ 
    [Test] 
    public void CopyingContainerData() 
    { 
     CloudStorageAccount sourceCloudStorageAccount = 
     CloudStorageAccount.Parse("StorageAccountKey"); 
     CloudBlobClient sourceCloudBlobClient = sourceCloudStorageAccount.CreateCloudBlobClient(); 
     List<string> outputLines = new List<string>(); 
     IEnumerable<CloudBlobContainer> containers = sourceCloudBlobClient.ListContainers(); 


     Process cmd = new Process(); 
     cmd.StartInfo.FileName = "cmd.exe"; 
     cmd.StartInfo.RedirectStandardInput = true; 
     cmd.StartInfo.RedirectStandardOutput = true; 
     cmd.StartInfo.CreateNoWindow = false; 
     cmd.StartInfo.UseShellExecute = false; 
     cmd.Start(); 
     int i = 0; 

     foreach (CloudBlobContainer oneContainer in containers) 
     { 

       string outputLine = oneContainer.Name; 
       outputLines.Add(outputLine); 
       string container = oneContainer.Name; 
       string strCmdText = @"AzCopy /Source:https://location1.blob.core.windows.net/" + container + @" /Dest:https://location2.blob.core.windows.net/" + container + @" /SourceKey:abc /DestKey:abc123 /S /NC:8 /XO /Y"; 
       string location = @"cd C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy"; 

       cmd.StandardInput.WriteLine(location); 
       cmd.StandardInput.WriteLine(strCmdText); 
       //System.Threading.Thread.Sleep(20000); 
       //cmd.WaitForExit(); 

       i++; 

      if (i == 15) 
      { 
       break; 
      } 

     } 
     string[] outputText = outputLines.ToArray(); 
     File.WriteAllLines(@"C:\AzureTests\CopyData.txt", outputText); 


     cmd.StandardInput.Flush(); 
     cmd.StandardInput.Close(); 
     Console.WriteLine(cmd.StandardOutput.ReadToEnd()); 



    } 
} 
} 
+0

Это не прямо ответить на ваш вопрос, но вы смотрели на использовании [Library Data Movement] (https://azure.microsoft.com/en-us/blog/introducing-azure- storage-data-movement-library-preview-2 /), которая в основном является функциональностью AzCopy, которую вы можете назвать программно? Это устранило бы необходимость вызова в оболочку. – BenV

+0

Является ли этот код даже работающим, если я хочу загрузить локальные файлы в хранилище azure blob? Я написал тот же код, но cmd бросает исключение для меня. – batmaci

+0

Код должен работать. Какое исключение? – chillax786

ответ

1

Я предлагаю вам использовать PowerShell, чтобы сделать это:

$SourceStorageAccount = "sourceStorageAccount" 
$SourceStorageKey = "sourceKey" 
$DestStorageAccount = "destStorageAccount" 
$DestStorageKey = "destKey" 

$SourceStorageContext = New-AzureStorageContext –StorageAccountName $SourceStorageAccount -StorageAccountKey $SourceStorageKey 
$DestStorageContext = New-AzureStorageContext –StorageAccountName $DestStorageAccount -StorageAccountKey $DestStorageKey 

$containers = Get-AzureStorageContainer -Context $SourceStorageContext 

foreach($container in $containers) { 
    New-AzureStorageContainer -Context $DestStorageContext -Name $container.name -Permission Off 

    $Blobs = Get-AzureStorageBlob -Context $SourceStorageContext -Container $container.name 

    #Do the copy of everything 
    foreach ($Blob in $Blobs) { 
     Write-Output "Moving $Blob.Name" 
     Start-CopyAzureStorageBlob -Context $SourceStorageContext -SrcContainer $container.name -SrcBlob $Blob.Name ` 
      -DestContext $DestStorageContext -DestContainer $container.name -DestBlob $Blob.Name 
    } 
} 
+0

Это будет копировать только капли из одного контейнера ... Если у меня есть 100 контейнеров, мне не нужно будет запускать этот скрипт 100 раз при обновлении имени контейнера каждый раз? – chillax786

+0

Я обновил свой ответ. Теперь вы можете скопировать все ваши контейнеры/капли из учетной записи хранилища в другую. Я проверил его в своем местном. –

+0

Означает ли это, что AzCopy.exe вызывается из .Net не вернется? Мы должны использовать PS для обработки? –

0

Мы похожи сценарий AzCopy.exe вызов не возвращает управление .Net. Причиной было параллельное выполнение AzCopy.exe без указания файлов журнала. Он по умолчанию делится файлами журнала и получает нарушение доступа. Когда мы выпускали разные файлы журналов для разных экземпляров AzCopy, он смотрел на работу.

Running multiple instances of AzCopy.exe from .Net

 Смежные вопросы

  • Нет связанных вопросов^_^