Typically, to achieve this, one has to
1. Save a system variable's current value to variable that is value in the entire scope of the process;
2. Change then system variable's value as desired before the process begins;
3. Right after the process ends, reset the changed system variable to its previously saved original value.
As one can see if the custom process requires change a few variables, writing code to do this would be quite tedious.
We can make this changing/restoring system variable process a lot easier by encapsulating system variable value change in a class.
Here is an fairly simple way to do it:
Code Snippet
- using System.Collections.Generic;
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.EditorInput;
- namespace SysVariables
- {
- public class SysVariableSetter : Dictionary<string, object>
- {
- public void SetSysVariable(string varName, object varValue)
- {
- if (!this.ContainsKey(varName))
- {
- object originalValue = Application.GetSystemVariable(varName);
- this.Add(varName, originalValue);
- }
- Application.SetSystemVariable(varName, varValue);
- }
- public void RestoreSysVariables()
- {
- //Debugging/Demo only code (next 1 line)
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
- foreach (KeyValuePair<string, object> varItem in this)
- {
- //Debugging/demo only code (next 2 lines)
- ed.WriteMessage("\n{0} original value: {1}",
- varItem.Key, varItem.Value);
- ed.WriteMessage("\n{0} current value: {1}",
- varItem.Key, Application.GetSystemVariable(varItem.Key));
- Application.SetSystemVariable(varItem.Key, varItem.Value);
- //Debug/demo code (next 2 lines)
- ed.WriteMessage("\n{0} current value has been restored to {1}",
- varItem.Key, varItem.Value);
- ed.WriteMessage("\n");
- }
- }
- }
- }
Note, Editor referred in the code is purely for the purpose of demo.
Here is the sample code of how to use this class:
Code Snippet
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.EditorInput;
- using Autodesk.AutoCAD.Runtime;
- [assembly: CommandClass(typeof(SysVariables.MyCommands))]
- namespace SysVariables
- {
- public class MyCommands
- {
- [CommandMethod("DoTest")]
- public void DoMyTest()
- {
- Document dwg = Application.DocumentManager.MdiActiveDocument;
- Editor ed = dwg.Editor;
- SysVariableSetter varSetter = new SysVariableSetter();
- try
- {
- //Change sys variable FILEDIA
- varSetter.SetSysVariable("FILEDIA", 0);
- //Do some work here
- //....................
- //Change sys variable BACKGROUNDPLOT
- varSetter.SetSysVariable("BACKGROUNDPLOT", 0);
- //Do plotting here
- //.................
- }
- catch(System.Exception ex)
- {
- ed.WriteMessage("\nError: {0}", ex.ToString());
- }
- finally
- {
- //Restore changed system variables
- varSetter.RestoreSysVariables();
- }
- }
- }
- }
As you can see, instead of using Application.SetSystmVariable() method, one can now change system variables with SysVariableSetter class with the same. one line of code. But there is no need to worry about to save system variable's original value to later restoration.
As long as the custom process is wrapped in a try{...} finally{...} block, a call to SysVariableSetter.RestoreSysVariables() in the finally{...} block will always be executed, thus changed system variables will be restored to their original values.
Update on September 17th, 2012
There is situation that during the execution of our custom developed process, we may want to change a system variable and restore (or even change and restore multiple times) before the process end. For example, we may want to change Object Snap Mode a few times whe we ask user to select someting in the editor and we may not want to just keep change OSMODE syatem variable and only restore it at the finally{...} block at the end of process.
Anyway to make the SysVariableSetter class a bit more flexible to use, I added a method to allow it to restore any changed system variable at any time:
Code Snippet
- public void RestoreVariable(string variableName)
- {
- if (this.ContainsKey(variableName.ToUpper()))
- {
- Application.SetSystemVariable(variableName, this[variableName]);
- this.Remove(variableName.ToUpper());
- }
- }
Now, we can call SetVariable() method at any time and restore any system variable at any time without bothering to save the system variable's original value.