ActivistInvestor \ Tony Tanzillo
Distributed under the terms of the MIT License
NOTE: This documentation is in the process of being revised. More updates are pending.
- Environment Variables
- Multi-targeting Basics
- Multi-targeting Example Project
- Debug Profiles
- Converting Existing Projects to use Multi-targeting
- Diagnostic Console Output
- Debug Startup Automation
Table of contents generated with markdown-toc
This file and the materials it is included with contain Autodesk-confidential information relating to AutoCAD 2027 that is restricted by NDA. It is not intended for public distribution or disclosure to anyone that is not bound by the terms of the NDA for AutoCAD 2027 prior to FCS.
A minimal example project that uses Multi-targeting to target 3 different
versions of the .NET framework (.NET Framework 4.71, .NET 8.0, and .NET 10.0),
and 8 AutoCAD product releases that use those frameworks (AutoCAD 2020
through AutoCAD 2027). Also included in the example project is fully-reusable
build logic (the Directory.Build.props and Directory.Build.targets files)
that vastly-simplify building AutoCAD extensions that use multi-targeting.
In order to build mult-target AutoCAD extensions, the included custom build
logic requires at least two of the environment variables shown below to be
defined. Each of these environment variables is required only if you are
targeting the corresponding framework. For example, if you don't intend to
target .NET 4.x in any project, you don't have to define the AC_NET_4_REF_PATH
environment variable, as it will never be used.
For framework versions that you do intend to target, these environment variables
are required in order for the custom build logic in the included Directory.Build.*
files to work correctly. If these environment variables are not defined, nothing
will work.
You can use the setx command to define these environment variables,
or the Environment Variables dialog in Windows.
| Environment Variable | Description |
|---|---|
AC_NET_4_REF_PATH |
Path to reference assemblies for AutoCAD 2020-2024 |
AC_NET_8_REF_PATH |
Path to reference assemblies for AutoCAD 2025-2026 |
AC_NET_10_REF_PATH |
Path to reference assemblies for AutoCAD 2027 |
See below for more environment variables that are required to support the included launchSettings.json file.
Note: The paths assigned to the above environment variable should not include a trailing slash (\).
Requiring paths to AutoCAD reference assemblies for each target framework
to be specified using environment variables allows the Directory.Build.*
files to be fully-portable across machines where the locations of the
reference assemblies may differ, thereby supporting widespread distribution
and team development scenarios.
Multi-targeting provides a means for a single .NET SDK-style project to target multiple .NET framework versions. When you build a multi-target project, the project is built multiple times, once for each targeted framework, with the build output for each placed in a different sub-folder below the \Release and \Debug folders.
To use multi-targeting in a C# project, you must use the <TargetFrameworks>
element (plural) in your .csproj file, rather than the <TargetFramework>
element (singular) (see this article for an overview).
That page also shows how to use the <TargetFrameworks> element.
For example, in the .csproj file of a project that uses the Directory.Build.props and
Directory.Build.targets files included in this project, you can target
all AutoCAD releases from AutoCAD 2020 thru AutoCAD 2027 (spanning 3 different
framework versions), thusly:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net471;net8.0-windows;net10.0-windows</TargetFrameworks>
</PropertyGroup>
</Project>You don't have to target all three frameworks or all AutoCAD releases. For example, you can target only .NET 4.x- and .NET 8.0-based releases of AutoCAD. Or, you can target only .NET 8.0- and .NET 10.0-based releases. For example, to target only AutoCAD 2025 or later, you would use:
<PropertyGroup>
<TargetFrameworks>net10.0-windows;net8.0-windows</TargetFrameworks>
</PropertyGroup>Or, to target AutoCAD 2020 through AutoCAD 2026, you would use:
<PropertyGroup>
<TargetFrameworks>net8.0-windows;net471</TargetFrameworks>
</PropertyGroup>In the <TargetFrameworks> element, The first item in
the list of target framework monikers (TFMs) determines
the project context, or which framework Visual Studio
uses for the display of item states in Solution Explorer.
You can change the project context framework by
editing the <TargetFrameworks> element and rearranging
the order of the TFMs, so that the first element is the TFM
of the framework used for the project context, however
you should first ensure that the project builds without
error, and there are no unsaved changes in open files.
In a multi-target project, whenever you directly edit the project's .csproj file, you should you first unload the project, then open and edit the .csproj file, save your edits, and then reload the project.
Visual Studio 2022 provides no way to create a multi-target project via the
'create a new project' UI. To create a new project that uses multi-targeting,
You first create a standard classlibrary project that targets a single framework
version, and then manually edit the .csproj file and change the <TargetFramework>
element to <TargetFrameworks> and specify the desired framework versions.
Within the <TargetFrameworks> element, each target framework's Target
Framework Moniker (TFM) must be specified, delimited by semicolons. You
can find a list of valid TFMs here,
although for AutoCAD development, the set of usable TFMs is limited to the
following:
| Target Framework Moniker | Framework Version | Targeted AutoCAD products |
|---|---|---|
net471 |
.NET 4.71 | AutoCAD 2020-2024 |
net8.0 or net8.0-windows |
.NET 8.0 | AutoCAD 2025 & 2026 |
net10.0 or net10.0-windows |
.NET 10.0 | AutoCAD 2027 or later |
The above table shows both primiary and platform-specific
TFM's for .NET 8.0 and later. For example, You can use net8.0 (primary) or
net8.0-windows (platform specific) to target .NET 8.0. Using the platform-specific TFM is generally
preferable as it pulls in additional Windows-specific APIs and also disables
many platform-compatibility warnings, since they are irrelevant in Windows-only
projects such as AutoCAD extensions.
When multi-targeting is used, different assembly references must be used for each targeted framework version. In the included example project, under the Dependencies node in Solution Explorer, you will see child nodes whose names are the TFM of each targeted framework, and each of those child nodes will contain assembly references that are specific to that target framework.
The following clip shows the example project open in Solution Explorer, with the Properties palette to its right. Notice that as references from different target frameworks are selected, the properties palette displays the effective path to the reference, confirming that it is the correct reference path for the target framework.
Using different, framework-specific AutoCAD references is required when multi-targeting different AutoCAD product releases that use different framework versions. This poses a problem, and is the most-complicated aspect of building AutoCAD extensions that use multi-targeting.
Unfortunately, Visual Studio and its project architecture provides
no way to reference multiple, framework-specific versions of the same
assembly in a multi-target project. That can't be done via the UI,
and further, Visual Studio's project schema provides no formal,
persistent representation for referencing different, framework-specific
versions of the same assembly. When you right-click on the Dependencies
node (or any framework-specific child node) in a multi-target project and
choose Add Project Reference, You must select an assembly having a specific
path, and Visual Studio adds the assembly reference to the .csproj file,
and emits a <HintPath/> element that specifies the absolute path
to the selected assembly. If you do that builds will fail, because
Visual Studio will incorrectly use the same version of the referenced
assembly for all targeted frameworks, when different versions of
that assembly must be used with each target framework.
The custom build logic in the included Directory.Build.* files transparently
solves that problem. When that custom build logic is used in a multi-target project,
You can use Visual Studio's UI to add a reference to an AutoCAD assembly to your
project, in the same way you do in a single-target project, and Visual Studio will
ignore the path specified in the <HintPath/> element, and will instead use the
path specified in one of the environment variables you've
set for each target framework (described below). After you've added references to
AutoCAD assemblies to a multi-target project using the Visual Studio UI, you can open
the .csproj file and remove the <HintPath/> elements that Visual Studio generated,
as they will not be used in any case.
You can also add references to AutoCAD assemblies manually by editing the .csproj file.
If you do that, you can safely omit <HintPath/> elements as they will not be used,
provided that the required environment variables described above
have been set, and the included Directory.Build.props and Directory.Build.targets files
are being used by the project.
You will note that this example project does not use Autodesk-provided Nuget packages for AutoCAD. There are several reasons for this:
-
There is no package for AutoCAD releases targeting .NET 4.x.
-
Autodesk's NuGet packages do not support nuget package versioning, that allows a single package to provide multiple versions of its assemblies, one for each target framework supported by the library, or one version for each AutoCAD product release. Instead, Autodesk released separate packages for different AutoCAD releases based on the version of .NET which they target, and while they can generally be used across product releases that target the same version of .NET, there can be subtle API revisions across those releases that could result in issues.
-
AutoCAD releases and the versions of .NET which they target are not fully-aligned, and without nuget semantic package versioning support, there is no mechanism that allows a package reference to specify assemblies for a specific AutoCAD product release among several that target the same version of .NET. For example, neither of the following will work:
<PackageReference Include="AutoCAD.NET" Version="25.0.0" /> <!-- 2025 DLLs -->
<PackageReference Include="AutoCAD.NET" Version="25.1.0" /> <!-- 2026 DLLs -->To support all AutoCAD product releases that target the same version of .NET, a rule of thumb is to always target the oldest product release for a given .NET framework version. So, for AutoCAD releases that target .NET 4.x, that would mean compiling against the assemblies for AutoCAD 2020, and for releases that target .NET 8.0, compiling against the assemblies for AutoCAD 2025.
This example project and the included build logic is designed to support only one AutoCAD product release for each targeted .NET version, and it is your decision on what specific AutoCAD product release's assemblies should be used. You can specify that by setting the environment variables that are used to specify the locations of the AutoCAD assemblies for each targeted framework to the appropriate locations holding the assemblies for the AutoCAD product release you want to compile against, although it is strongly recommended to follow the above rule-of-thumb.
For other third-party nuget packages that support package versioning and multiple target frameworks, there is no difference in how you include them in multi-target projects verses single-target projects. In other words, It just works. However, you should keep in mind that if you are going to target all of the AutoCAD releases from 2020-2027 and later, you should ensure that any third-party nuget packages you need to use supports all of the framework versions your project targets.
Project references in multi-target projects work the same way they do in single-target projects with several special requirements.
First, you don't have to specify separate project references for each target framework, but any project references must be to projects that multi-target at least the same frameworks that are targeted by the referencing project. In other words, if your project targets .NET 4.x, .NET 8.0, and .NET 10.0, any project references must be to projects that also multi-target those same framework versions.
The included Directory.Build.props and Directory.Build.targets files implement the multi-target build logic that is used by all projects in a solution, and all projects that use those files. These files serve to vastly simplify building AutoCAD extensions that use multi-targeting to target multiple AutoCAD/NET framework versions. The custom build logic is not optional, it is required to in order for AutoCAD extension projects that use multi-targeting to build correctly.
Directory.Build.props and Directory.Build.targets are designed to be fully-reusable and are not coupled to a specific project or solution. You can copy and use them in other multi-target AutoCAD projects as needed, with no changes required. You can have any number of projects share a single Directory.Build.props and Directory.Build.targets file, by placing them in any folder that contains the projects that are to use them. This centralized build configuration strategy allows many projects to use a single custom build configuration, without replicating the custom build logic in each project that uses it.
It is recommended that you add Directory.Build.props and Directory.Build.targets to your Solution folder, above any project folders, so that they will be used by all projects in the solution. You can also add them as Solution Items, but that's optional and not required. If you add these files to your solution's folder, you don't have to add them to individual projects in the solution that are contained within the solution's folder, as they are automatically used by all projects within the folder where the files are located.
Before you can use the included Directory.Build.props and
Directory.Build.targets in a project, you must
assign values to at least two of the three AC_NET_X_REF_PATH environment variables described above. The values of these environment variables must point to the locations of AutoCAD reference assemblies for each targeted framework version.
The included Directory.Build.targets file adds references to the 3 basic AutoCAD assemblies that are used in most AutoCAD managed extensions:
AcMgd.dllAcCoreMgd.dllAcDbMgd.dll
Hence, you do not (and should not) add references to those assemblies to any project that uses the included Directory.Build.targets file. You can add additional AutoCAD references to Directory.Build.targets that will be used by all projects that use that file, that eliminates the need to add those same references to each project.
The custom build logic in the included Directory.Build.* files recognize the <RealDwg> property, which can be set to true in a .csproj file to prevent AcMgd.dll from being referenced, which is required in projects where the extension is to be loaded into a RealDwg host application such as AutoCAD Core Console:
<PropertyGroup>
<RealDwg>true</RealDwg>
</PropertyGroup>If you target .NET 4.x, you can set <LangVersion> to at least 8.0 to support compilation of Nullable Reference Types and implicit usings. Or, you can disable both of those features (as is done in this example
project) if you are primarily compiling migrated legacy code that doesn't use those features. If you don't set <LangVersion> in a multi-target project, Visual Studio uses the language version officially-supported for each target framework. If you target .NET 4.x and your code uses Nullable Reference Types, Implicit Usings, or other features not supported by the language version for .NET 4.x, you will get compiler errors for the .NET 4.x build.
While you can set <LangVersion> to a value that's greater than the officially-supported value for .NET 4.x, you cannot use framework-dependent features (such as Span<T>, ranges, etc.) that were introduced in more-recent framework and C# versions, because the language features have a dependence on a more recent framework version. In some cases, packages can be added to projects targeting legacy
framework versions that add various features introduced in later framework versions to them. Examples
include the System.Memory NuGet package, which enables the use of Span<T> in older framework versions, including .NET 4.x.
Targeting releases of AutoCAD that use .NET 4.x with the same code base that targets .NET 8.0 or later, can be problematic depending on what features/functionality the code uses from newer frameworks and language versions. With Windows Forms components, the issues increase exponentially.
If you can, avoid targeting older AutoCAD product releases that use .NET
4.x and you will be free from the restrictions and limitations on code that
goes with targeting that framework version. The Directory.Build.targets
and Directory.Build.props files included in this example are designed to
support targeting AutoCAD 2020 or later, but you don't have to target all
releases in multi-target projects that use these files. If you do not
specify .NET 4.x in your project's <TargetFrameworks> element, there will
be no build output generated for .NET 4.x, and no references for .net 4.x
needed, and that works without having to modify the Directory.Build.props or
Directory.Build.targets files. So, you can leave the Directory.Build.* files
as-is, and target only a subset of the frameworks those files support.
Targeting multiple framework/AutoCAD versions from a single code base can introduce another layer of complexity that you may need to deal with, which is that you may have situations where you want to leverage a feature that exists in some, but not all of the targeted framework versions.
In those cases, you can use conditional compilation with compiler-defined preprocessor symbols,
that allow you to conditionally include/exclude code depending on the
targeted framework version/AutoCAD release. The following example shows
the use of one of those preprocessor symbols with #if/#else/#endif, to
define two different implementations of a method, one for .NET 4.x, and
the other for .NET 8.0 or later. Note that this example can be expressed
more succinctly, but is not done that way in this case, mainly for illustration
purposes.
public static partial class Check
{
#if NET8_0_OR_GREATER
public static void IsNotNull(object arg, [CallerArgumentExpression("arg")] string msg = "null argument")
{
if(arg is null)
throw new ArgumentNullException(msg).Log(msg);
}
#else // .NET 4.x doesn't support [CallerArgumentExpression] attribute :(
public static void IsNotNull(object arg, string msg = "null argument")
{
if(arg == null)
throw new ArgumentNullException(msg).Log(msg);
}
#endif
}The Directory.Build.props file included in this project define several
constants that are useful for conditional code compilation. The compiler
constants shown below can be used just like the standard compiler-defined
preprocessor symbols (e.g., NET_8_OR_GREATER), and in fact, they are
merely synonyms for same, but help to make the intent clearer.
| Symbol | Condition |
|---|---|
AUTOCAD_2020_OR_GREATER |
Defined when targeting AutoCAD 2020 or later |
AUTOCAD_2025_OR_GREATER |
Defined when targeting AutoCAD 2025 or later |
AUTOCAD_2027_OR_GREATER |
Defined when targeting AutoCAD 2027 or later |
Example usage (C#):
#if AUTOCAD_2025_OR_GREATER
// code here will be included only when
// targeting AutoCAD 2025/NET 8.0 or later.
#endifIn a multi-target project, the Visual Studio editor must use one and only one target framework for the editor context. The editor context controls how intellisense, code completion, error checking, display of code based on conditional compilation, and various other code-related functions work, based on the current target framework.
For example, the above snippet shows two versions of a method, one used when targeting .NET 4.x and the other when targeting .NET 8.0 or later. In the editor, one of these two methods will appear in gray, which indicates it is not included in the compilation for the current target framework. The current target framework used for the editor context can be selected from the left-most drop-down control on the navigation bar located just above the editor window. From this control you can select any targeted framework to use as the editor context.
In the clip below, the above code example is shown in the editor window, with
conditional compilation using the NET_8_OR_GREATER compiler constant, to
control which version of the method is included for .NET 8 or later, and
which is included for .NET 4.X. The clip shows what happens when the current
target framework is changed from the target framework selector dropdown.
Notice that as the current target framework is changed, the display of each
of the two versions of the method are toggled between included and excluded.
The included example project (AcadMultiTargetExample) targets the following framework versions and AutoCAD product releases:
| Target Framework | Target Framework Moniker (TFM) | AutoCAD Product Release(s) |
|---|---|---|
| .NET 8.0 | net8.0-windows |
AutoCAD 2025, 2026 |
| .NET 10.0 | net10.0-windows |
AutoCAD 2027 |
This example project includes a launchSettings.json file (in the
Properties folder) that configures the project for debugging in Visual
Studio. The launchSettings.json file defines 3 debugging profiles, one
for each targeted framework/AutoCAD release.
You must edit this file and change the paths assigned to the
workingDirectory property to point to the locations of the AutoCAD
executable (e.g., acad.exe) to launch, for each launch profile. You
can leave the executablePath property as-is, since Visual Studio
will look for acad.exe in the working directory and find it. You
should also remove profiles for framework versions that your project
does not target.
You can also add command line arguments to be passed to the executable
as well in the commandLineArgs property. The commandLineArgs property
in the example project is defined to pass the /nologo switch to start
AutoCAD without showing the splash screen.
When you run the project in the debugger, you can select which launch profile to use from the dropdown list on the Visual Studio toolbar:
While it's possible to convert an existing project to use multi-targeting, it may ultimately be better to start from scratch with a new project and copy the code files from the existing project to the new one, to ensure that the project is correctly-configured for multi-targeting.
If you prefer to convert an existing project, follow the steps below. These steps should also be followed to create a new project that uses multi-targeting, after first creating a new classlibrary project that targets a single framework, and then following these same steps to configure the new project to use multi-targeting.
When converting an existing project, you should backup the existing project
first. These steps assume that you've already defined the (AC_NET_x_REF_PATH)
environment variables that are described above, to point to the AutoCAD
reference assembly locations for each targeted framework.
These steps outline the process of converting an existing (or new project) that targets a single framework version to one that targets multiple framework versions:
-
If the project is open in Visual Studio, right-click on the project node in Solution Explorer, and choose Unload Project from the context menu.
-
Open the project's .csproj file and change the
<TargetFramework>element to<TargetFrameworks>, and specify the desired target framework monikers, separated by semicolons. For example, to target AutoCAD 2020 through AutoCAD 2027 you would use:
<PropertyGroup>
<TargetFrameworks>net10.0;net8.0;net471</TargetFrameworks>
</PropertyGroup>-
Add copies of the
Directory.Build.propsandDirectory.Build.targetsfiles from the included example project to the project you are converting to multi-targeting. You should copy these files to the solution folder that contains the project being converted. You don't have to explicitly add these files to the project, as it will automatically use them if the project is located in the same folder or in any subfolder of the solution folder. -
Add a copy of the
launchSettings.jsonfile from the included example project the Properties folder of the project being converted, and edit it to have the correct path(s) to the AutoCAD executable(s) and working directories for each targeted framework/AutoCAD release. You can specify 'acad.exe' as the executablePath property, and it will be found in the path specified as the workingDirectory. Note that this step is optional and not required for multi-targeting to work. -
Remove any references to
acmgd.dll,acdbmgd.dll, andaccoremgd.dllfrom the .csproj file for the project being converted, as these three references are included by theDirectory.Build.targetsfile. If the project being converted is designed to not have a dependence on AutoCAD, and is intended to be loaded into AutoCAD Core Console or another RealDwg host application, add the following to the .csproj file to suppress referencing ofAcMgd.dll:
<PropertyGroup>
<RealDwg>true</RealDwg>
</PropertyGroup>-
If an existing project includes references to AutoCAD assemblies other than
AcMgd.dll,AcDbMgd.dll, andAcCoreMgd.dll, remove the<HintPath/>child elements from those<Reference>elements, as they will not be used. Note that this step is optional. -
Finally, save all open files, and right-click on the project in Solution Explorer and choose Reload Project, and then build the solution.
After completing the above steps, if Visual Studio displays error messages, it is most-likely a result of it not being able to fully-reconcile changes made to the project. In that case, you should save all open files, close and restart Visual Studio, and reopen the solution containing the project.
The included example project targets 3 major framework versions and 8 AutoCAD releases that use those framework versions. If you wish to experiement with or build the example project but don't have the AutoCAD reference assemblies for all of the targeted frameworks installed, you can remove one of the target frameworks from the project (removing two would make it a single-target project).
If you remove a target framework you also do not need to define
the corresponding AC_NET_X_REF_PATH environment variable.
To modify an existing multi-target project to add, remove, or change a targeted framework, follow these steps:
-
If the project is open in Visual Studio, right-click on the project node in Solution Explorer, and choose Unload Project from the context menu.
-
Open the project's .csproj file and edit the
<TargetFrameworks>element and add, remove, or replace the desired framework's TFM.
- If you are only adding a target framework to the project, you can skip steps 4 and 5 below, and go to step 6.
-
Right-click on the project node in Solution Explorer and choose Open Folder in File Explorer from the context menu.
-
In File Explorer, delete the
bin/andobj/folders from the project's root folder. -
Save all open files, and right-click on the project in Solution Explorer and choose Reload Project, and then rebuild the solution.
When a multi-target project is built, for each targeted framework version, a diagnostic message is displayed on the output console indicating the target build and the path to the set of AutoCAD reference assemblies used to build that target. You can view the Output pane to see these messages and use them to verify that build targets are using the correct set of AutoCAD reference assemblies:
1>Built target for AutoCAD 2020 / .NET v4.7.1 using references from C:\Program Files\Autodesk\AutoCAD 2023
1>Built target for AutoCAD 2025 / .NET v8.0 using references from C:\Program Files\Autodesk\AutoCAD 2025
1>Built target for AutoCAD 2027 / .NET v10.0 using references from C:\Program Files\Autodesk\AutoCAD 2027
Debug startup automation is the general term used to describe common debugging startup tasks that the build system can initiate or stage when AutoCAD is launched in the debugger. These tasks are described in detail below. Startup automation tasks are staged using two basic methods:
-
Dynamic startup script generation: A script (.scr) file is dynamically generated during the build process, that fully-automates NETLOADing the debug target assembly into AutoCAD, and optionally loading and/or executing a LISP and/or SCRIPT file when AutoCAD is started in a debug session, after the debug target assembly has been NETLOADed.
-
Dynamic launch command line argument generation: The launch command line is dynamically generated to load the dynamically-generated startup script into AutoCAD, and optionally open a drawing file when AutoCAD is started in a debug session. It can also generate and add various other command line switches/arguments as directed by MSBUILD properties that can be defined in each project. These MSBUILD properties are documented below.
Debug startup automation is optional, and must be explicitly enabled by setting the <StartupAutomation/> property in a .csproj file. This setting has project scope and can be set in each project in a solution.
When enabled, debug startup automation provides the following basic functionality:
-
Support for startup
.dwg,.dwt,.lsp, and.scrfiles. Any of these file types can be automatically opened or loaded into AutoCAD when started in a debug session without having to explicitly specify them using launch command line switches/arguments or script files. The developer can simply place these files in the Startup folder (see below) and the build system will generate the required command line switches and/or scripting needed to automatically open/load/execute them when AutoCAD is started in a debug session, after the debug target assembly has been automatically NETLOADed. -
Dynamically-generated, target framework-specific loader script (.scr) files that implicitly NETLOAD the debug target assembly into AutoCAD when started in a debug session, which eliminates the need for an explicit script file to NETLOAD the target. A distinct script file is generated for each targeted framework, ensuring that the correct debug target assembly is loaded into AutoCAD, based on the target framework of the launch profile used to start the debug session.
-
A dynamically-generated executable launch command line provides the needed switches/arguments required to load startup drawing, LISP and script files. The build system also provides the option of adding additional command line switches/arguments on a per-project basis, by specifying them using a property assigned in a .csproj file (see below).
-
Highly-configurable and flexible build environment that gives the developer complete control over its behavior using MSBUILD properties.
The custom build system is designed to implicitly NETLOAD the debug target assembly into AutoCAD when a debug session is started. It does this using a dynamically-generated script (.scr) file that is passed as a command line argument with the /b switch.
The included build logic dynamically-generates multiple loader script files, one for each target framework, and places each in the build output folders along with each framework-specific output assembly. The script file has the same name as the output assembly.
The dynamically-generated loader script file performs three actions:
-
NETLOADs the correct, framework-specific debug target assembly. In a multi-target project there are multiple build output assemblies, one for each target framework. The loader script ensures that the correct one is loaded for the debug launch profile that's used.
-
If a LISP file is present in the Startup folder, or the path to a LISP file is specified in the
<StartupLisp/>property, it loads the LISP file. -
If a script file is present in the Startup folder, or the path to a script file is specified in the
<StartupScript/>property, it executes the script file via the SCRIPT command.
This scheme offers a number of adantages:
-
It fully-automates NETLOADing of the debug target assembly, while also allowing a separate test script and/or LISP file to be run/loaded after the target assembly has been loaded.
-
It serves to decouple loading of the debug target from the test scripting and test LISP files. That allows the test script or LISP code to contain only test code or commands, and not have to deal with NETLOADing the debug target assembly explicitly. By decoupling the NETLOADing of the debug target assembly from the test script/lisp, the test script and/or LISP can be used repeatedly in the same AutoCAD session without redundantly issuing the NETLOAD command.
-
Eliminates the complexity of resolving which of several target framework-specific debug target assemblies is to be loaded in multi-target projects, based on the target framework of the debug profile used to start the debug session.
-
Allows a single test script and/or LISP file to be used with all targeted frameworks/AutoCAD releases.
Implicit NETLOADing of the debug target assembly can be disabled on a per-project basis, by setting the '' property to false in a .csproj file. This property allows other startup automation functionality to be used without implicitly NETLOADing the debug target assembly, which can be useful in cases where that assembly is already loaded automatically at AutoCAD startup via the registry or an Autoloader bundle.
Startup automation is folder- and file-driven. If a folder having the name "Startup" resides in the root folder of the project, it can contain one of each the following file types. All files are optional, and can have any name:
| File type | Description |
|---|---|
.dwg |
A drawing file to be opened when AutoCAD is started in a debug session. |
.dwt |
A drawing template that is used to create a new drawing when AutoCAD is started in a debug session. This file will not be used if a .dwg file is also present in the Startup folder. To use a .dwt file to create a new drawing, remove any .dwg file from the Startup folder (or you can just give it a different file extension). |
.scr |
A script file to be executed when AutoCAD starts in a debug session, after the debug target assembly has been NETLOADed. The script file does not have to (and must not) NETLOAD the debug target assembly, as that is performed implicitly by a dynamically-generated script file that's used to start AutoCAD, and will have already happened at the point when this script file executes. |
.lsp |
A LISP file to be loaded at AutoCAD startup in a debug session after the debug target assembly has been NETLOADed. The LISP file should not NETLOAD the debug target assembly because at the point when the LISP file is loaded, that will have already happened. If a LISP file and a script file both exist, the LISP file is loaded before the script file is executed. |
The included build logic looks in the Startup folder for the presence of .dwg, .dwt, .scr, and .lsp files, and generates the command line switches and arguments required to open a .dwg file and/or load/execute a LISP and/or script file when AutoCAD is started in a debug session.
To support per-project customization of the dynamically-generated command line, the build logic recognizes the <AppendToCommandLine> element that can be added to a project's .csproj file. In this element one can specify additional command line arguments/switches, which are appended to the dynamically-generated command line.
The included launchSettings.json file is generic, by virtue of its entirely property-driven nature, using both MSBUILD properties defined by the custom build logic and each project that uses it, and environment variables that point to the folders containing the application executables to launch (usually acad.exe).
That allows launchSetting.json to be reusable without changes, across multiple projects that use this custom build environment, and allows it to be portable across different systems where the paths to executable files and reference assemblies may differ. The included launchSettings.json file depends on the following environment variables, which must hold the location of the AutoCAD program executable for each targeted product release.
| Environment Variable | Description |
|---|---|
AC_NET_4_BASE_PATH |
Path to the installation folder of a .NET 4.x-based AutoCAD product (e.g., 2020-2024) |
AC_NET_8_BASE_PATH |
Path to the installation folder of a .NET 8.0-based AutoCAD product (e.g., 2025-2026 FCS) |
AC_NET_10_BASE_PATH |
Path to the installation folder of a .NET 10.0-based AutoCAD product (e.g., 2027 and .NET 10-based updates of 2025 and 2026). |
The custom build system recognizes a number of MSBUILD properties that can optionally be defined in a .csproj file, to override/customize the default behavior of the build system:
| Property | Description |
|---|---|
<StartupPath/> |
Can be used to explicitly specify the Startup folder that will be probed for startup files, which by default, is a folder in the project root having the name "Startup". To have a different folder probed for startup files, specify its full path in this property. |
<StartupDrawing/> |
Can be used to override default probing of the Startup folder for a startup drawing, allowing any .dwg file to be loaded into AutoCAD at startup, by assigning its full path to this property. |
<StartupTemplate/> |
Can be used to override default probing of the Startup folder for a drawing template file, allowing any Note: Use of this property requires that there not be a startup drawing (dwg) file either specified explicitly via the |
<StartupScript/> |
Can be used to override default probing of the Startup folder for a startup script file, allowing any Note: If this property is assigned to a .scr file, that script file should not NETLOAD the target assembly into AutoCAD, as that is handled by the dynamically-generated loader script, and will have already happened at the point when this script file executes. |
<StartupLisp/> |
Can be used to override default probing of the Startup folder for a startup LISP file, allowing any A startup LISP file and startup SCRIPT file are not mutually exclusive. Either or both can be present in the Startup folder. If both are present, the startup script file is executed after the startup LISP file is loaded. |
<AppendToCommandLine/> |
Can be used to add one or more additional switches/arguments to the dynamically-generated command line that is used to start AutoCAD in a debug session. Note that the |
<CommandLineArgs/> |
Can be used to completely override dynamic command-line generation, by assigning the entire command line to be used to start AutoCAD to this property. If this property is assigned, there is no dynamically-generated command line, and hence, no startup drawing or drawing template; startup LISP or script file used, and there is no dynamically-generated loader script to implicitly NETLOAD the debug target into AutoCAD. When this property is assigned, all other properties shown in this table are ignored and have no effect. |
<StartupAutomation/> |
Enables or disables all dynamic debug startup functionality (e.g. dynamically-generated loader script and dynamically-generated command line switches/arguments needed to load the loader script and open/load a startup .dwg, .lsp, or .scr file). When set to false, all startup automation functionality is disabled and there is no dynamically-generated loader script or dynamically-generated command line arguments passed to AutoCAD when started from a debug session. When set to false, all other properties shown in this table except for Dynamic loader script and command line argument generation, and automatic loading of startup files is only applicable to projects that are loaded explicitly via NETLOAD or some other means such as the registry or a package bundle, and are usually set as the Startup Project in Visual Studio. The default value of this property is false (e.g., no startup automation). For projects that are loaded indirectly as a result of being referenced from another project, this property should be set to false in the .csproj file to opt-out of startup automation. This is an opt-in setting that is opt-out by default. One would typically set this property to true if the project output would otherwise have to be manually NETLOADed into AutoCAD at the start of a debug session. |
<AutoNetload/> |
Enables or disables implicit automatic NETLOADing of the debug target assembly when AutoCAD is started in a debug session and startup automation is enabled. This property allows the use of startup automation without implicit NETLOADing, which is useful when the debug target assembly is automatically loaded via the Applications key in the registry, or by a package bundle. This property is only applicable when |
<ExeName/> |
The name of the executable that is started when a debug session begins. The default value is "acad.exe", but this property can be assigned to a different value in a .csproj file as needed (for example, "accoreconsole.exe"). This property is referenced from the bundled launchSettings.json file. |
<KillTargetProcessOnBuild/> |
Instructs the custom build system to terminate a running instance of the debug target executable when the project is built, to prevent build failures that would result from not being able to write to the build output assembly because it is loaded into the debug target's process space. The name of the executable that is killed is the value of the Important: Use this property with extreme care, as the process is terminated regardless of whether there are unsaved changes to one or more open DWG files. |
<DebugStartup/> |
A debugging switch that will cause the build system to display the values of internal variables used to generate the loader script and command line arguments in the Visual Studio output window. |
The following example illustrates the use of the <AppendToCommandLine/> property element. The example specifies that a view named PLANVIEW be restored when the drawing containing it is opened:
<PropertyGroup>
<AppendToCommandLine>/v PLANVIEW</AppendToCommandLine>
</PropertyGroup>The included test/example project's output assembly needs to be NETLOADed into AutoCAD when a debug session starts. The test/example project shows how to leverage the startup automation functionality provided by the custom build environment, to fully-automate NETLOADing of the debug target assembly, and perform other common startup tasks.
The test/example project demonstrates how the build system fully-automates the staging of these tasks when a debug session is started:
-
Starting AutoCAD with the /nologo switch to suppress the splash screen.
-
Opening a .DWG file at startup.
-
Implicit/automatic NETLOADing of the debug target assembly into AutoCAD.
-
Loading a LISP file after the debug target assembly has been NETLOADed (optional).
-
Running a SCRIPT file after the LISP file has been loaded (optional).
Enabling startup automation functionality in a project requires nothing more than setting the <StartupAutomation> property to true in the .csproj file:
<PropertyGroup>
<StartupAutomation>true</StartupAutomation>
</PropertyGroup>The sample/test project includes a "Startup" folder that contains a test.dwg file; a test.lsp file; and a test.scr file. When this project is started in the debugger, the following takes place:
- AutoCAD launches without displaying the splash
window, and opens the
test.dwgfile. - The debug target assembly is NETLOADed into AutoCAD.
- The
test.lspfile is loaded. - The
test.scrfile is run.
All of the above happens without requiring the developer to write script files to NETLOAD the debug target, or specify executable launch command line switches and arguments. IOW, it requires zero-configuration.
To automatically open a .dwg file, and/or load or execute a .lsp file or .scr file when AutoCAD is launched in the debugger, The developer only needs to create a folder with the name "Startup" in the root folder of the project, and in it place the startup files that are to be opened/loaded/executed when AutoCAD starts in a debug session. The custom build environement implicitly and dynamically generates the required command line switches and arguments, along with the startup scripting required to perform all of the tasks.
The "Startup" folder and its contents are completely optional. If that folder doesn't exist (or contains no files), the only task that's staged is NETLOADing the debug target assembly into AutoCAD.
A more-subtle and easily-overlooked aspect of startup automation is that in a multi-target project, there are multiple debug target assemblies, one for each targeted framework. Because the custom build environment is multi-target aware, it will always generate the scripting needed to select and load the correct debug target assembly into AutoCAD based on the launch profile's target framework.
For issues, questions, and general discussion you can visit the repository where this project is hosted.




