AcadApplication for AutoCAD 2022 的位置和使用

Location and usage of AcadApplication for AutoCAD 2022

我正在尝试了解如何让 AutoCAD 识别 运行 实例。但是,我 运行 遇到了一个问题,其中 AcadApplication 未被识别在应用程序中不存在,如下面的代码所述。

我这样做是为了避免必须制作一个直接的插件,而是一个可以单独与 AutoCAD 通信的 WPF 应用程序(创建一个工具包,将来也可以提供与 AutoCAD 无关的功能)。如果这种方法是个坏主意,请随时告诉我,因为我正在寻找解决此问题的最佳方法。

谁能帮助我使此代码适用于 AutoCAD 2022? 目前这是 运行 在 WPF 应用程序 运行 .NET Framework 4.7.2 中(参考是从我安装的 AutoCAD 中手动包含的)

using System.Windows;

using System.Runtime.InteropServices;
using System;

using aD = Autodesk.AutoCAD.ApplicationServices;

namespace
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        aD.Application.AcadApplication acAppComObj = null;
        const string strProgId = "AutoCAD.Application.22";

        public MainWindow()
        {
            InitializeComponent();

            acAppComObj = Marshal.GetActiveObject(strProgId) as aD.Application.AcadApplication;

            // Get a running instance of AutoCAD
            try
            {
                acAppComObj = (aD.Application.AcadApplication)Marshal.GetActiveObject(strProgId);
            }
            catch // An error occurs if no instance is running
            {
                try
                {
                    // Create a new instance of AutoCAD
                    acAppComObj = (aD.Application.AcadApplication)Activator.CreateInstance(Type.GetTypeFromProgID(strProgId), true);
                }
                catch (Exception)
                {
                    // If an instance of AutoCAD is not created then message and exit
                    MessageBox.Show("Instance of 'AutoCAD.Application' could not be created.");

                    return;
                }
            }
        }
    }
}

为了简明扼要地回答我的问题,我如何使用 AcadApplication 类型,我从哪里访问它?

这是一个示例 class,您可以使用它来开始。

我猜,您无法启动 AutoCAD 实例是否有两个根本原因:

  1. 您没有使用 Autodesk.AutoCAD.Interop.AcadApplication 参考资料
  2. 您使用的 AutoCAD 2022 progId 错误

尝试一下这段代码,然后看看是否可以逆向查找问题。
当您想在没有直接插件的情况下启动 AutoCAD/使用 AutoCAD 时,您需要使用 COM 互操作对象而不是 Autodesk.AutoCAD.ApplicationServices。

另外,这里是您需要的新参考文献的路径:
C:\程序Files\Autodesk\AutoCAD2022\Autodesk.AutoCAD.Interop.dll
C:\程序Files\Autodesk\AutoCAD2022\Autodesk.AutoCAD.Interop.Common.dll
C:\Program Files (x86)\Reference\Assemblies\Microsoft\Framework.NETFramework\v4.7.2\Microsoft.VisualBasic.dll

using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows;


namespace Whosebug
{
    public partial class MainWindow : Window
    {


        public MainWindow()
        {
            InitializeComponent();
            bool isAutoCADRunning = Utilities.IsAutoCADRunning();
            if (isAutoCADRunning == false)
            {
                MessageBox.Show("Starting new AutoCAD 2022 instance...this will take a some time.");
                Utilities.StartAutoCADApp();
            }
            else
            {
                MessageBox.Show("AutoCAD already running.");
            }
            Utilities.SendMessage("AutoCAD started from WPF");
            MyDriver.CreateMyProfile();
            Utilities.SendMessage("Profile created:" + Utilities.yourProfileName);
            //MyDriver.NetloadMyApp(@"C:\YourPathFolderPath\custom.Dll");
        }
    }



    public class MyDriver
    {
        public static void CreateMyProfile()
        {
            bool isAutoCADRunning = Utilities.IsAutoCADRunning();
            if (isAutoCADRunning == false)
                Utilities.StartAutoCADApp();
            Utilities.CreateProfile();
        }

        public static void NetloadMyApp(String dllPath)
        {
            bool isAutoCADRunning = Utilities.IsAutoCADRunning();
            if (isAutoCADRunning == false)
                Utilities.StartAutoCADApp();
            Utilities.NetloadDll(dllPath);
        }
    }

    public class Utilities
    {
        [System.Runtime.InteropServices.DllImport("user32")]
        public static extern IntPtr GetWindowThreadProcessId(IntPtr hwnd, ref IntPtr lpdwProcessId);

        private static readonly string AutoCADProgId = "AutoCAD.Application.24.1";
        private static AcadApplication App;


        public static void SendMessage(String message)
        {   
            App.ActiveDocument.SendCommand("(princ \"" + message + "\")(princ)" + Environment.NewLine);
        }
            

        public static bool IsAutoCADRunning()
        {
            bool isRunning = GetRunningAutoCADInstance();
            return isRunning;
        }

        public static bool ConfigureRunningAutoCADForUsage()
        {
            if (App == null)
                return false;
            MessageFilter.Register();
            SetAutoCADWindowToNormal();
            return true;
        }

        public static bool StartAutoCADApp()
        {
            Type autocadType = System.Type.GetTypeFromCLSID(new Guid("AA46BA8A-9825-40FD-8493-0BA3C4D5CEB5"), true);
            object obj = System.Activator.CreateInstance(autocadType, true);
            AcadApplication appAcad = (AcadApplication)obj;
            App = appAcad;
            MessageFilter.Register();
            SetAutoCADWindowToNormal();
            return true;
        }

        public static bool NetloadDll(string dllPath)
        {
            if (!System.IO.File.Exists(dllPath))
                throw new Exception("Dll does not exist: " + dllPath);
            App.ActiveDocument.SendCommand("(setvar \"secureload\" 0)" + Environment.NewLine);
            dllPath = dllPath.Replace(@"\", @"\");
            App.ActiveDocument.SendCommand("(command \"_netload\" \"" + dllPath + "\")" + Environment.NewLine);
            return true;
        }
      

        public static bool CreateProfile()
        {
            if (App == null)
                return false;
            bool profileExists = DoesProfileExist(App, yourProfileName);
            if (profileExists)
            {
                SetYourProfileActive(App, yourProfileName);
                AddTempFolderToTrustedPaths(App);
            }
            else
            {
                CreateYourCustomProfile(App, yourProfileName);
                AddTempFolderToTrustedPaths(App);
            }
            SetYourProfileActive(App, yourProfileName);
            return true;
        }


        public static bool SetAutoCADWindowToNormal()
        {
            if (App == null)
                return false;
            App.WindowState = AcWindowState.acNorm;
            return true;
        }






        private static bool GetRunningAutoCADInstance()
        {
            Type autocadType = System.Type.GetTypeFromProgID(AutoCADProgId, true);
            AcadApplication appAcad;
            try
            {
                object obj = Microsoft.VisualBasic.Interaction.GetObject(null, AutoCADProgId);
                appAcad = (AcadApplication)obj;
                App = appAcad;
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            return false;
        }

        public static readonly string yourProfileName = "myCustomProfile";

        private static void SetYourProfileActive(AcadApplication appAcad, string profileName)
        {
            AcadPreferencesProfiles profiles = appAcad.Preferences.Profiles;
            profiles.ActiveProfile = profileName;
        }

        private static void CreateYourCustomProfile(AcadApplication appAcad, string profileName)
        {
            AcadPreferencesProfiles profiles = appAcad.Preferences.Profiles;
            profiles.CopyProfile(profiles.ActiveProfile, profileName);
            profiles.ActiveProfile = profileName;
        }

        private static bool DoesProfileExist(AcadApplication appAcad, string profileName)
        {
            AcadPreferencesProfiles profiles = appAcad.Preferences.Profiles;
            object pNames = null;
            profiles.GetAllProfileNames(out pNames);
            string[] profileNames = (string[])pNames;
            foreach (string name in profileNames)
            {
                if (name.Equals(profileName))
                    return true;
            }
            return false;
        }

        private static void AddTempFolderToTrustedPaths(AcadApplication appAcad)
        {
            string trustedPathsString = System.Convert.ToString(appAcad.ActiveDocument.GetVariable("TRUSTEDPATHS"));
            string tempDirectory = System.IO.Path.GetTempPath();
            List<string> newPaths = new List<string>() { tempDirectory };
            if (!trustedPathsString.Contains(tempDirectory))
                AddTrustedPaths(appAcad, newPaths);
        }

        private static void AddTrustedPaths(AcadApplication appAcad, List<string> newPaths)
        {
            string trustedPathsString = System.Convert.ToString(appAcad.ActiveDocument.GetVariable("TRUSTEDPATHS"));
            List<string> oldPaths = new List<string>();
            oldPaths = trustedPathsString.Split(System.Convert.ToChar(";")).ToList();
            string newTrustedPathsString = trustedPathsString;
            foreach (string newPath in newPaths)
            {
                bool pathAlreadyExists = trustedPathsString.Contains(newPath);
                if (!pathAlreadyExists)
                    newTrustedPathsString = newPath + ";" + newTrustedPathsString;
            }
            appAcad.ActiveDocument.SetVariable("TRUSTEDPATHS", newTrustedPathsString);
        }
    }


    public class MessageFilter : IOleMessageFilter
    {
        [DllImport("Ole32.dll")]
        private static extern int CoRegisterMessageFilter(IOleMessageFilter newFilter, ref IOleMessageFilter oldFilter);

        public static void Register()
        {
            IOleMessageFilter newFilter = new MessageFilter();
            IOleMessageFilter oldFilter = null;
            CoRegisterMessageFilter(newFilter, ref oldFilter);
        }
        public static void Revoke()
        {
            IOleMessageFilter oldFilter = null;
            CoRegisterMessageFilter(null, ref oldFilter);
        }

        public int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo)
        {
            return 0;
        }

        public int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType)
        {
            if (dwRejectType == 2)
                // flag = SERVERCALL_RETRYLATER.

                // Retry the thread call immediately if return >=0 & 
                // <100.
                return 99;
            // Too busy; cancel call.
            return -1;
        }

        public int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType)
        {
            return 2;
        }
    }

    [ComImport()]
    [Guid("00000016-0000-0000-C000-000000000046")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IOleMessageFilter
    {
        [PreserveSig]
        int HandleInComingCall(int dwCallType, IntPtr hTaskCaller, int dwTickCount, IntPtr lpInterfaceInfo);
        [PreserveSig]
        int RetryRejectedCall(IntPtr hTaskCallee, int dwTickCount, int dwRejectType);
        [PreserveSig]
        int MessagePending(IntPtr hTaskCallee, int dwTickCount, int dwPendingType);
    }

}