Как запустить эмулятор Azure Storage из программы
У меня есть некоторые модульные тесты, которые используют Azure Storage. Когда я запускаю их локально, я хочу, чтобы они использовали эмулятор Azure Storage, который является частью Azure SDK v1.5. Если эмулятор не запущен, я хочу, чтобы он был запущен.
Чтобы запустить эмулятор из командной строки, я могу использовать это:
"C:\Program Files\Windows Azure SDK\v1.5\bin\csrun" /devstore
Это отлично работает.
Когда я пытаюсь запустить его с помощью этого кода на С#, он сбой:
using System.IO;
using System.Diagnostics;
...
ProcessStartInfo processToStart = new ProcessStartInfo()
{
FileName = Path.Combine(SDKDirectory, "csrun"),
Arguments = "/devstore"
};
Process.Start(processToStart);
Я пробовал работать с несколькими параметрами ProcessStartInfo, но ничего не работает. У кого-нибудь еще такая проблема?
Я проверил журнал событий приложений и нашел следующие две записи:
Код события: 1023
.NET Runtime версии 2.0.50727.5446 - Ошибка машинного сбоя (000007FEF46B40D2) (80131506)
Идентификатор события: 1000
Неверное имя приложения: DSService.exe, версия: 6.0.6002.18312, отметка времени: 0x4e5d8cf3
Неверное имя модуля: mscorwks.dll, версия: 2.0.50727.5446, отметка времени: 0x4d8cdb54
Код исключения: 0xc0000005
Смещение ошибки: 0x00000000001de8d4
Идентификатор процесса отказа: 0x% 9
Время сбоя при запуске: 0x% 10
Неисправность пути приложения:% 11
Ошибка пути модуля:% 12
Идентификатор отчета:% 13
Ответы
Ответ 1
Я удалил все биты Windows Azure:
- WA SDK v1.5.20830.1814
- Инструменты WA для Visual Studio: v1.5.40909.1602
- WA AppFabric: v1.5.37
- WA AppFabric: v2.0.224
Затем я загрузил и установил все, используя унифицированный установщик. Все вернулось, кроме AppFabric v2. Все номера версий одинаковы. Повторите мои тесты и все еще испытывайте проблемы.
А потом... (это странно)... это будет работать время от времени. Перезагрузите машину, и теперь она работает. Выключение и перезагрузка несколько раз сейчас... и это просто работает. (Вздох)
Спасибо всем, кто предоставил отзывы и/или идеи!
Конечный код:
static void StartAzureStorageEmulator()
{
ProcessStartInfo processStartInfo = new ProcessStartInfo()
{
FileName = Path.Combine(SDKDirectory, "csrun.exe"),
Arguments = "/devstore",
};
using (Process process = Process.Start(processStartInfo))
{
process.WaitForExit();
}
}
Ответ 2
Обновлено: 1/19/2015:
После выполнения большего тестирования (т.е. запуска нескольких сборок) я обнаружил, что WAStorageEmulator.exe
API состояния > фактически разбит несколькими важными способами (что может или не может повлиять на то, как вы его используете).
Отчет о состоянии False
, даже если существующий процесс выполняется, если пользователь отличается между существующим запущенным процессом и пользователем, используемым для запуска процесса состояния. Этот неправильный отчет о состоянии приведет к сбою процесса, который выглядит следующим образом:
C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator>WAStorageEmulator.exe status
Windows Azure Storage Emulator 3.4.0.0 command line tool
IsRunning: False
BlobEndpoint: http://127.0.0.1:10000/
QueueEndpoint: http://127.0.0.1:10001/
TableEndpoint: http://127.0.0.1:10002/
C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator>WAStorageEmulator.exe start
Windows Azure Storage Emulator 3.4.0.0 command line tool
Error: Port conflict with existing application.
Кроме того, команда статуса выводит только сообщения о конечных точках, указанных в WAStorageEmulator.exe.config
, а не в текущем запущенном процессе. I.e., если вы запустите эмулятор, затем внесите изменения в файл конфигурации, а затем вызовите статус, он сообщит о конечных точках, перечисленных в конфиге.
Учитывая все эти оговорки, на самом деле может быть лучше использовать исходную реализацию, поскольку она кажется более надежной.
Я оставлю оба, чтобы другие могли выбирать, какое решение для них работает.
Обновлено 1/18/2015:
Я полностью переписал этот код, чтобы правильно использовать WAStorageEmulator.exe
API состояния для запроса @RobertKoritnik.
public static class AzureStorageEmulatorManager
{
public static bool IsProcessRunning()
{
bool status;
using (Process process = Process.Start(StorageEmulatorProcessFactory.Create(ProcessCommand.Status)))
{
if (process == null)
{
throw new InvalidOperationException("Unable to start process.");
}
status = GetStatus(process);
process.WaitForExit();
}
return status;
}
public static void StartStorageEmulator()
{
if (!IsProcessRunning())
{
ExecuteProcess(ProcessCommand.Start);
}
}
public static void StopStorageEmulator()
{
if (IsProcessRunning())
{
ExecuteProcess(ProcessCommand.Stop);
}
}
private static void ExecuteProcess(ProcessCommand command)
{
string error;
using (Process process = Process.Start(StorageEmulatorProcessFactory.Create(command)))
{
if (process == null)
{
throw new InvalidOperationException("Unable to start process.");
}
error = GetError(process);
process.WaitForExit();
}
if (!String.IsNullOrEmpty(error))
{
throw new InvalidOperationException(error);
}
}
private static class StorageEmulatorProcessFactory
{
public static ProcessStartInfo Create(ProcessCommand command)
{
return new ProcessStartInfo
{
FileName = @"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\WAStorageEmulator.exe",
Arguments = command.ToString().ToLower(),
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
}
}
private enum ProcessCommand
{
Start,
Stop,
Status
}
private static bool GetStatus(Process process)
{
string output = process.StandardOutput.ReadToEnd();
string isRunningLine = output.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).SingleOrDefault(line => line.StartsWith("IsRunning"));
if (isRunningLine == null)
{
return false;
}
return Boolean.Parse(isRunningLine.Split(':').Select(part => part.Trim()).Last());
}
private static string GetError(Process process)
{
string output = process.StandardError.ReadToEnd();
return output.Split(':').Select(part => part.Trim()).Last();
}
}
И соответствующие тесты:
[TestFixture]
public class When_starting_process
{
[Test]
public void Should_return_started_status()
{
if (AzureStorageEmulatorManager.IsProcessRunning())
{
AzureStorageEmulatorManager.StopStorageEmulator();
Assert.That(AzureStorageEmulatorManager.IsProcessRunning(), Is.False);
}
AzureStorageEmulatorManager.StartStorageEmulator();
Assert.That(AzureStorageEmulatorManager.IsProcessRunning(), Is.True);
}
}
[TestFixture]
public class When_stopping_process
{
[Test]
public void Should_return_stopped_status()
{
if (!AzureStorageEmulatorManager.IsProcessRunning())
{
AzureStorageEmulatorManager.StartStorageEmulator();
Assert.That(AzureStorageEmulatorManager.IsProcessRunning(), Is.True);
}
AzureStorageEmulatorManager.StopStorageEmulator();
Assert.That(AzureStorageEmulatorManager.IsProcessRunning(), Is.False);
}
}
Оригинальное сообщение:
Я сделал Doug Clutter и Smarx код еще на один шаг и создал класс утилиты:
Код ниже обновлен для работы как с Windows 7, так и с 8 и теперь указывает на новый путь эмулятора хранилища с SDK 2.4. **
public static class AzureStorageEmulatorManager
{
private const string _windowsAzureStorageEmulatorPath = @"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\WAStorageEmulator.exe";
private const string _win7ProcessName = "WAStorageEmulator";
private const string _win8ProcessName = "WASTOR~1";
private static readonly ProcessStartInfo startStorageEmulator = new ProcessStartInfo
{
FileName = _windowsAzureStorageEmulatorPath,
Arguments = "start",
};
private static readonly ProcessStartInfo stopStorageEmulator = new ProcessStartInfo
{
FileName = _windowsAzureStorageEmulatorPath,
Arguments = "stop",
};
private static Process GetProcess()
{
return Process.GetProcessesByName(_win7ProcessName).FirstOrDefault() ?? Process.GetProcessesByName(_win8ProcessName).FirstOrDefault();
}
public static bool IsProcessStarted()
{
return GetProcess() != null;
}
public static void StartStorageEmulator()
{
if (!IsProcessStarted())
{
using (Process process = Process.Start(startStorageEmulator))
{
process.WaitForExit();
}
}
}
public static void StopStorageEmulator()
{
using (Process process = Process.Start(stopStorageEmulator))
{
process.WaitForExit();
}
}
}
Ответ 3
Эта программа отлично работала для меня. Попробуйте, и если это сработает для вас, откиньтесь назад. (Что относительно вашего приложения отличается от этого?)
using System.Diagnostics;
public class Program
{
public static void Main() {
Process.Start(@"c:\program files\windows azure sdk\v1.5\bin\csrun", "/devstore").WaitForExit();
}
}
Ответ 4
Для Windows Azure Storage Emulator v5.2 для запуска эмулятора можно использовать следующий вспомогательный класс:
using System.Diagnostics;
public static class StorageEmulatorHelper {
/* Usage:
* ======
AzureStorageEmulator.exe init : Initialize the emulator database and configuration.
AzureStorageEmulator.exe start : Start the emulator.
AzureStorageEmulator.exe stop : Stop the emulator.
AzureStorageEmulator.exe status : Get current emulator status.
AzureStorageEmulator.exe clear : Delete all data in the emulator.
AzureStorageEmulator.exe help [command] : Show general or command-specific help.
*/
public enum StorageEmulatorCommand {
Init,
Start,
Stop,
Status,
Clear
}
public static int StartStorageEmulator() {
return ExecuteStorageEmulatorCommand(StorageEmulatorCommand.Start);
}
public static int StopStorageEmulator() {
return ExecuteStorageEmulatorCommand(StorageEmulatorCommand.Stop);
}
public static int ExecuteStorageEmulatorCommand(StorageEmulatorCommand command) {
var start = new ProcessStartInfo {
Arguments = command.ToString(),
FileName = @"C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe"
};
var exitCode = executeProcess(start);
return exitCode;
}
private static int executeProcess(ProcessStartInfo startInfo) {
int exitCode = -1;
try {
using (var proc = new Process {StartInfo = startInfo}) {
proc.Start();
proc.WaitForExit();
exitCode = proc.ExitCode;
}
}
catch {
//
}
return exitCode;
}
}
[Благодаря huha для кода шаблона для выполнения команды оболочки.]
Ответ 5
FYI. Расположение по умолчанию 1.6 - это C:\Program Files\эмулятор Windows Azure Emulator, как указано в документах MSDN.
Ответ 6
Мы сталкиваемся с той же проблемой. У нас есть концепция "smoke test", которая проходит между группами тестов и которая гарантирует, что среда находится в хорошем состоянии до того, как начнется следующая группа. У нас есть файл .cmd, который запускает тесты дыма, и он отлично работает, начиная с эмулятора devfabric, но эмулятор devstore работает только до тех пор, пока выполняется процесс .cmd.
По-видимому, реализация DSServiceSQL.exe отличается от DFService.exe. DFService, похоже, работает как сервис Windows - отключайте его, и он продолжает работать. DSServiceSQL умирает, как только начинается процесс его запуска.
Ответ 7
В имени файла в версии 4.4 указано "AzureStorageEmulator.exe". Полный путь: "C:\Program Files (x86)\Microsoft SDK\Azure\Storage Emulator\AzureStorageEmulator.exe"
Ответ 8
может быть вызвано не найденным файлом?
попробуйте это
FileName = Path.Combine(SDKDirectory, "csrun.exe")
Ответ 9
Вот так: Передайте строку "start" методу ExecuteWAStorageEmulator().
NUnit.Framework используется только для подтверждения.
using System.Diagnostics;
using NUnit.Framework;
private static void ExecuteWAStorageEmulator(string argument)
{
var start = new ProcessStartInfo
{
Arguments = argument,
FileName = @"c:\Program Files (x86)\Microsoft SDKs\Windows Azure\Storage Emulator\WAStorageEmulator.exe"
};
var exitCode = ExecuteProcess(start);
Assert.AreEqual(exitCode, 0, "Error {0} executing {1} {2}", exitCode, start.FileName, start.Arguments);
}
private static int ExecuteProcess(ProcessStartInfo start)
{
int exitCode;
using (var proc = new Process { StartInfo = start })
{
proc.Start();
proc.WaitForExit();
exitCode = proc.ExitCode;
}
return exitCode;
}
См. также мой новый ответ на вопрос
Ответ 10
Теперь есть небольшой пакет NuGet для программного запуска и остановки эмулятора хранилища Azure: RimDev.Automation.StorageEmulator.
Исходный код доступен в этом репозитории GitHub, но вы можете делать такие вещи:
if(!AzureStorageEmulatorAutomation.IsEmulatorRunning())
{
AzureStorageEmulatorAutomation emulator = new AzureStorageEmulatorAutomation();
emulator.Start();
// Even clear some things
emulator.ClearBlobs();
emulator.ClearTables();
emulator.ClearQueues();
emulator.Stop();
}
Это похоже на самый чистый вариант для меня.