private EmulatorStatus Run(EmulatorAction action) { var status = new EmulatorStatus(this, action); if (!ReferenceEquals(status.Version, null)) { Version = status.Version; } if (!ReferenceEquals(status.BlobEndpoint, null)) { BlobEndpoint = status.BlobEndpoint; } if (!ReferenceEquals(status.QueueEndpoint, null)) { QueueEndpoint = status.QueueEndpoint; } if (!ReferenceEquals(status.TableEndpoint, null)) { TableEndpoint = status.TableEndpoint; } return(status); }
/// <summary>Executes the Azure Storage Emulator and returns the resulting status.</summary> /// <param name="emulator">The emulator environment providing settings necessary to run.</param> /// <param name="action">The action to perform.</param> internal EmulatorStatus(Emulator emulator, EmulatorAction action) { string arguments; switch (action) { case EmulatorAction.Unknown: throw new ArgumentException(@"'action' contained 'Unknown'.", nameof(action)); case EmulatorAction.Status: arguments = "status"; break; case EmulatorAction.Start: arguments = "start"; break; case EmulatorAction.Stop: arguments = "stop"; break; case EmulatorAction.Clear: arguments = "clear"; break; case EmulatorAction.Init: arguments = "init"; break; default: throw new ArgumentOutOfRangeException(nameof(action), action, @$ "'action' did not contain a recognized value: {action}."); } Action = action; if (!emulator.IsEmulatorExePresent) { IsInstalled = false; IsSuccessful = false; Error = @$ "Azure Storage Emulator was not found to be installed at the expected location: " "{emulator.EmulatorExePath}" "."; return; } // For actions that do not capture these details, we can, where possible, reuse those from a previous run. Version = emulator.Version; BlobEndpoint = emulator.BlobEndpoint; QueueEndpoint = emulator.QueueEndpoint; TableEndpoint = emulator.TableEndpoint; IsInstalled = true; var process = new Process { StartInfo = new ProcessStartInfo(emulator.EmulatorExePath, arguments) { CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, WindowStyle = ProcessWindowStyle.Minimized, WorkingDirectory = emulator.EmulatorDirectoryPath, UseShellExecute = false } }; var outputStringBuilder = new StringBuilder(); process.OutputDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data); process.ErrorDataReceived += (sender, eventArgs) => outputStringBuilder.AppendLine(eventArgs.Data); process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); try { var processExited = process.WaitForExit(Emulator.Timeout); if (!processExited) // we timed out... { process.Kill(); IsInstalled = true; IsSuccessful = false; Error = @$ "Process timed-out waiting for a response from {Emulator.EmulatorExeName}."; return; } var output = outputStringBuilder.ToString(); Output = output; if (process.ExitCode != 0) { switch (action) { case EmulatorAction.Start: if (process.ExitCode == -5) { IsSuccessful = true; IsRunning = true; Warning = @"Azure storage emulator already in a running state."; return; } break; case EmulatorAction.Stop: if (process.ExitCode == -6) { IsSuccessful = true; IsRunning = false; Warning = @"Azure storage emulator already in a stopped state."; return; } break; case EmulatorAction.Clear: break; case EmulatorAction.Init: break; } var errorMessage = @$ "{Emulator.EmulatorExeName} exited with a non-zero error code: {process.ExitCode}."; if (output.Length > 0) { errorMessage = errorMessage + $@" Output: {output}."; } IsInstalled = true; IsSuccessful = false; Error = errorMessage; } IsSuccessful = true; /* * For example: * Windows Azure Storage Emulator 5.10.0.0 command line tool * IsRunning: True * BlobEndpoint: http://127.0.0.1:10000/ * QueueEndpoint: http://127.0.0.1:10001/ * TableEndpoint: http://127.0.0.1:10002/ */ var lines = output.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); var index = 0; foreach (var line in lines) { Match matches; switch (index++) { case 0: matches = _versionRegex.Match(line); if (matches.Success) { Version = new Version(matches.Groups[1].Value); } break; case 1: matches = _isRunningRegex.Match(line); if (matches.Success) { if (bool.TryParse(matches.Groups[1].Value, out var isRunning)) { IsRunning = isRunning; } } break; case 2: matches = _blobEndpointRegex.Match(line); if (matches.Success) { BlobEndpoint = new Uri(matches.Groups[1].Value, UriKind.Absolute); } break; case 3: matches = _queueEndpointRegex.Match(line); if (matches.Success) { QueueEndpoint = new Uri(matches.Groups[1].Value, UriKind.Absolute); } break; case 4: matches = _tableEndpointRegex.Match(line); if (matches.Success) { TableEndpoint = new Uri(matches.Groups[1].Value, UriKind.Absolute); } break; default: if (string.IsNullOrWhiteSpace(Error)) { Warning = Warning + @$ "; Unexpected results on line {index}: {line}"; } else { Warning = @$ "Unexpected results on line {index}: {line}"; } break; } } } finally { process.Close(); } }