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

时间:2011-09-25 18:20:00

标签: c# azure azure-storage

我有一些使用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

10 个答案:

答案 0 :(得分:21)

2015年1月19日更新:

在做了更多测试(即运行多个版本)之后,我发现WAStorageEmulator.exe status 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中指定的端点,而不是现有正在运行的进程的端点。即,如果启动模拟器,然后更改配置文件,然后调用status,它将报告配置中列出的端点。

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

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

2015年1月18日更新:

我已完全重写此代码,以便根据@ RobertKoritnik的请求正确使用WAStorageEmulator.exe status 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();
        }
    }
}

答案 1 :(得分: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 :(得分:2)

For Windows Azure Storage Emulator v5.2, the following helper class can be used to start the emulator:

 x = seq(from = 0,to = 14,length.out = 100)

        p <- ggplot(data=data.frame(x), aes(x = x,y = sin(x + 1 * .5)*(7 - 1) ))+geom_line()

        for (i in 2:6) {

           p <- p + geom_line(aes_string(y = sin(x + i * .5)*(7 - i)),col  = i)+
                      theme_classic()+theme(axis.title.y = element_blank())

         }
       p

[Thanks to huha for the boilerplate code to execute a shell command.]

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

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

答案 6 :(得分:0)

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

试试这个

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

答案 7 :(得分:0)

我卸载了所有Windows Azure位:

  • WA SDK v1.5.20830.1814
  • 适用于Visual Studio的WA工具: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();
        }
    }

答案 8 :(得分:0)

我们走了:传递字符串&#34;开始&#34;到方法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

答案 9 :(得分:0)

现在有一个精巧的NuGet小型软件包,可帮助以编程方式启动/停止Azure存储模拟器:RimDev.Automation.StorageEmulator

源代码在this GitHub repository中可用,但是您基本上可以执行以下操作:

if(!AzureStorageEmulatorAutomation.IsEmulatorRunning())
{
    AzureStorageEmulatorAutomation emulator = new AzureStorageEmulatorAutomation();
    emulator.Start();

    // Even clear some things
    emulator.ClearBlobs();
    emulator.ClearTables();
    emulator.ClearQueues();

    emulator.Stop();
}

感觉对我来说是最干净的选择。