如何从程序中启动Azure存储模拟器

问题描述 投票:15回答:9

我有一些使用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设置,但似乎没有任何效果。有人有这个问题吗?

我检查了应用程序事件日志,发现了以下两个条目:

事件ID:1023 .NET运行时版本2.0.50727.5446 - 致命执行引擎错误(000007FEF46B40D2)(80131506)

事件ID:1000故障应用程序名称:DSService.exe,版本:6.0.6002.18312,时间戳:0x4e5d8cf3故障模块名称:mscorwks.dll,版本:2.0.50727.5446,时间戳:0x4d8cdb54异常代码:0xc0000005故障偏移:0x00000000001de8d4故障处理id:0x%9错误应用程序启动时间:0x%10错误应用程序路径:%11错误模块路径:%12报告ID:%13

c# azure azure-storage
9个回答
21
投票

2015年1月19日更新:

在进行了更多的测试(即运行多个版本)之后,我发现WAStorageEmulator.exestatus 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.

此外,status命令仅显示为报告WAStorageEmulator.exe.config中指定的端点,而不是现有正在运行的进程的端点。即,如果启动模拟器,然后更改配置文件,然后调用状态,它将报告配置中列出的端点。

鉴于所有这些警告,事实上,使用原始实现可能更好,因为它看起来更可靠。

我会留下两个,以便其他人可以选择适合他们的解决方案。

2015年1月18日更新:

我完全重写了这段代码,以便根据@ RobertKoritnik的要求适当地利用WAStorageEmulator.exestatus API

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

4
投票

这个程序对我来说很好。试一试,如果它也适合你,那就从那里开始工作。 (你的应用程序与此有何不同?)

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
投票

对于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执行shell命令的样板代码。]


1
投票

仅供参考 - 1.6默认位置是MSDN docs上所述的C:\ Program Files \ Windows Azure Emulator \ emulator。


1
投票

我们遇到了同样的问题。我们有一个“冒烟测试”的概念,它在各组测试之间运行,并确保在下一组开始之前环境处于良好状态。我们有一个.cmd文件启动了冒烟测试,它可以正常启动devfabric模拟器,但只有.cmd进程运行时,devstore模拟器才会运行。

显然,DSServiceSQL.exe的实现与DFService.exe不同。 DFService似乎像Windows服务一样运行 - 启动它,它继续运行。一旦启动它的进程终止,DSServiceSQL就会死掉。


1
投票

v4.6中的文件名是“AzureStorageEmulator.exe”。完整路径是:“C:\ Program Files(x86)\ Microsoft SDKs \ Azure \ Storage Emulator \ AzureStorageEmulator.exe”


0
投票

我卸载了所有Windows Azure位:

  • SDK v1.50 20830 1814
  • 适用于Visual Studio的WA工具:v1.5.40909.1602
  • W:p 1. c:v 1. 5. 37
  • W:p 2.c:v 2. 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
投票

可能是由于找不到文件引起的?

试试这个

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

0
投票

我们继续:将字符串“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;
}

另见我的新自我回答question

© www.soinside.com 2019 - 2024. All rights reserved.