Search code examples
c#autocadobjectarx

How to wait until an Acad's instance runs to create e new documents?


I'm using objectARX and trying to create a new document. What i'm doing first is to run AutoCad.

Process acadApp = new Process();
            acadApp.StartInfo.FileName = "C:/Program Files/Autodesk/AutoCAD 2015/acad.exe";
            acadApp.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
            acadApp.Start();

Then the problem is when I wait until the instance of Acad is ready. I can't get The process by his name with the Process class because Autocad window is not ready yet and I can't create the AcadApplication instance. It only works when Autocad is completely loaded so I use .

bool checkInstance = true;
            //This piece of pure shit listen for an Acad instnce until this is opened
            while (checkInstance)
            {
                try
                {
                    var checkinstance = Marshal.GetActiveObject("AutoCAD.Application");
                    checkInstance = false;
                }
                catch (Exception ex)
                {

                }
            }
            //Once the acad instance is opende The show starts
            Thread.Sleep(12000);
            Thread jili2 = new Thread(new ThreadStart(() => acadG.AcadGrid(Convert.ToInt32(grid.floorHeight), Convert.ToInt32(grid.floorWidth), grid.numFloors)));
            jili2.Start();
           // MessageBox.Show("I don't know why it was executed");
        }

The acadGrid Method running in the thread creates a new document in AutoCad and then draws a grid. It sometimes works and sometimes not, and when it works it uses even 50% of CPU. Sometimes i gett this exception. enter image description here


Solution

  • Process.WaitForInputIdle and Application.GetAcadState can help:

    Process acadProc = new Process();
    acadProc.StartInfo.FileName = "C:/Program Files/Autodesk/AutoCAD 2015/acad.exe";
    acadProc.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
    acadProc.Start();
    if (!acadProc.WaitForInputIdle(300000))
      throw new ApplicationException("Acad takes too much time to start.");
    AcadApplication acadApp;
    while (true)
    {
      try
      {
        acadApp = Marshal.GetActiveObject("AutoCAD.Application.20");
        return;
      }
      catch (COMException ex)
      {
        const uint MK_E_UNAVAILABLE = 0x800401e3;
        if ((uint) ex.ErrorCode != MK_E_UNAVAILABLE) throw;
        Thread.Sleep(1000);
      }
    }
    while (true)
    {
      AcadState state = acadApp.GetAcadState();
      if (state.IsQuiescent) break;
      Thread.Sleep(1000);
    }