public StackHashScriptResult RunScript(StackHashProduct product, StackHashFile file, StackHashEvent theEvent, StackHashCab cab, String dumpFileName, String scriptName, bool extractCab, StackHashClientData clientData, bool forceRun) { if (product == null) { throw new ArgumentNullException("product"); } if (file == null) { throw new ArgumentNullException("file"); } if (theEvent == null) { throw new ArgumentNullException("theEvent"); } if (cab == null) { throw new ArgumentNullException("cab"); } if (scriptName == null) { throw new ArgumentNullException("scriptName"); } String machineArchitecture = "x86"; // Default to 32 bit. if ((cab.DumpAnalysis != null) && !String.IsNullOrEmpty(cab.DumpAnalysis.MachineArchitecture)) { machineArchitecture = cab.DumpAnalysis.MachineArchitecture; } StackHashScriptResult result = null; bool use32BitDebugger = true; if (machineArchitecture != null) { if ((String.Compare(machineArchitecture, "x64", StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(machineArchitecture, "X64", StringComparison.OrdinalIgnoreCase) == 0)) { use32BitDebugger = false; } } // Unwrap the cab if necessary. String cabFileName = m_ErrorIndex.GetCabFileName(product, file, theEvent, cab); String cabFileFolder = Path.GetDirectoryName(cabFileName); if (!File.Exists(cabFileName)) { throw new StackHashException("Cab file does not exist: " + cabFileName, StackHashServiceErrorCode.CabDoesNotExist); } if (extractCab) { try { Cabs.ExtractCab(cabFileName, cabFileFolder); } catch (System.Exception ex) { if (ex.Message.Contains("The file is not a cabinet") || ex.Message.Contains("corrupt") || ex.Message.Contains("Corrupt")) { // Set the downloaded flag appropriately if different. StackHashCab loadedCab = m_ErrorIndex.GetCab(product, file, theEvent, cab.Id); if (loadedCab != null) { if (loadedCab.CabDownloaded) { loadedCab.CabDownloaded = false; m_ErrorIndex.AddCab(product, file, theEvent, loadedCab, false); } } } throw new StackHashException("Cab file cannot be unpackaged. Try downloading the file from again.", ex, StackHashServiceErrorCode.CabIsCorrupt); } } // Now get the dump filename - mdmp and dmp files should be returned. String[] allDumpFiles = Directory.GetFiles(cabFileFolder, "*.*dmp"); if (allDumpFiles.Length == 0) { return(null); } // Choose the largest dump file to process. String fullDumpFilePath = null; long largestFileSize = 0; foreach (String fileName in allDumpFiles) { FileInfo fileInfo = new FileInfo(fileName); if (fileInfo.Length > largestFileSize) { largestFileSize = fileInfo.Length; fullDumpFilePath = fileName; } } if (!String.IsNullOrEmpty(dumpFileName)) { fullDumpFilePath = cabFileFolder + "\\" + dumpFileName; } // Find the script that the user wants to run. StackHashScriptSettings scriptSettings = m_ScriptManager.LoadScript(scriptName); // Auto generate the script file. String dumpAnalysisFolder = cabFileFolder + "\\Analysis"; if (!Directory.Exists(dumpAnalysisFolder)) { Directory.CreateDirectory(dumpAnalysisFolder); } // Check if the file has already been run. bool runScript = true; String resultsFileName = String.Format(CultureInfo.InvariantCulture, "{0}\\{1}.log", dumpAnalysisFolder, scriptSettings.Name); if (File.Exists(resultsFileName)) { DateTime lastWriteTime = File.GetLastWriteTimeUtc(resultsFileName); if (scriptSettings.LastModifiedDate <= lastWriteTime) { runScript = false; } } String installFolder = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); if (runScript || forceRun) { String overrideSymbolPath = null; String overrideBinaryPath = null; String overrideSourcePath = null; if (m_Debugger.Use32BitDebugger(use32BitDebugger, m_DebuggerSettings)) { overrideSymbolPath = m_DebuggerSettings.SymbolPath.FullPath; overrideBinaryPath = m_DebuggerSettings.BinaryPath.FullPath; overrideSourcePath = null; // Check the script for PSSCOR loading. String clrVersion = String.Empty; if ((cab.DumpAnalysis != null) && (!String.IsNullOrEmpty(cab.DumpAnalysis.DotNetVersion))) { clrVersion = cab.DumpAnalysis.DotNetVersion; } scriptSettings.FixUp(StackHashScriptDumpArchitecture.X86, clrVersion, installFolder); } else { overrideSymbolPath = m_DebuggerSettings.SymbolPath64Bit.FullPath; overrideBinaryPath = m_DebuggerSettings.BinaryPath64Bit.FullPath; overrideSourcePath = null; // Check the script for PSSCOR loading. String clrVersion = String.Empty; if ((cab.DumpAnalysis != null) && (!String.IsNullOrEmpty(cab.DumpAnalysis.DotNetVersion))) { clrVersion = cab.DumpAnalysis.DotNetVersion; } scriptSettings.FixUp(StackHashScriptDumpArchitecture.Amd64, clrVersion, installFolder); } String scriptFileName = Path.GetTempFileName(); scriptSettings.GenerateScriptFile(scriptFileName, resultsFileName, ref overrideSymbolPath, ref overrideBinaryPath, ref overrideSourcePath); DateTime timeOfRun = DateTime.Now.ToUniversalTime(); try { m_Debugger.RunScript(m_DebuggerSettings, use32BitDebugger, scriptFileName, fullDumpFilePath, resultsFileName, overrideSymbolPath, overrideBinaryPath, overrideSourcePath); // Check if the results were generated. If not there must be a command line error so get the output from the // debugger and throw an exception. if (!File.Exists(resultsFileName)) { throw new StackHashException("Debugger Error: " + m_Debugger.StandardError, StackHashServiceErrorCode.DebuggerError); } // Load in the results. result = StackHashScriptResult.MergeAnalysisDumpFiles(resultsFileName); // Add a script run note to the error index. StackHashNoteEntry note = new StackHashNoteEntry(); // MUST KEEP THIS TEXT THE SAME - because it is used as a search string by the BugTrackerTask. note.Note = String.Format(CultureInfo.CurrentCulture, "Script {0} executed", scriptName); if ((clientData == null) || (clientData.ClientName == null)) { note.Source = "Service"; note.User = "******"; } else { note.Source = "StackHash Client"; note.User = clientData.ClientName; } note.TimeOfEntry = timeOfRun; int cabNoteId = m_ErrorIndex.AddCabNote(product, file, theEvent, cab, note); // Report the event to bug tracking plug-ins. m_ErrorIndex.AddUpdate(new StackHashBugTrackerUpdate( StackHashDataChanged.DebugScript, StackHashChangeType.NewEntry, product.Id, file.Id, theEvent.Id, theEvent.EventTypeName, cab.Id, cabNoteId)); } catch (System.Exception ex) { // Add a script run note to the error index. StackHashNoteEntry note = new StackHashNoteEntry(); note.Note = String.Format(CultureInfo.CurrentCulture, "Script {0} execution failed: {1}", scriptName, ex.Message); note.Source = "Service"; if ((clientData == null) || (clientData.ClientName == null)) { note.User = "******"; } else { note.User = clientData.ClientName; } note.TimeOfEntry = timeOfRun; m_ErrorIndex.AddCabNote(product, file, theEvent, cab, note); throw; } finally { if (File.Exists(scriptFileName)) { File.Delete(scriptFileName); } } } return(result); }