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

Dou*_*ter 18 c# azure azure-storage

我有一些使用Azure存储的单元测试.在本地运行这些时,我希望它们使用Azure存储模拟器,它是Azure SDK v1.5的一部分.如果模拟器没有运行,我希望它能够启动.

要从命令行启动模拟器,我可以使用:

"C:\Program Files\Windows Azure SDK\v1.5\bin\csrun" /devstore
Run Code Online (Sandbox Code Playgroud)

这很好用.

当我尝试使用这个C#代码启动它时,它会崩溃:

using System.IO;
using System.Diagnostics;
...
ProcessStartInfo processToStart = new ProcessStartInfo() 
{   
    FileName = Path.Combine(SDKDirectory, "csrun"),
    Arguments = "/devstore"
};
Process.Start(processToStart);
Run Code Online (Sandbox Code Playgroud)

我试过摆弄一些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

Dav*_*den 22

2015年1月19日更新:

做更多的测试(即运行几个版本)后,我发现WAStorageEmulator.exe状态API是一对夫妇的显著方式(这可能会或可能不会对你如何使用它的影响)实际上打破.

如果用户在现有运行进程与用于启动状态进程的用户之间存在差异,则False即使现有进程正在运行,状态也会报告.此错误的状态报告将导致无法启动如下所示的进程:

C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator>WAStorageEmulator.exe status
Run Code Online (Sandbox Code Playgroud)
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/
Run Code Online (Sandbox Code Playgroud)
C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator>WAStorageEmulator.exe start
Run Code Online (Sandbox Code Playgroud)
Windows Azure Storage Emulator 3.4.0.0 command line tool
Error: Port conflict with existing application.
Run Code Online (Sandbox Code Playgroud)

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

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

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

2015年1月18日更新:

我已经完全改写该代码正常发挥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();
    }
}
Run Code Online (Sandbox Code Playgroud)

并进行相应的测试:

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

原帖:

我将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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Dou*_*ter 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();
        }
    }
Run Code Online (Sandbox Code Playgroud)