public static void Main(string[] args) { try { //Allows us to group device runs for logging purposes RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); ParallelProcessObserver = new ProcessObserver(); Trace.Listeners.Add(new TextWriterTraceListener("ParallelDeviceOutput.log", "myListener")); //Get the devices to run for string currentPath = Directory.GetCurrentDirectory(); string baseProjectPath = Path.GetFullPath(Path.Combine(currentPath, @"..\..\..\")); ParameterRetriever retriever = new ParameterRetriever(); PerfectoTestParams testParams = retriever.GetVSOExecParam(baseProjectPath, true); if (testParams.Devices.Count < 0) { Console.WriteLine("No devices found from JSON config file."); #if DEBUG Console.ReadKey(); #endif return; } //Now create a mutex so that this console app can only be run 1 at a time. // get application GUID as defined in AssemblyInfo.cs string appGuid = "PerfectoParallelRunner-82678dc5439649959b6e0b686efb1222"; // unique id for global mutex - Global prefix means it is global to the machine string mutexId = string.Format("Global\\{{{0}}}", appGuid); // Need a place to store a return value in Mutex() constructor call bool createdNew; var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var securitySettings = new MutexSecurity(); securitySettings.AddAccessRule(allowEveryoneRule); using (var mutex = new Mutex(false, mutexId, out createdNew, securitySettings)) { var hasHandle = false; try { try { hasHandle = mutex.WaitOne(5000, false); if (hasHandle == false) { throw new TimeoutException("Make sure another Test Process isn't already running."); } } catch (AbandonedMutexException) { // Log the fact that the mutex was abandoned in another process, it will still get acquired hasHandle = true; } // Perform your work here. RunParallelExecutions(testParams); } finally { if (hasHandle) { mutex.ReleaseMutex(); } } } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); #if DEBUG Console.ReadKey(); #endif throw; } }
public static void Main(string[] args) { try { //Allows us to group device runs for logging purposes RunIdentifier = string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now); ParallelProcessObserver = new ProcessObserver(); Trace.Listeners.Add(new TextWriterTraceListener("ParallelDeviceOutput.log", "myListener")); /*Args Note: * Having difficulty sending in separated args from Powershell * when there are spaces in the arguments, they split up the where statment. * Need to do some special handling to get around this. Using an "^" to split incoming args * * Expecting possiblity of: a:TheTestAssembly.dll^w:category==xyz AND category==123 */ var joinedArgs = string.Join(" ", args); Console.WriteLine("arguments are: " + joinedArgs); var argsSplit = string.IsNullOrWhiteSpace(joinedArgs) ? null : joinedArgs.Split('^'); string assemblyArgs = ""; string whereFilter = ""; if (argsSplit != null && argsSplit.Length > 0) { foreach (string arg in argsSplit) { Console.WriteLine("Reading Arg:" + arg); if (arg.StartsWith("a:")) { assemblyArgs = arg.Substring(2); } if (arg.StartsWith("w:")) { whereFilter = arg.Substring(2); } } } else { Console.WriteLine("No assembly passed in so using VSTSDigitalDemoTests.dll"); assemblyArgs = "VSTSDigitalDemoTests.dll"; } //Get the devices to run for string currentPath = Directory.GetCurrentDirectory(); string baseProjectPath = Path.GetFullPath(Path.Combine(currentPath, @"..\..\..\")); ParameterRetriever retriever = new ParameterRetriever(); PerfectoTestParams testParams = retriever.GetVSOExecParam(baseProjectPath, true); if (testParams.Devices.Count < 0) { Console.WriteLine("No devices found from JSON config file."); #if DEBUG Console.ReadKey(); #endif return; } //Now create a mutex so that this console app can only be run 1 at a time. // get application GUID as defined in AssemblyInfo.cs string appGuid = "PerfectoParallelRunner-82678dc5439649959b6e0b686efb1222"; // unique id for global mutex - Global prefix means it is global to the machine string mutexId = string.Format("Global\\{{{0}}}", appGuid); // Need a place to store a return value in Mutex() constructor call bool createdNew; var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow); var securitySettings = new MutexSecurity(); securitySettings.AddAccessRule(allowEveryoneRule); using (var mutex = new Mutex(false, mutexId, out createdNew, securitySettings)) { var hasHandle = false; try { try { hasHandle = mutex.WaitOne(5000, false); if (hasHandle == false) { throw new TimeoutException("Make sure another Test Process isn't already running."); } } catch (AbandonedMutexException) { // Log the fact that the mutex was abandoned in another process, it will still get acquired hasHandle = true; } // Perform your work here. RunParallelExecutions(assemblyArgs, whereFilter, testParams); } finally { if (hasHandle) { mutex.ReleaseMutex(); } } } } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); #if DEBUG Console.ReadKey(); #endif throw; } }