public static void LogScriptTelemetryRecord(ref ScriptRuntime runtime) { var envDict = new EnvDictionary(); var record = MakeTelemetryRecord(ref runtime); if (envDict.TelemetryState) { if (envDict.TelemetryState && envDict.TelemetryServerUrl != null && !string.IsNullOrEmpty(envDict.TelemetryServerUrl)) { new Task(() => Telemetry.PostTelemetryRecord(envDict.TelemetryServerUrl, record)).Start(); } if (envDict.TelemetryState && envDict.TelemetryFilePath != null && !string.IsNullOrEmpty(envDict.TelemetryFilePath)) { new Task(() => Telemetry.WriteTelemetryRecord(envDict.TelemetryFilePath, record)).Start(); } } }
public static int Execute(EventHook eventHook, object eventSender, object eventArgs) { var env = new EnvDictionary(); return(ScriptExecutor.ExecuteScript( scriptData: new ScriptData { ScriptPath = eventHook.Script, ConfigScriptPath = eventHook.Script, CommandUniqueId = eventHook.UniqueId, CommandName = string.Format("hooks.{0}", Path.GetFileNameWithoutExtension(eventHook.Script)), CommandBundle = string.Format("{0}.hooks", eventHook.ExtensionName), CommandExtension = eventHook.ExtensionName, HelpSource = "", }, scriptRuntimeCfg: new ScriptRuntimeConfigs { CommandData = null, SelectedElements = new ElementSet(), SearchPaths = new List <string>(eventHook.SearchPaths), Arguments = new List <string>(), EventSender = eventSender, EventArgs = eventArgs, EngineConfigs = " { \"full_frame\" : true } ", RefreshEngine = false, ConfigMode = false, DebugMode = false, ExecutedFromUI = false }, scriptExecConfigs: new ScriptExecutorConfigs { SendTelemetry = env.TelemetryState && env.TelemetryIncludeHooks } )); }
public ScriptRuntime(ScriptData scriptData, ScriptRuntimeConfigs scriptRuntimeCfg) { // setup a new id and timestamp ExecId = CommonUtils.NewShortUUID(); ExecTimestamp = Telemetry.GetTelemetryTimeStamp(); // set data ScriptData = scriptData; ScriptRuntimeConfigs = scriptRuntimeCfg; //env // get the state of variables before command execution; the command could potentially change the values EnvDict = new EnvDictionary(); // apply application override hooks if given if (ScriptRuntimeConfigs.ControlledApp != null) { ControlledApp = ScriptRuntimeConfigs.ControlledApp; } if (ScriptRuntimeConfigs.App != null) { App = ScriptRuntimeConfigs.App; } if (ScriptRuntimeConfigs.UIControlledApp != null) { UIControlledApp = ScriptRuntimeConfigs.UIControlledApp; } if (ScriptRuntimeConfigs.UIApp != null) { UIApp = ScriptRuntimeConfigs.UIApp; } // determine event sender type if (ScriptRuntimeConfigs.EventSender != null) { // detemine sender type if (ScriptRuntimeConfigs.EventSender.GetType() == typeof(UIControlledApplication)) { UIControlledApp = (UIControlledApplication)ScriptRuntimeConfigs.EventSender; } else if (ScriptRuntimeConfigs.EventSender.GetType() == typeof(UIApplication)) { UIApp = (UIApplication)ScriptRuntimeConfigs.EventSender; } else if (ScriptRuntimeConfigs.EventSender.GetType() == typeof(ControlledApplication)) { ControlledApp = (ControlledApplication)ScriptRuntimeConfigs.EventSender; } else if (ScriptRuntimeConfigs.EventSender.GetType() == typeof(Application)) { App = (Application)ScriptRuntimeConfigs.EventSender; } } // prepare results ExecutionResult = ScriptExecutorResultCodes.Succeeded; TraceMessage = string.Empty; }
public void UnRegisterHook(string uniqueId) { var env = new EnvDictionary(); if (env.EventHooks.ContainsKey(uniqueId)) { env.EventHooks.Remove(uniqueId); } }
public static string GetTelemetryTimeStamp() { var env = new EnvDictionary(); if (env.TelemetryUTCTimeStamps) { return(GetISOTimeStamp(DateTime.Now.ToUniversalTime())); // 2019-09-27T23:22:41.1355Z } else { return(GetISOTimeStamp(DateTime.Now)); // 2019-09-27T16:15:56.9528-07:00 } }
public static Assembly CompileCLRScript(ref ScriptRuntime runtime, out List <string> errors) { // https://stackoverflow.com/a/3188953 // read the referenced dlls from env vars // pyrevit sets this when loading List <string> refFiles; var envDic = new EnvDictionary(); if (envDic.ReferencedAssemblies.Length == 0) { var refs = AppDomain.CurrentDomain.GetAssemblies(); refFiles = refs.Select(a => a.Location).ToList(); } else { refFiles = envDic.ReferencedAssemblies.ToList(); } // add location of this assembly refFiles.Add(typeof(ScriptExecutor).Assembly.Location); // create output assembly string outputAssembly = Path.Combine( UserEnv.UserTemp, string.Format("{0}_{1}.dll", runtime.ScriptData.CommandName, runtime.ScriptSourceFileSignature) ); List <string> defines = new List <string> { $"REVIT{runtime.App.VersionNumber}", #if (REVIT2013 || REVIT2014 || REVIT2015 || REVIT2016 || REVIT2017) $"REVIT{runtime.App.VersionNumber}_0" #else $"REVIT{runtime.App.SubVersionNumber.Replace(".", "_")}" #endif }; // determine which compiler to use switch (runtime.EngineType) { case ScriptEngineType.CSharp: return(CompileCSharp(runtime.ScriptSourceFile, outputAssembly, refFiles, defines, runtime.ScriptRuntimeConfigs.DebugMode, out errors)); case ScriptEngineType.VisualBasic: return(CompileVB(runtime.ScriptSourceFile, outputAssembly, refFiles, defines, runtime.ScriptRuntimeConfigs.DebugMode, out errors)); default: throw new PyRevitException("Specified language does not have a compiler."); } }
public void RegisterHook(string uniqueId, string eventName, string eventTarget, string scriptPath, string[] searchPaths, string extensionName) { if (EventHook.IsValid(eventName)) { var env = new EnvDictionary(); env.EventHooks[uniqueId] = new Dictionary <string, string> { { EventHook.id_key, uniqueId }, { EventHook.name_key, eventName }, { EventHook.target_key, eventTarget }, { EventHook.script_key, scriptPath }, { EventHook.syspaths_key, string.Join(Path.PathSeparator.ToString(), searchPaths) }, { EventHook.extension_name_key, extensionName }, }; } else { throw new PyRevitException("Invalid hook type"); } }
public static List <EventHook> GetAllEventHooks() { var env = new EnvDictionary(); var eventHooks = new List <EventHook>(); foreach (KeyValuePair <string, Dictionary <string, string> > eventHookInfo in env.EventHooks) { var eventName = eventHookInfo.Value[EventHook.name_key]; if (EventHook.IsValid(eventName)) { eventHooks.Add(new EventHook( uniqueId: eventHookInfo.Value[EventHook.id_key], eventName: eventName, eventTarget: eventHookInfo.Value[EventHook.target_key], scriptPath: eventHookInfo.Value[EventHook.script_key], syspaths: eventHookInfo.Value[EventHook.syspaths_key], extension_name: eventHookInfo.Value[EventHook.extension_name_key] )); } } return(eventHooks); }
private string GetStyleSheetFile() { var env = new EnvDictionary(); return(env.ActiveStyleSheet); }
public void UnRegisterAllHooks(UIApplication uiApp) { var env = new EnvDictionary(); env.ResetEventHooks(); }
public static Assembly CompileCLRScript(ref ScriptRuntime runtime) { // https://stackoverflow.com/a/3188953 // read the script var scriptContents = File.ReadAllText(runtime.ScriptSourceFile); // read the referenced dlls from env vars // pyrevit sets this when loading string[] refFiles; var envDic = new EnvDictionary(); if (envDic.ReferencedAssemblies.Length == 0) { var refs = AppDomain.CurrentDomain.GetAssemblies(); refFiles = refs.Select(a => a.Location).ToArray(); } else { refFiles = envDic.ReferencedAssemblies; } // create compiler parameters var compileParams = new CompilerParameters(refFiles); compileParams.OutputAssembly = Path.Combine( UserEnv.UserTemp, string.Format("{0}_{1}.dll", runtime.ScriptData.CommandName, runtime.ScriptSourceFileSignature) ); compileParams.CompilerOptions = string.Format("/optimize /define:REVIT{0}", runtime.App.VersionNumber); compileParams.GenerateInMemory = true; compileParams.GenerateExecutable = false; compileParams.ReferencedAssemblies.Add(typeof(ScriptExecutor).Assembly.Location); // determine which code provider to use CodeDomProvider compiler; var compConfig = new Dictionary <string, string>() { { "CompilerVersion", "v4.0" } }; switch (runtime.EngineType) { case ScriptEngineType.CSharp: compiler = new CSharpCodeProvider(compConfig); break; case ScriptEngineType.VisualBasic: compiler = new VBCodeProvider(compConfig); break; default: throw new PyRevitException("Specified language does not have a compiler."); } // compile code first var res = compiler.CompileAssemblyFromSource( options: compileParams, sources: new string[] { scriptContents } ); return(res.CompiledAssembly); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { // 1: ---------------------------------------------------------------------------------------------------- #region Processing modifier keys // Processing modifier keys bool refreshEngine = false; bool configScriptMode = false; bool forcedDebugMode = false; bool ALT = Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt); bool SHIFT = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift); bool CTRL = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl); bool WIN = Keyboard.IsKeyDown(Key.LWin) || Keyboard.IsKeyDown(Key.RWin); // If Ctrl+Alt+Shift clicking on the tool run in clean engine if (CTRL && ALT && SHIFT) { refreshEngine = true; } // If Alt+Shift clicking on button, open the context menu with options. else if (SHIFT && WIN) { // start creating context menu ContextMenu pyRevitCmdContextMenu = new ContextMenu(); // menu item to open help url if exists if (ScriptData.HelpSource != null && ScriptData.HelpSource != "") { MenuItem openHelpSource = new MenuItem(); openHelpSource.Header = "Open Help"; openHelpSource.ToolTip = ScriptData.HelpSource; openHelpSource.Click += delegate { System.Diagnostics.Process.Start(ScriptData.HelpSource); }; pyRevitCmdContextMenu.Items.Add(openHelpSource); } // menu item to copy script path to clipboard MenuItem copyScriptPath = new MenuItem(); copyScriptPath.Header = "Copy Script Path"; copyScriptPath.ToolTip = ScriptData.ScriptPath; copyScriptPath.Click += delegate { System.Windows.Forms.Clipboard.SetText(ScriptData.ScriptPath); }; pyRevitCmdContextMenu.Items.Add(copyScriptPath); // menu item to copy config script path to clipboard, if exists if (ScriptData.ConfigScriptPath != null && ScriptData.ConfigScriptPath != "") { MenuItem copyAltScriptPath = new MenuItem(); copyAltScriptPath.Header = "Copy Config Script Path"; copyAltScriptPath.ToolTip = ScriptData.ConfigScriptPath; copyAltScriptPath.Click += delegate { System.Windows.Forms.Clipboard.SetText(ScriptData.ConfigScriptPath); }; pyRevitCmdContextMenu.Items.Add(copyAltScriptPath); } // menu item to copy bundle path to clipboard var bundlePath = Path.GetDirectoryName(ScriptData.ScriptPath); MenuItem copyBundlePath = new MenuItem(); copyBundlePath.Header = "Copy Bundle Path"; copyBundlePath.ToolTip = bundlePath; copyBundlePath.Click += delegate { System.Windows.Forms.Clipboard.SetText(bundlePath); }; pyRevitCmdContextMenu.Items.Add(copyBundlePath); // menu item to copy command unique name (assigned by pyRevit) to clipboard MenuItem copyUniqueName = new MenuItem(); copyUniqueName.Header = "Copy Unique Id"; copyUniqueName.ToolTip = ScriptData.CommandUniqueId; copyUniqueName.Click += delegate { System.Windows.Forms.Clipboard.SetText(ScriptData.CommandUniqueId); }; pyRevitCmdContextMenu.Items.Add(copyUniqueName); // menu item to copy command unique name (assigned by pyRevit) to clipboard MenuItem copyControlIdName = new MenuItem(); copyControlIdName.Header = "Copy Control Id"; copyControlIdName.ToolTip = ScriptData.CommandControlId; copyControlIdName.Click += delegate { System.Windows.Forms.Clipboard.SetText(ScriptData.CommandControlId); }; pyRevitCmdContextMenu.Items.Add(copyControlIdName); // menu item to copy ;-separated sys paths to clipboard // Example: "path1;path2;path3" MenuItem copySysPaths = new MenuItem(); string sysPathsText = string.Join(Environment.NewLine, ScriptRuntimeConfigs.SearchPaths); copySysPaths.Header = "Copy Sys Paths"; copySysPaths.ToolTip = sysPathsText; copySysPaths.Click += delegate { System.Windows.Forms.Clipboard.SetText(sysPathsText); }; pyRevitCmdContextMenu.Items.Add(copySysPaths); // menu item to copy ;-separated arguments to clipboard // Example: "path1;path2;path3" MenuItem copyArguments = new MenuItem(); string argumentsText = string.Join(Environment.NewLine, ScriptRuntimeConfigs.Arguments); copyArguments.Header = "Copy Arguments"; copyArguments.ToolTip = argumentsText; copyArguments.Click += delegate { System.Windows.Forms.Clipboard.SetText(argumentsText); }; pyRevitCmdContextMenu.Items.Add(copyArguments); if (argumentsText == null || argumentsText == string.Empty) { copyArguments.IsEnabled = false; } // menu item to copy engine configs MenuItem copyEngineConfigs = new MenuItem(); string engineCfgs = ScriptRuntimeConfigs.EngineConfigs; copyEngineConfigs.Header = "Copy Engine Configs"; copyEngineConfigs.ToolTip = engineCfgs; copyEngineConfigs.Click += delegate { System.Windows.Forms.Clipboard.SetText(engineCfgs); }; pyRevitCmdContextMenu.Items.Add(copyEngineConfigs); if (engineCfgs == null || engineCfgs == string.Empty) { copyEngineConfigs.IsEnabled = false; } // menu item to copy help url MenuItem copyHelpSource = new MenuItem(); copyHelpSource.Header = "Copy Help Url"; copyHelpSource.ToolTip = ScriptData.HelpSource; copyHelpSource.Click += delegate { System.Windows.Forms.Clipboard.SetText(ScriptData.HelpSource); }; pyRevitCmdContextMenu.Items.Add(copyHelpSource); if (ScriptData.HelpSource == null || ScriptData.HelpSource == string.Empty) { copyHelpSource.IsEnabled = false; } // open the menu pyRevitCmdContextMenu.IsOpen = true; return(Result.Succeeded); } // If Ctrl+Shift clicking on button, run the script in debug mode and run config script instead. else if (CTRL && (SHIFT || ExecConfigs.UseConfigScript)) { configScriptMode = true; forcedDebugMode = true; } // If Alt clicking on button, open the script in explorer and return. else if (SHIFT && ALT) { // combine the arguments together // it doesn't matter if there is a space after ',' if (ScriptExecutor.EnsureTargetScript(ScriptData.ConfigScriptPath)) { string argument = "/select, \"" + ScriptData.ConfigScriptPath + "\""; System.Diagnostics.Process.Start("explorer.exe", argument); } return(Result.Succeeded); } else if (ALT) { // combine the arguments together // it doesn't matter if there is a space after ',' if (ScriptExecutor.EnsureTargetScript(ScriptData.ScriptPath)) { string argument = "/select, \"" + ScriptData.ScriptPath + "\""; System.Diagnostics.Process.Start("explorer.exe", argument); } return(Result.Succeeded); } // If Shift clicking on button, run config script instead else if (SHIFT || ExecConfigs.UseConfigScript) { configScriptMode = true; } // If Ctrl clicking on button, set forced debug mode. else if (CTRL) { forcedDebugMode = true; } #endregion // 2: ---------------------------------------------------------------------------------------------------- #region Setup pyRevit Command Runtime Configs // fill in the rest of runtime info ScriptRuntimeConfigs.CommandData = commandData; ScriptRuntimeConfigs.SelectedElements = elements; ScriptRuntimeConfigs.RefreshEngine = refreshEngine; ScriptRuntimeConfigs.ConfigMode = configScriptMode; ScriptRuntimeConfigs.DebugMode = forcedDebugMode; ScriptRuntimeConfigs.ExecutedFromUI = ExecConfigs.MimicExecFromUI; #endregion // 3: ---------------------------------------------------------------------------------------------------- #region Execute and log results // Executing the script and logging the results // Get script executor and Execute the script var env = new EnvDictionary(); int result = ScriptExecutor.ExecuteScript( ScriptData, ScriptRuntimeConfigs, new ScriptExecutorConfigs { SendTelemetry = env.TelemetryState } ); // Return results to Revit. Don't report errors since we don't want Revit popup with error results if (result == 0) { return(Result.Succeeded); } else { return(Result.Cancelled); } #endregion }