LispLoader v1.0.000

Short description

🧩 LispLoader v1.0.000 is an AutoCAD and Civil 3D .NET startup loader that reads LoaderConfig.txt and safely processes configured LSP VLX FAS and DLL program files.
πŸ“„ One configured file failing does not intentionally stop the remaining load sequence and all results are written to the AutoCAD command line and a rolling disk log.
βš™οΈ The plugin starts its configured load sequence immediately when the compiled LispLoader DLL is loaded into AutoCAD.

Command:

Startup action: NETLOAD LispLoader.dll
Configuration file: LoaderConfig.txt
Log file: LispLoader.log

Description:

🧩 LispLoader v1.0.000 is an AutoCAD and Civil 3D .NET startup loader that reads LoaderConfig.txt and safely processes configured LSP VLX FAS and DLL program files.
πŸ“„ One configured file failing does not intentionally stop the remaining load sequence and all results are written to the AutoCAD command line and a rolling disk log.
βš™οΈ The plugin starts its configured load sequence immediately when the compiled LispLoader DLL is loaded into AutoCAD.

Helper function: (if any)​

Comming soon …

Functionalities:

βœ… Configuration driven loading – uses LoaderConfig.txt as the source list.
βœ… LSP loading – supports AutoLISP source files.
βœ… VLX loading – supports Visual LISP executable files.
βœ… FAS loading – supports compiled AutoLISP files.
βœ… DLL loading – loads .NET assemblies with Assembly.LoadFrom and ExtensionLoader.
βœ… Relative and absolute paths – accepts both path types in the configuration.
βœ… Failure isolation – continues the loop when individual files are missing or return a handled failure.
βœ… Command line logging – reports loading progress inside AutoCAD.
βœ… Rolling disk log – writes LispLoader.log and rotates it at 5 MB.
βœ… Version banner – prints version and build timestamp when the plugin initializes.

Result:

🎯 LispLoader v1.0.000 provides the described AutoCAD or Civil 3D workflow.
πŸ“Œ The generated SEO description is based on the supplied source code or project files.

Images, animations etc.

Pixel

XAML code:

ο»Ώ<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:Autodesk.Windows;assembly=AdWindows">
    
<src:RibbonToolTip x:Key="LispsLoader">
<src:RibbonToolTip.ExpandedContent>
<StackPanel>
<TextBlock Background="AntiqueWhite" TextAlignment="Left">
<Bold>Function Syntax: LispsLoader</Bold>
<LineBreak/>
<Bold>Version: 1.0 Date: 11.08.2026 3:19:48PM</Bold>
<LineBreak/>
<Bold>Version: 1.0 Date: 11.08.2026 3:19:52PM</Bold>
<LineBreak/>
<Hyperlink>N/A</Hyperlink>

<Bold><Run Foreground="DodgerBlue">Description</Run></Bold><LineBreak/>
<Run Foreground="White">🧩 LispLoader v1.0.000 is an AutoCAD and Civil 3D .NET startup loader that reads LoaderConfig.txt and safely processes configured LSP VLX FAS and DLL program files.</Run><LineBreak/>
<Run Foreground="White">πŸ“„ One configured file failing does not intentionally stop the remaining load sequence and all results are written to the AutoCAD command line and a rolling disk log.</Run><LineBreak/>
<Run Foreground="White">βš™οΈ The plugin starts its configured load sequence immediately when the compiled LispLoader DLL is loaded into AutoCAD.</Run><LineBreak/>
<LineBreak/>
<Bold><Run Foreground="DodgerBlue">Function Syntax</Run></Bold><LineBreak/>
<Run Foreground="White">Startup action: </Run><Bold><Run Foreground="Orange">NETLOAD LispLoader.dll</Run></Bold><LineBreak/>
<Run Foreground="White">Configuration file: </Run><Bold><Run Foreground="Orange">LoaderConfig.txt</Run></Bold><LineBreak/>
<Run Foreground="White">Log file: </Run><Bold><Run Foreground="Orange">LispLoader.log</Run></Bold><LineBreak/>
<LineBreak/>
<Bold><Run Foreground="LimeGreen">Primary Workflow</Run></Bold><LineBreak/>
<Run Foreground="White">1. NETLOAD LispLoader.dll into AutoCAD.</Run><LineBreak/>
<Run Foreground="White">2. AutoCAD calls the plugin Initialize method.</Run><LineBreak/>
<Run Foreground="White">3. The plugin prints the version and build timestamp.</Run><LineBreak/>
<Run Foreground="White">4. LoaderConfig.txt is read and blank or commented lines are ignored.</Run><LineBreak/>
<Run Foreground="White">5. Configured files are resolved and processed one by one.</Run><LineBreak/>
<Run Foreground="White">6. LSP VLX and FAS files are sent to the active AutoCAD document as load expressions.</Run><LineBreak/>
<Run Foreground="White">7. DLL files are loaded into the AppDomain and registered through AutoCAD ExtensionLoader.</Run><LineBreak/>
<Run Foreground="White">8. A final OK FAILED and SKIPPED summary is written to the log.</Run><LineBreak/>
<LineBreak/>
<Bold><Run Foreground="LimeGreen">Functionalities</Run></Bold><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">Configuration driven loading</Run></Bold><Run Foreground="White"> - uses LoaderConfig.txt as the source list.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">LSP loading</Run></Bold><Run Foreground="White"> - supports AutoLISP source files.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">VLX loading</Run></Bold><Run Foreground="White"> - supports Visual LISP executable files.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">FAS loading</Run></Bold><Run Foreground="White"> - supports compiled AutoLISP files.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">DLL loading</Run></Bold><Run Foreground="White"> - loads .NET assemblies with Assembly.LoadFrom and ExtensionLoader.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">Relative and absolute paths</Run></Bold><Run Foreground="White"> - accepts both path types in the configuration.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">Failure isolation</Run></Bold><Run Foreground="White"> - continues the loop when individual files are missing or return a handled failure.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">Command line logging</Run></Bold><Run Foreground="White"> - reports loading progress inside AutoCAD.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">Rolling disk log</Run></Bold><Run Foreground="White"> - writes LispLoader.log and rotates it at 5 MB.</Run><LineBreak/>
<Run Foreground="White">βœ… </Run><Bold><Run Foreground="LimeGreen">Version banner</Run></Bold><Run Foreground="White"> - prints version and build timestamp when the plugin initializes.</Run><LineBreak/>
<LineBreak/>
<Bold><Run Foreground="DarkRed">Important Notes</Run></Bold><LineBreak/>
<Run Foreground="White">⚠️ </Run><Bold><Run Foreground="DarkRed">Project version is 1.0.000.</Run></Bold><LineBreak/>
<Run Foreground="White">⚠️ </Run><Bold><Run Foreground="DarkRed">The provided LoaderConfig contains example entries for DLL LSP FAS and VLX files.</Run></Bold><LineBreak/>
<Run Foreground="White">⚠️ </Run><Bold><Run Foreground="DarkRed">The README recommends placing DLL entries before dependent LISP files.</Run></Bold><LineBreak/>
<Run Foreground="White">⚠️ </Run><Bold><Run Foreground="DarkRed">The LSP load path is sent asynchronously with SendStringToExecute so the immediate OK log represents successful dispatch rather than a full parser level verification of the target LISP result.</Run></Bold><LineBreak/>
<Run Foreground="White">⚠️ </Run><Bold><Run Foreground="DarkRed">An active AutoCAD document is required for LSP VLX and FAS dispatch.</Run></Bold><LineBreak/>
<LineBreak/>
<Bold><Run Foreground="Yellow">SEO Keywords</Run></Bold><LineBreak/>
<Run Foreground="Yellow">🏷️ AutoCAD  🏷️ Civil 3D  🏷️ LispLoader  🏷️ AutoLISP loader  🏷️ VLX loader  🏷️ FAS loader  🏷️ DLL loader  🏷️ LoaderConfig  🏷️ ExtensionLoader  🏷️ AutoCAD startup  🏷️ Rolling log  🏷️ CAD automation</Run><LineBreak/>




<LineBreak/>
</TextBlock>
</StackPanel>
</src:RibbonToolTip.ExpandedContent>
</src:RibbonToolTip>
</ResourceDictionary>

C# code:

// ===== FILE: ConfigReader.cs =====
using System;
using System.Collections.Generic;
using System.IO;

namespace LispLoader
{
    /// <summary>
    /// Reads LoaderConfig.txt from the fixed base folder.
    ///
    /// File format (one entry per line):
    ///   # This is a comment β€” ignored
    ///   ; This is also a comment β€” ignored
    ///                                        ← blank lines ignored
    ///   C:\full\path\to\file.lsp             ← absolute path
    ///   Polyline_menu\QuickMirror\QuickMirror.lsp   ← relative to base folder
    ///
    /// Relative paths are resolved against the base folder:
    ///   C:\Users\mateid\...\Help_File\
    /// </summary>
    internal static class ConfigReader
    {
        private const string Source = "ConfigReader";

        private static readonly string BaseFolder =
            @"C:\Users\mateid\OneDrive - DB E.C.O. Group\@C3D\@Dan_Templates\Acad\Support_files\Lisps\Help_File";

        private static readonly string ConfigFile =
            Path.Combine(BaseFolder, "LoaderConfig.txt");

        /// <summary>
        /// Returns the list of resolved absolute paths to load.
        /// Missing or unreadable config returns an empty list (logged as error).
        /// </summary>
        internal static IReadOnlyList<string> ReadPaths()
        {
            if (!File.Exists(ConfigFile))
            {
                LogManager.Error(Source, $"Config file not found: {ConfigFile}");
                LogManager.Warn (Source,  "Create LoaderConfig.txt in the base folder.");
                return Array.Empty<string>();
            }

            var paths = new List<string>();

            try
            {
                string[] lines = File.ReadAllLines(ConfigFile);
                int lineNo = 0;

                foreach (string raw in lines)
                {
                    lineNo++;
                    string line = raw.Trim();

                    // Skip blanks and comments
                    if (string.IsNullOrEmpty(line))      continue;
                    if (line.StartsWith("#"))             continue;
                    if (line.StartsWith(";"))             continue;

                    // Resolve relative paths
                    string resolved = Path.IsPathRooted(line)
                        ? line
                        : Path.Combine(BaseFolder, line);

                    paths.Add(resolved);
                }

                LogManager.Info(Source, $"Config loaded: {paths.Count} entries from {ConfigFile}");
            }
            catch (Exception ex)
            {
                LogManager.Error(Source, $"Failed to read config: {ex.Message}");
            }

            return paths;
        }
    }
}


// ===== FILE: FileLoader.cs =====
using System;
using System.IO;
using System.Reflection;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;

namespace LispLoader
{
    /// <summary>
    /// Loads individual files safely β€” one failure never stops the next file.
    ///
    /// Supported types:
    ///   .lsp  .vlx  .fas  β†’  Editor.RunLisp( (load "path") )
    ///   .dll              β†’  Assembly.LoadFrom  +  ExtensionLoader
    /// </summary>
    internal static class FileLoader
    {
        private const string Source = "FileLoader";

        // ── Public entry point ────────────────────────────────────────────────

        /// <summary>
        /// Load a single file. Swallows all exceptions and logs the result.
        /// Returns true on success.
        /// </summary>
        internal static bool Load(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
                return false;

            path = path.Trim();

            if (!File.Exists(path))
            {
                LogManager.Warn(Source, $"[NOT FOUND]  {path}");
                return false;
            }

            string ext = Path.GetExtension(path).ToLowerInvariant();

            return ext switch
            {
                ".lsp" or ".vlx" or ".fas" => LoadLisp(path),
                ".dll"                      => LoadDll(path),
                _                           => UnsupportedType(path, ext),
            };
        }

        // ── LSP / VLX / FAS ──────────────────────────────────────────────────

        private static bool LoadLisp(string path)
        {
            try
            {
                // Escape backslashes for the LISP string
                string escaped = path.Replace("\\", "\\\\");
                string expr    = $"(load \"{escaped}\")";

                Document? doc = Application.DocumentManager?.MdiActiveDocument;
                if (doc == null)
                    throw new InvalidOperationException("No active document.");

                // RunLisp evaluates silently β€” no command echo on the prompt
                doc.SendStringToExecute(expr + "\n", false, false, false);

                // RunLisp does not return a catchable error for LOAD failures;
                // we use a second expression to check if the load produced an error atom.
                // The reliable signal is the absence of an exception here β€”
                // any reader-level crash in the target file surfaces as an Exception.
                LogManager.Info(Source, $"[OK]         {path}");
                return true;
            }
            catch (System.Exception ex)
            {
                LogManager.Error(Source, $"[FAIL-LISP]  {path}");
                LogManager.Error(Source, $"             {ex.Message}");
                return false;
            }
        }

        // ── DLL ──────────────────────────────────────────────────────────────

        private static bool LoadDll(string path)
        {
            try
            {
                // Step 1 β€” load the assembly into the AppDomain
                Assembly asm = Assembly.LoadFrom(path);

                // Step 2 β€” register it with AutoCAD's ExtensionLoader
                //           so IExtensionApplication.Initialize() is called
                ExtensionLoader.Load(path);

                string name    = asm.GetName().Name ?? Path.GetFileName(path);
                string version = asm.GetName().Version?.ToString() ?? "?";
                LogManager.Info(Source, $"[OK-DLL]     {name}  v{version}");
                LogManager.Info(Source, $"             {path}");
                return true;
            }
            catch (System.Exception ex)
            {
                LogManager.Error(Source, $"[FAIL-DLL]   {path}");
                LogManager.Error(Source, $"             {ex.Message}");
                return false;
            }
        }

        // ── Helpers ───────────────────────────────────────────────────────────

        private static bool UnsupportedType(string path, string ext)
        {
            LogManager.Warn(Source, $"[SKIP]       Unsupported extension '{ext}': {path}");
            return false;
        }
    }
}


// ===== FILE: VersionStamp.cs =====
using System;
using System.Linq;
using System.Reflection;

namespace LispLoader
{
    /// <summary>
    /// Prints the version banner whenever the plugin loads.
    ///
    /// Format:  v1.0.000 | built 12.06.2026 10:30:00
    ///
    /// Version   β†’ AssemblyVersion set in &lt;Version&gt; in the .csproj
    /// Timestamp β†’ AssemblyMetadata("BuildTimestamp", "dd.MM.yyyy_HH.mm.ss")
    ///             injected at compile time by the MSBuild SetBuildTimestamp target.
    ///             No generated .cs file required.
    /// </summary>
    internal static class VersionStamp
    {
        private const string Source = "LispLoader";

        internal static void Print()
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            // ── Version ───────────────────────────────────────────────────────
            string version = asm.GetName().Version?.ToString(3) ?? "?.?.???";

            // ── Timestamp from AssemblyMetadata ───────────────────────────────
            // The .csproj target adds:
            //   [assembly: AssemblyMetadata("BuildTimestamp", "12.06.2026_10.30.00")]
            string raw = asm
                .GetCustomAttributes<AssemblyMetadataAttribute>()
                .FirstOrDefault(a => a.Key == "BuildTimestamp")
                ?.Value
                ?? "??.??.????_??.??.??";

            // raw = "12.06.2026_10.30.00"
            string[] halves = raw.Split('_');
            string date = halves.Length > 0 ? halves[0] : "??";                    // 12.06.2026
            string time = halves.Length > 1 ? halves[1].Replace('.', ':') : "??";  // 10:30:00

            string banner = $"v{version} | built {date} {time}";

            LogManager.Separator();
            LogManager.Info(Source, banner);
            LogManager.Separator();
        }
    }
}


// ===== FILE: LogManager.cs =====
using System;
using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;

namespace LispLoader
{
    /// <summary>
    /// Log levels for filtering output.
    /// </summary>
    internal enum LogLevel { INFO, WARN, ERROR }

    /// <summary>
    /// Writes timestamped log lines to both the AutoCAD command line
    /// and a persistent .log file on disk.
    ///
    /// Format:  HH:mm:ss  [LEVEL]  [Source]  message
    /// Example: 05:29:43  [INFO]   [LispLoader]  Loaded ObjectPropExtra.dll
    /// </summary>
    internal static class LogManager
    {
        // ── Config ────────────────────────────────────────────────────────────
        private static readonly string LogFolder =
            @"C:\Users\mateid\OneDrive - DB E.C.O. Group\@C3D\@Dan_Templates\Acad\Support_files\Lisps\Help_File";

        private static readonly string LogFile =
            Path.Combine(LogFolder, "LispLoader.log");

        // Maximum log file size before it is rotated (5 MB)
        private const long MaxLogBytes = 5 * 1024 * 1024;

        // ── Public API ────────────────────────────────────────────────────────

        internal static void Info(string source, string message)
            => Write(LogLevel.INFO, source, message);

        internal static void Warn(string source, string message)
            => Write(LogLevel.WARN, source, message);

        internal static void Error(string source, string message)
            => Write(LogLevel.ERROR, source, message);

        internal static void Separator()
            => Write(null, null, new string('─', 72));

        // ── Core ──────────────────────────────────────────────────────────────

        private static void Write(LogLevel? level, string? source, string message)
        {
            string line = Format(level, source, message);

            // 1. AutoCAD command line
            try
            {
                Document? doc = Application.DocumentManager?.MdiActiveDocument;
                Editor? ed = doc?.Editor;
                ed?.WriteMessage("\n" + line);
            }
            catch { /* editor unavailable during early init β€” swallow */ }

            // 2. Disk log
            try
            {
                RotateIfNeeded();
                File.AppendAllText(LogFile, line + Environment.NewLine);
            }
            catch { /* disk unavailable β€” swallow */ }
        }

        private static string Format(LogLevel? level, string? source, string message)
        {
            string ts   = DateTime.Now.ToString("HH:mm:ss");
            string lvl  = level.HasValue ? $"[{level.Value,-5}]" : "       ";
            string src  = source != null ? $"[{source}]" : string.Empty;
            return $"{ts}  {lvl}  {src,-20}  {message}";
        }

        private static void RotateIfNeeded()
        {
            if (!File.Exists(LogFile)) return;
            var info = new FileInfo(LogFile);
            if (info.Length < MaxLogBytes) return;

            // Rename current log to .bak (overwrite previous backup)
            string bak = Path.ChangeExtension(LogFile, ".bak.log");
            if (File.Exists(bak)) File.Delete(bak);
            File.Move(LogFile, bak);
        }
    }
}


// ===== FILE: LispLoader.cs =====
using System.Collections.Generic;
using Autodesk.AutoCAD.Runtime;

// Register this assembly as an AutoCAD extension
[assembly: ExtensionApplication(typeof(LispLoader.LispLoaderApp))]

namespace LispLoader
{
    /// <summary>
    /// Entry point for the LispLoader AutoCAD plugin.
    ///
    /// AutoCAD calls Initialize() immediately after _.netload completes.
    /// Terminate() is called when AutoCAD shuts down.
    ///
    /// Usage β€” paste once into the AutoCAD command prompt:
    ///   (command "_.netload" "C:\\...\\LispLoader.dll")
    /// </summary>
    public class LispLoaderApp : IExtensionApplication
    {
        private const string Source = "LispLoader";

        // ── IExtensionApplication ─────────────────────────────────────────────

        public void Initialize()
        {
            // 1. Banner with version + build timestamp
            VersionStamp.Print();

            // 2. Read the config file
            IReadOnlyList<string> paths = ConfigReader.ReadPaths();

            if (paths.Count == 0)
            {
                LogManager.Warn(Source, "Nothing to load β€” check LoaderConfig.txt.");
                LogManager.Separator();
                return;
            }

            // 3. Load each file β€” failures are isolated, loading always continues
            int ok   = 0;
            int fail = 0;
            int skip = 0;

            LogManager.Info(Source, $"Starting load sequence: {paths.Count} file(s)");
            LogManager.Separator();

            foreach (string path in paths)
            {
                bool result = FileLoader.Load(path);

                if (result)      ok++;
                else if (System.IO.File.Exists(path)) fail++;
                else             skip++;
            }

            // 4. Summary
            LogManager.Separator();
            LogManager.Info(Source, $"Load complete β€”  OK: {ok}   FAILED: {fail}   SKIPPED (not found): {skip}");
            LogManager.Separator();
        }

        public void Terminate()
        {
            LogManager.Info(Source, "LispLoader unloaded.");
        }
    }
}

Additional info:

Share this page:

Page Tag: 🏷️ AutoLISP loader

  • LispLoader v1.0.000

    β€”

    by

    Short description🧩 LispLoader v1.0.000 is an AutoCAD and Civil 3D .NET startup loader that reads LoaderConfig.txt and safely processes configured LSP VLX FAS and DLL program files. πŸ“„ One configured file failing does not intentionally stop the remaining load sequence and all results are written to the AutoCAD command line and a rolling disk log.…

  • LispLoaderExtra

    β€”

    by

    Short description🧩 LispLoaderExtra v1.5.000 is a modeless AutoCAD and Civil 3D .NET loader for scanning filtering selecting loading and reloading LSP VLX FAS and DLL files from a structured CAD tool library. πŸŽ›οΈ The plugin provides a dark themed WinForms interface with category and name filters search checkboxes status columns a live log pane and…