How to start Azure Storage Emulator from within a program - c#

I have some unit tests that use Azure Storage. When running these locally, I want them to use the Azure Storage emulator which is part of the Azure SDK v1.5. If the emulator isn't running, I want it to be started.
To start the emulator from the command line, I can use this:
"C:\Program Files\Windows Azure SDK\v1.5\bin\csrun" /devstore
This works fine.
When I try to start it using this C# code, it crashes:
using System.IO;
using System.Diagnostics;
...
ProcessStartInfo processToStart = new ProcessStartInfo()
{
FileName = Path.Combine(SDKDirectory, "csrun"),
Arguments = "/devstore"
};
Process.Start(processToStart);
I've tried fiddling with a number of ProcessStartInfo settings, but nothing seems to work. Is anybody else having this problem?
I've checked the Application Event Log and found the following two entries:
Event ID: 1023
.NET Runtime version 2.0.50727.5446 - Fatal Execution Engine Error (000007FEF46B40D2) (80131506)
Event ID: 1000
Faulting application name: DSService.exe, version: 6.0.6002.18312, time stamp: 0x4e5d8cf3
Faulting module name: mscorwks.dll, version: 2.0.50727.5446, time stamp: 0x4d8cdb54
Exception code: 0xc0000005
Fault offset: 0x00000000001de8d4
Faulting process id: 0x%9
Faulting application start time: 0x%10
Faulting application path: %11
Faulting module path: %12
Report Id: %13

Updated 7/12/2022:
If you are running Visual Studio 2022, azurite.exe is the replacement for the now-deprecated AzureStorageEmulator.exe which can be found here:
C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\Extensions\Microsoft\Azure Storage Emulator\azurite.exe
NB: if you are running Professional (or another) Edition, you'll need to replace Community with Professional (or the appropriate edition name) in the path.
Updated 1/19/2015:
After doing more testing (i.e., running several builds), I've discovered that WAStorageEmulator.exe's status API is actually broken in a couple of significant ways (which may or may not have impact on how you use it).
The status reports False even when an existing process is running if the user differs between the existing running process and the user used to launch the status process. This incorrect status report will lead to a failure to launch the process that looks like this:
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.
Additionally, the status command appears only to report the endpoints specified in WAStorageEmulator.exe.config, not those of the existing running process. I.e., if you start the emulator, then make a change to the config file, and then call status, it will report the endpoints listed in the config.
Given all of these caveats, it may, in fact, simply be better to use the original implementation as it appears to be more reliable.
I will leave both so others can choose whichever solution works for them.
Updated 1/18/2015:
I have fully rewritten this code to properly leverage WAStorageEmulator.exe's status API per #RobertKoritnik's request.
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();
}
}
And the corresponding tests:
[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);
}
}
Original post:
I took Doug Clutter's and Smarx's code one step further and created a utility class:
The code below has been updated to work on both Windows 7 and 8 and now points at the new storage emulator path as of 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();
}
}
}

This program worked fine for me. Give it a try, and if it works for you too, work backwards from there. (What about your app is different from this?)
using System.Diagnostics;
public class Program
{
public static void Main() {
Process.Start(#"c:\program files\windows azure sdk\v1.5\bin\csrun", "/devstore").WaitForExit();
}
}

The file name in v4.6 is "AzureStorageEmulator.exe". The full path is: "C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator\AzureStorageEmulator.exe"

For Windows Azure Storage Emulator v5.2, the following helper class can be used to start the emulator:
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;
}
}
[Thanks to huha for the boilerplate code to execute a shell command.]

FYI - The 1.6 default location is C:\Program Files\Windows Azure Emulator\emulator as stated on the MSDN docs.

We are running into the same issue. We have the concept of a "smoke test" which runs between groups of tests, and which ensure the environment is in a good state before the next group starts. We have a .cmd file that kicks off the smoke tests, and it works just fine starting the devfabric emulator, but the devstore emulator only runs as long as the .cmd process runs.
Apparently the implementation of the DSServiceSQL.exe is different than DFService.exe. DFService seems to run like a windows service - kick it off, and it keeps running. DSServiceSQL dies as soon as the process that started it dies.

I uninstalled all of the Windows Azure bits:
WA SDK v1.5.20830.1814
WA Tools for Visual Studio: v1.5.40909.1602
WA AppFabric: v1.5.37
WA AppFabric: v2.0.224
Then, I downloaded and installed everything using the unified installer. Everything came back except the AppFabric v2. All the version numbers are the same. Reran my tests and still having a problem.
And then...(this is weird)...it would work every now and then. Rebooted the machine and now it works. Have shutdown and rebooted a number of times now...and it just works. (sigh)
Thanks to everyone who provided feedback and/or ideas!
The final code is:
static void StartAzureStorageEmulator()
{
ProcessStartInfo processStartInfo = new ProcessStartInfo()
{
FileName = Path.Combine(SDKDirectory, "csrun.exe"),
Arguments = "/devstore",
};
using (Process process = Process.Start(processStartInfo))
{
process.WaitForExit();
}
}

maybe caused by file not found?
try this
FileName = Path.Combine(SDKDirectory, "csrun.exe")

Here we go: Pass the string "start" to the method ExecuteWAStorageEmulator().
The NUnit.Framework is used for the Assert only.
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;
}
See also my new self-answered question

There's now a neat little NuGet package to assist with starting/stopping the Azure Storage Emulator programmatically: RimDev.Automation.StorageEmulator.
The source code is available in this GitHub repository, but you can essentially do things like this:
if(!AzureStorageEmulatorAutomation.IsEmulatorRunning())
{
AzureStorageEmulatorAutomation emulator = new AzureStorageEmulatorAutomation();
emulator.Start();
// Even clear some things
emulator.ClearBlobs();
emulator.ClearTables();
emulator.ClearQueues();
emulator.Stop();
}
It feels like the cleanest option to me.

Related

Check if an instance of an application is open

Could someone show how could I check if an instance of VS is open and if so I need to show a message.
private String MSBUILD = File.Exists(#"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe") == true
? #"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe"
: #"C:\LegacyApp\Microsoft Visual Studio\MSBuild\15.0\Bin\MSBuild.exe";
This is my path to the VS directory. I need to check if it's open and if it's open I need to show a message that is saying you need to close the previous one before you open another.
In c# you can use "Process.GetProcessesByName()" for check if process is running. To see name of program use "Task Manager - Services".
Get current process-application name with "Process.GetCurrentProcess().ProcessName".
Combining all will give you
bool isAlreadyWorking = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1;
When an application is running, it is called a process in the context of the operating system. In c# you can use the Process.GetProcessById(), Process.GetProcessesByName() .
using System;
using System.Diagnostics;
namespace check_if_process_is_running
{
class Program
{
static bool isRunning(string name)
{
try {
Process.GetProcessByName(name);
}
catch (InvalidOperationException) {
return false;
}
catch (ArgumentException) {
return false;
}
return true;
}
static void Main(string[] args)
{
bool running = isRunning("devenv.exe");
if (running)
{
Console.WriteLine("Running");
}
else
{
Console.WriteLine("Not Running");
}
}
}
}

Process.Responding detects process exit, while process runs

I have trouble with checking if a process is still running.
I created a small program that should keep 2 programs up and running.
For this example I use Notepad and windows calculator.
The Code below will launch both applications, but its failing on checking their running state by their process.checkalive propert also hasexited fails.
Notice that the sample program uses a class Apprunner to handle multiple applications. After launching both applications it crashes with:
System.InvalidOperationException:
'Process has exited, so the requested information is not available.'
Despite that both programs Notepad.exe and Calc.exe are running.
Code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace watchdog
{
class AppRunner
{
public Process Program;
public AppRunner(ProcessStartInfo processrunner)
{
this.Program = new Process();
this.Program.StartInfo = processrunner;
StartExecute();
}
public void StartExecute()
{
this.Program.Start();
}
public bool checkAlive()
{
this.Program.Refresh();
return (bool)this.Program.Responding;
//fails
// also failing as true => return this.Program.HasExited;
//(its not true app still runs)
}
public void KeepEmRunning()
{
if (!checkAlive())
{
StartExecute();
}
}
}
//-----------main prog - - - - -
class Program
{
static void Main(string[] args)
{
List<AppRunner> programs = new List<AppRunner>();
ProcessStartInfo prog = new ProcessStartInfo();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Windows\system32\Notepad.exe";
programs.Add(new AppRunner(startInfo));
startInfo.FileName = #"C:\Windows\system32\Calc.exe";
programs.Add(new AppRunner(startInfo));
string s;
do
{
System.Threading.Thread.Sleep(1000);// wait for start.
Console.WriteLine("Notepad" + programs[0].checkAlive());
Console.WriteLine("Calc" + programs[1].checkAlive());
Console.WriteLine("press X for exit other key for update");
s = Console.ReadLine().ToUpper();
} while (s != "X");
}
}
}
Code running on Windows 10, and vs2017 its a .net 4.6 console app.
Process.Responding throws an exception if the process has already exited. I guess Responding's purpose is to check if the process is dead-locked or still working, but doesn't work if the process is gone already.
Calc.exe indeed immediatly returns, after starting Calculator.exe (see TaskManager). So the result you observe is correct: the process you started for calc.exe has already exited, although you still see a calculator window.

Script Error when open .chm disappear when opening through the debugger

I get a number of script errors and none of the images will be shown when I open a .chm file on my computer. If I esc all error messages and refresh (twice) then the .chm is shown correctly. Although I need to do this for each new page.
I have made all recommended fixes for .chm files! Reregistrered, unblocked, fixed paths,... The errors is for all .chm on the machine
But, here is my real question, if I run this program, with a .chm file as argument, through the Visual Studio 2013 debugger then the .chm is shown correctly!
The problem is probably in my Windows configuration, but somehow the debugger "fixes" this error and get it to work. Does the debugger have it's own configuration that isn't dependent on the actual Windows configuration?
using System.Diagnostics;
namespace xcute
{
class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
string f = args[0];
Process.Start(f);
}
}
}
}
EDIT: Here are the error dialogs
I have found the problem (well sort of)!
If I open the .chm as administrator then everything works! So obviously I have some permission error on my computer. The reason it worked when I ran my program in the debugger is that Visual Studio is started as Administrator...
But since I'm a programmer I solved the issue by creating a small program that start hh.exe as admin. I get the UAC consent form but I can live with that.
// Anders
The program:
internal class Program
{
private static void Main(string[] args)
{
if (args.Length > 0)
{
Execute(args[0]);
}
}
private static void Execute(string chmFile)
{
const int ERROR_CANCELLED = 1223; //The operation was canceled by the user.
ProcessStartInfo info = new ProcessStartInfo(#"C:\Windows\hh.exe");
info.Arguments = chmFile;
info.UseShellExecute = true;
info.Verb = "runas";
try
{
Process.Start(info);
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ERROR_CANCELLED)
Console.WriteLine("Why you no select Yes?");
else
throw;
}
}
}

Why do i get Error when i try to run or start my win service?

I have a windows service which i can't run or start, only install or directly debug the project.
This is my main:
namespace MyService
{
public static class Program
{
private static void Main()
{
var ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
}
}
And this is my Service:
public partial class Service : ServiceBase
{
private dynamic _serviceHost;
public Service()
{
this.InitializeComponent();
this.ServiceName = "MyService";
this.CanShutdown = true;
this.CanStop = true;
}
private static string HostName
{
get
{
string hostName = Dns.GetHostName();
IPHostEntry ipHostEntry = Dns.GetHostEntry(hostName);
return ipHostEntry.HostName;
}
}
protected override void OnStart(string[] args)
{
var worker = new Thread(this.InitializeHost) { Name = "Host", IsBackground = false };
worker.Start();
}
private void InitializeHost()
{
var baseAddress = new Uri(string.Format("net.tcp://{0}:{1}/MyService", HostName, "9020"));
var mexAddress = new Uri(string.Format("http://{0}:{1}/MyService", HostName, "8000"));
var cache = Factory.Create<string>("MyAssembly.MyClass", "MyAssembly");
var service = new ServiceWcf<string>(cache);
using (this._serviceHost = new Host<string>(service))
{
this._serviceHost.Open(baseAddress, mexAddress);
}
}
protected override void OnStop()
{
this._serviceHost.Dispose();
}
}
When I try to run without debugging or to start after installing the service i get the following error:
Run (directly or through VS):
Error while trying to run project: Unable to start program
'C:\path\to\my\projects\bin\Release\MyService.exe'.
The system cannot find the specified path.
Service start:
The service "MyService" on local cimpouter could not be started.
Error 3: The system cannot find the specified path.
I have no clue where the error could be.
EDIT:
private void InitializeComponent()
{
this.serviceProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller();
this.serviceInstaller = new System.ServiceProcess.ServiceInstaller();
//
// serviceProcessInstaller
//
this.serviceProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem;
this.serviceProcessInstaller.Password = null;
this.serviceProcessInstaller.Username = null;
//
// serviceInstaller
//
this.serviceInstaller.ServiceName = "MyService";
this.serviceInstaller.DisplayName = "My service";
this.serviceInstaller.Description = "My service is awesome.";
this.serviceInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller,
this.serviceInstaller});
}
I think this is just an issue with how the service has been registered - i.e. it's in the wrong place.
run an installutil /u [service] from a VS command prompt to uninstall any service entries you already have.
CD over to the folder where you want to run the service from - be careful here, you will have both a debug and a release build - which one do you want to be installed in the services list?
Use installutil /i [service] on the exe to reinstall.
Now it should work.
I think you might have registered the debug build first and have subsequently run a Clean operation on the build before building the Release version; thus deleting the original executable. Either that - or perhaps you moved the project after originally developing it?
Many of the developers I work with use a different folder for their local service installations that is always the same; they then deploy either a debug or release version to it; thus when they want to switch between the two they just copy different file versions over. I don't do this - I only ever register the debug build; but then I have more work to do when testing the release build :)

After updating EnvironmentVariable - PATH - I still get a FileNotFoundException on Windows 2003 Server

I'm just starting with a new product and I guess I don't understand the PATH variable. My documentation says to update the PATH like this which I do successfully in a little console application:
using HP.HPTRIM.SDK;
namespace TestSDKforTRIM71
{
class Program
{
static void Main(string[] args)
{
string trimInstallDir = #"C:\Program Files\Hewlett-Packard\HP TRIM";
string temp = Environment.GetEnvironmentVariable("PATH") + ";" + trimInstallDir;
Environment.SetEnvironmentVariable("PATH", temp);
DoTrimStuff();
}
public static void DoTrimStuff()
{
using (Database db = new Database())
{
db.Connect();
Console.WriteLine(db.Id);
}
Console.ReadKey();
}
}
}
In the above project, I have a reference to HP.HPTRIM.SDK which exists at:
C:\Program Files\Hewlett-Packard\HP TRIM\HP.HPTRIM.SDK.dll
After the above ran successfully, I tried to permanently change the PATH by using Control Panel:System:Advanced:Environment Variables. I verified the above PATH by examining the registry at HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. I see the following as the last entry in the PATH value:
;C:\Program Files\Hewlett-Packard\HP TRIM\
I thought this would permanently SET this at the end of the PATH but when I run the above console program with a few lines commented out I get the FileNotFoundException (see below). I am confused about how to get this in the PATH and not have to worry about it anymore.
using HP.HPTRIM.SDK;
namespace TestSDKforTRIM71
{
class Program
{
static void Main(string[] args)
{
//string trimInstallDir = #"C:\Program Files\Hewlett-Packard\HP TRIM";
//string temp = Environment.GetEnvironmentVariable("PATH") + ";" + trimInstallDir;
//Environment.SetEnvironmentVariable("PATH", temp);
DoTrimStuff(); // without setting the PATH this fails despite being in REGISTRY...
}
public static void DoTrimStuff()
{
using (Database db = new Database())
{
db.Connect();
Console.WriteLine(db.Id);
}
Console.ReadKey();
}
}
}
Only newly started processes that don't inherit their environment from their parent will have the updated PATH. You'll have to at least restart the Visual Studio hosting process, close and re-open your solution. To cover all possible corners, log out and log back in so that Windows Explorer (and thus Visual Studio) also start using the updated environment.

Categories

Resources