2016-05-05 20 views
3

Ich versuche, Container in Azure von einem Speicherort zum anderen zu kopieren. Ich verwende den AzCopy-Befehl dafür. Zuerst erhalte ich eine Liste aller Container und führe dann AzCopy basierend auf dem Containernamen über die Befehlszeile mit C# -Code aus.Verwenden der Befehlszeile aus C# zum Kopieren des Containers mit AzCopy

Das Problem, das mir dabei auftrat, ist, dass es die Container von einem Ort zum anderen kopiert, aber nach 4 Containern scheint es zu stecken. Und der Test läuft für immer weiter. Wenn ich den Test abbringe, sehe ich, dass alle anderen Container ebenfalls kopiert werden.

Ich frage mich, wie ich dieses Problem lösen kann, dass der Test abgeschlossen ist und alle Ordner kopiert werden. Ich habe versucht, nach jedem Anruf zu warten, um sicherzustellen, dass genügend Zeit für den Anruf vorhanden ist. Auch versucht mit cmd.WaitForExit(); nach jedem Anruf aber das bleibt einfach hängen.

Irgendwelche Vorschläge, was ich vermissen könnte, eine Sache, die ich tun wollte, war die Ausgabe nach jedem Aufruf zu bekommen, denn im Moment gibt es nur das Ergebnis aus, sobald alle Befehle beendet sind. Außerdem wurde darüber nachgedacht, wie der Befehlszeilenaufruf der Reihe nach ausgeführt wird, so dass er erst ausgeführt wird, nachdem der erste beendet wurde.

Jede Hilfe wäre willkommen!

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

Ihre Frage nicht direkt beantworten, aber haben Sie sehen die [Data-Bewegung Library] bei Verwendung von (https://azure.microsoft.com/en-us/blog/introducing-azure- storage-data-movement-library-preview-2 /), was ist eigentlich AzCopy-Funktionalität, die Sie programmatisch aufrufen können? Das würde die Notwendigkeit beseitigen, nach der Shell zu rufen. – BenV

+0

Funktioniert dieser Code sogar, wenn ich lokale Dateien in azure Blobspeicher hochladen möchte? Ich habe den gleichen Code geschrieben, aber cmd wirft eine Ausnahme für mich. – batmaci

+0

Code sollte funktionieren. Was ist die Ausnahme? – chillax786

Antwort

1

Ich schlage vor, Sie Powershell, dies zu tun verwenden:

$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

Dies würde nur Blobs aus einem Container kopieren ... Wenn ich 100 Container habe, müsste ich dieses Script nicht 100 Mal ausführen, während ich den Containernamen jedes Mal aktualisiere? – chillax786

+0

Ich habe meine Antwort aktualisiert. Jetzt können Sie alle Ihre Container/Blobs von einem Speicherkonto auf ein anderes kopieren. Ich habe es in meinem lokalen getestet. –

+0

Bedeutet dies, dass die von .Net aufgerufene AzCopy.exe nicht zurückgibt? Wir sollten PS verwenden, um damit umzugehen? –

0

Wir hatten ähnliches Szenario von AzCopy.exe Aufruf nicht die Kontrolle zu .Net zurück. Der Grund war die parallele Ausführung von AzCopy.exe ohne Angabe der Journaldateien. Es teilt die Journaldateien standardmäßig und erhält Zugriffsverletzung. Wenn wir verschiedene Journaldateien für verschiedene Instanzen von AzCopy ausgaben, funktionierte es.

Running multiple instances of AzCopy.exe from .Net