Как запустить эмулятор хранилища Azure из программы - PullRequest
16 голосов
/ 25 сентября 2011

У меня есть несколько модульных тестов, которые используют хранилище Azure. При их локальном запуске я хочу, чтобы они использовали эмулятор хранилища Azure, который является частью Azure SDK v1.5. Если эмулятор не запущен, я хочу, чтобы он был запущен.

Чтобы запустить эмулятор из командной строки, я могу использовать это:

"C:\Program Files\Windows Azure SDK\v1.5\bin\csrun" /devstore

Это отлично работает.

Когда я пытаюсь запустить его, используя этот код C #, происходит сбой:

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

Ответы [ 9 ]

21 голосов
/ 07 августа 2013

Обновлено 19.01.2015:

Проведя дополнительное тестирование (т. Е. Выполнив несколько сборок), я обнаружил, что API статуса WAStorageEmulator.exe на самом деле не работает в двух важных аспектах (которые могут или не могут оказать влияние о том, как вы его используете).

Отчеты о состоянии 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, а не о существующем запущенном процессе. Т.е., если вы запустите эмулятор, затем внесете изменения в файл конфигурации, а затем вызовете состояние, он сообщит о конечных точках, перечисленных в конфигурации.

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

Я оставлю оба, чтобы другие могли выбрать, какое решение подойдет им.

Обновлено 18.01.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);
    }
}

Оригинальный пост:

Я взял код Дуга Клаттера и Смаркса на один шаг вперед и создал класс утилит:

Приведенный ниже код был обновлен для работы в 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();
        }
    }
}
4 голосов
/ 26 сентября 2011

Эта программа отлично работала для меня.Попробуйте, и если это сработает и для вас, работайте в обратном направлении.(А чем ваше приложение отличается от этого?)

using System.Diagnostics;
public class Program
{
public static void Main() {
        Process.Start(@"c:\program files\windows azure sdk\v1.5\bin\csrun", "/devstore").WaitForExit();
    }
}
2 голосов
/ 18 декабря 2017

В 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 за шаблонный код для выполнения команды оболочки.]

1 голос
/ 03 февраля 2017

Имя файла в v4.6 - «AzureStorageEmulator.exe».Полный путь: «C: \ Program Files (x86) \ Microsoft SDK \ Azure \ Storage Emulator \ AzureStorageEmulator.exe»

1 голос
/ 08 февраля 2013

Мы сталкиваемся с той же проблемой. У нас есть концепция «теста на дым», который проводится между группами тестов и который гарантирует, что среда находится в хорошем состоянии перед началом следующей группы. У нас есть файл .cmd, который запускает тесты дыма, и он прекрасно работает при запуске эмулятора devfabric, но эмулятор devstore работает только до тех пор, пока выполняется процесс .cmd.

Очевидно, что реализация DSServiceSQL.exe отличается от DFService.exe. DFService, кажется, работает как служба Windows - запускайте его, и он продолжает работать. DSServiceSQL умирает, как только умирает запущенный процесс.

1 голос
/ 23 декабря 2011

FYI - расположение по умолчанию 1.6: C: \ Program Files \ Windows Azure Emulator \ emulator, как указано в документах MSDN .

0 голосов
/ 08 апреля 2014

Вот и мы: передаем строку «start» в метод ExecuteWAStorageEmulator (). NUnit.Framework используется только для Assert.

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;
}

См. Также мой новый ответ на свой вопрос вопрос

0 голосов
/ 30 сентября 2011

Я удалил все биты Windows Azure:

  • WA SDK v1.5.20830.1814
  • WA Tools для 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();
        }
    }
0 голосов
/ 25 сентября 2011

может быть вызвано тем, что файл не найден?

попробуйте

FileName = Path.Combine(SDKDirectory, "csrun.exe")
...