Setting and accessing USERS1 variable

Setting and accessing USERS1 variable

TK_Rao5AR2
Participant Participant
360 Views
3 Replies
Message 1 of 4

Setting and accessing USERS1 variable

TK_Rao5AR2
Participant
Participant

Here is something interesting that I thought I knew well for decades.

I thought USERS1 is a setvar that can be set and accessed. This is true as long as I am in the same  API context, meaning if I am using COM (ActiveX) then this is set and returned in a document context. If I am using .Net then it can only be set using Application.SetSystemVariable and accessed using Application.GetSystemVariable.

 

My situation is that I want to set this in .Net using Application.SetSystemVariable and access it from COM that is out of process. I am unable to get the desired value here. Can someone shed more light on these USERS1 variables and the context it is created?

 

Note: I know USERS1 is not saved anywhere and is temporary.

 

Thanks,

-Thilak Rao

0 Likes
361 Views
3 Replies
Replies (3)
Message 2 of 4

norman.yuan
Mentor
Mentor

@TK_Rao5AR2 wrote:

...

My situation is that I want to set this in .Net using Application.SetSystemVariable and access it from COM that is out of process. I am unable to get the desired value here. Can someone shed more light on these USERS1 variables and the context it is created?

 

Note: I know USERS1 is not saved anywhere and is temporary.

 

Thanks,

-Thilak Rao


You did not describe how you are "...unable to get desired value...". However, the knowledge you knew well for decades still remains true: there is only one value of each USERSx variable, regardless how its value being set (manually at command line, with code of different APIs of LISP/COM/.NET), or where it is accessed to (from in-process, or out-process).

 I took a bit of time to write some simply code and recorded the code execution in video clip to prove it here.

 

This is a console app that uses AutoCAD COM API to get AutoCAD's USERS1 value:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AcadComAutomationApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Do you want to start an AutoCAD session? (Y/N):");
            var an = Console.ReadLine();
            if (!an.ToUpper().StartsWith("Y")) return;

            var comAcad = new Autodesk.AutoCAD.Interop.AcadApplication();
            comAcad.Visible = true;
            while(true)
            {
                if (comAcad.ActiveDocument!=null)
                {
                    var users1 = comAcad.ActiveDocument.GetVariable("USERS1").ToString();
                    Console.WriteLine($"System variable \"USERS1\" -> {users1}");
                    Console.WriteLine("Press any key to get value again, \"X\" to quit:");
                    an = Console.ReadLine();
                    if (an.ToUpper().StartsWith("X"))
                    {
                        break;
                    }
                }
                else
                {
                    Console.WriteLine("\nNo drawing is opened in AutoCAD.");
                    Console.WriteLine("Preaa any key toopen a new/existing drawing in AutoCAD");
                    Console.WriteLine("Or press \"X\" to quit:");
                    an = Console.ReadLine();
                    if (an.ToUpper().StartsWith("X"))
                    {
                        break;
                    }
                }
            }
        }
    }
}

 

 

Here is a simple .NET plugin's CommandMethod that set USERS1:

 

        [CommandMethod("SetUserS1")]
        public static void SetUserS1Variable()
        {
            var dwg = CadApp.DocumentManager.MdiActiveDocument;
            var ed = dwg.Editor;

            var res = ed.GetString("\nEnter value for \"USERS1\":");
            if (res.Status == PromptStatus.OK)
            {
                CadApp.SetSystemVariable("USERS1", res.StringResult);
            }
        }

 

 

Here is how to run the code to prove USERS1 value is the same when accessed from the out-process (the console app) regardless how it is set:

 

1. Start the console app, which would start a new AutoCAD session;

2. In AutoCAD command line. enter "USERS1" to set its value manually;

3. Go back to the console app, press any key to read "USERS1" value from AutoCAD;

4. Go back to AutoCAD, load the .NET plugin and run command "SetUserS1" to set a new value to "USERS1";

5. Go back to the console app, press any key to read "USERS1" value again.

 

You can see that regardless how the value is set - manually, or by .NET API, the out-process app always get the latest USERS1 value, as expected. If your code does not get the "desired value", it is something wrong with your code, for sure.

 

To further prove what I described, see the video clip here:

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 4

ActivistInvestor
Mentor
Mentor

I'm assuming that you are aware that USERSx system variables have document scope, and therefore have a different value for each document. So, the value assigned or returned is always the value associated with the active document. 

0 Likes
Message 4 of 4

thilak.rao
Participant
Participant

Thank you both for your responses. May be I was doing something incorrect earlier as your code works just fine.

0 Likes