Как запустить эмулятор 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();
}

Это похоже на самый чистый вариант для меня.