ChatGPT Teams C#.NET Assistance & C3D Crash Diagnosis/Resolution

ChatGPT Teams C#.NET Assistance & C3D Crash Diagnosis/Resolution

hencoop
Advisor Advisor
435 Views
4 Replies
Message 1 of 5

ChatGPT Teams C#.NET Assistance & C3D Crash Diagnosis/Resolution

hencoop
Advisor
Advisor

Hi everyone,

I'm pretty new to .NET development — in 2020 completed a 17-hour beginner course and built a few basic AutoCAD apps as part of it. That said, I still struggled to independently structure a working .NET app for AutoCAD Civil 3D. I wasn’t (and maybe still am not) confident about how the .cs files should be structured or which references are essential.

Recently, I started using ChatGPT Teams to help build some .NET apps for Civil 3D, and it's been an amazing assistant and teacher. It even helped diagnose and fix an AutoCAD crash—twice now. The latest issue turned out to be due to corrupted or missing GEOLOCATION data, which apparently is a known issue. Oddly enough, in all my previous crashes, Autodesk never flagged this as a possible cause.

I’ve uploaded a PDF of my chat with ChatGPT, in case anyone’s interested in seeing how it assisted with coding and resolved VS linked crashing. Hopefully this helps someone else down the road!

Cheers,

AutoCAD User since 1989. Civil Engineering Professional since 1983
Product Version: 13.6.1963.0 Civil 3D 2024.4.1 Update Built on: U.202.0.0 AutoCAD 2024.1.6
                        27.0.37.14 Autodesk AutoCAD Map 3D 2024.0.1
                        8.6.52.0 AutoCAD Architecture 2024
436 Views
4 Replies
  • .net
Replies (4)
Message 2 of 5

jeff.wangD95HG
Collaborator
Collaborator

great to see someone with similar background as me. we should keep in touch with our experience using chatGPT for coding for civil3d

0 Likes
Message 3 of 5

essam-salah
Collaborator
Collaborator

Autodesk did good job for Revit by sharing an LLM.txt to be used with Cursor as a context to avoid hallucinations when we asked LLM to write codes for us, I hope Autodesk will do the same soon and share same file for Civil3d

0 Likes
Message 4 of 5

mmcguireL5Y2Y
Explorer
Explorer

I've been using Grok and realized that it often tries to use classes or commands that aren't valid, which led me astray for a while. I would paste the resulting error messages back into Grok, and it would respond with suggestions like missing reference files or a corrupt installation—none of which were actually the problem.

 

Eventually, I figured out the root issue and started looking for a way to "teach" Grok which classes, structures, and methods are actually valid within the various namespaces. AI suggested I use "reflection" to do that and it wrote the code for it - which produced a JSON file for each DLL associated with the Civil 3D Namespaces.  

 

I'm still using Grok 3, since I haven’t upgraded to version 4 yet. Sometimes it reads the JSON files correctly, but other times it either truncates them or claims to have read them but produces inconsistent results. Hopefully version 4 handles JSON more reliably.

 

When it *does* work, it's incredibly helpful. The AI realizes it's using an invalid command, searches for a valid one in the JSON, and rewrites the .cs code accordingly. I have one DLL with 600 lines of C# code to map custom properties to storm structures for various purposes—something I never could have written from scratch on my own.  I originally made one JSON file with all of the DLLs but it was 122MB in size and too large for AI uploading... so I made one JSON for each of the important DLL files.  

 

Having the reflected JSON files for the various DLL files (accoremgd, acbdmgd, acmgd, AecBaseMgd, AeccDbMgd, and AecPropDataMgd) has been key to keeping AI on track with valid C# code generation.  I would upload these files to the forum, but it's currently blocking .json file uploads.

 

Here's the .cs code for JSON reflection if you want it.  One created, just run NETLOAD to load it and ExtractDllInfoToJson to run it.  Should produce JSON files up to about 5MB in size.  

 

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.EditorInput;
using System.Reflection;
using System.IO;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows.Forms; // For FolderBrowserDialog
using Newtonsoft.Json;

public class DllInfo
{
public string Name { get; set; }
public string Version { get; set; }
public string FullName { get; set; }
public List<TypeInfo> Types { get; set; }
}

public class TypeInfo
{
public string Name { get; set; }
public bool IsPublic { get; set; }
public List<MethodInfo> Methods { get; set; }
public List<PropertyInfo> Properties { get; set; }
}

public class MethodInfo
{
public string Name { get; set; }
public string ReturnType { get; set; }
public List<string> Parameters { get; set; }
}

public class PropertyInfo
{
public string Name { get; set; }
public string Type { get; set; }
}

public class Commands
{
[CommandMethod("ExtractDllInfoToJson")]
public void ExtractDllInfoToJson()
{
var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
var ed = doc.Editor;

try
{
// Prompt for DLL file
PromptOpenFileOptions dllPrompt = new PromptOpenFileOptions("\nSelect DLL file to process")
{
Filter = "DLL files (*.dll)|*.dll|All Files (*.*)|*.*",
DialogCaption = "Select DLL File"
};
PromptFileNameResult dllResult = ed.GetFileNameForOpen(dllPrompt);
if (dllResult.Status != PromptStatus.OK)
{
ed.WriteMessage("\nDLL selection cancelled.");
return;
}
string dllPath = dllResult.StringResult;

// Prompt for output folder using FolderBrowserDialog
string outputPath; // Declare outputPath here to ensure scope
using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
{
folderDialog.Description = "Select Output Folder for JSON File";
folderDialog.SelectedPath = @"C:\Users\MarkMcGuire\Desktop";
folderDialog.ShowNewFolderButton = true;
DialogResult result = folderDialog.ShowDialog();
if (result != DialogResult.OK)
{
ed.WriteMessage("\nOutput folder selection cancelled.");
return;
}
outputPath = folderDialog.SelectedPath;
}

// Ensure output directory exists
if (!Directory.Exists(outputPath))
{
try
{
Directory.CreateDirectory(outputPath);
ed.WriteMessage($"\nCreated output directory: {outputPath}");
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nError creating output directory {outputPath}: {ex.Message}");
return;
}
}

// Define paths for dependency resolution
string civil3dPath = @"C:\Program Files\Autodesk\AutoCAD 2024\";
string civil3dC3DPath = @"C:\Program Files\Autodesk\AutoCAD 2024\C3D\";
string netFrameworkPath = @"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\";
string netAssemblyPath = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\";
string programFilesPath = @"C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.5\";

// Set up dependency resolution
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += (sender, args) =>
{
string assemblyName = new AssemblyName(args.Name).Name;

// Check Civil 3D-specific folder
string assemblyPath = Path.Combine(civil3dC3DPath, assemblyName + ".dll");
if (File.Exists(assemblyPath))
{
ed.WriteMessage($"\nResolved dependency: {assemblyPath}");
return Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}

// Check main AutoCAD folder
assemblyPath = Path.Combine(civil3dPath, assemblyName + ".dll");
if (File.Exists(assemblyPath))
{
ed.WriteMessage($"\nResolved dependency: {assemblyPath}");
return Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}

// Check .NET Framework folder
assemblyPath = Path.Combine(netFrameworkPath, assemblyName + ".dll");
if (File.Exists(assemblyPath))
{
ed.WriteMessage($"\nResolved dependency: {assemblyPath}");
return Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}

// Check .NET Reference Assemblies
assemblyPath = Path.Combine(netAssemblyPath, assemblyName + ".dll");
if (File.Exists(assemblyPath))
{
ed.WriteMessage($"\nResolved dependency: {assemblyPath}");
return Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}

// Check Microsoft SDKs for System.Windows.Interactivity
assemblyPath = Path.Combine(programFilesPath, assemblyName + ".dll");
if (File.Exists(assemblyPath))
{
ed.WriteMessage($"\nResolved dependency: {assemblyPath}");
return Assembly.ReflectionOnlyLoadFrom(assemblyPath);
}

try
{
return Assembly.ReflectionOnlyLoad(args.Name);
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nFailed to resolve dependency {assemblyName}: {ex.Message}");
return null;
}
};

// Process the selected DLL
ed.WriteMessage($"\nProcessing DLL: {dllPath}");
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(dllPath);
var assemblyInfo = new DllInfo
{
Name = assembly.GetName().Name,
Version = assembly.GetName().Version.ToString(),
FullName = assembly.GetName().FullName,
Types = new List<TypeInfo>()
};

int totalTypes = 0;
int includedTypes = 0;

try
{
foreach (Type type in assembly.GetTypes())
{
totalTypes++;
try
{
if (!type.FullName.StartsWith("Autodesk.AutoCAD.") &&
!type.FullName.StartsWith("Autodesk.Aec.") &&
!type.FullName.StartsWith("Autodesk.Civil."))
continue;

if (!type.IsPublic)
continue;

includedTypes++;
var typeInfo = new TypeInfo
{
Name = type.FullName,
IsPublic = type.IsPublic,
Methods = new List<MethodInfo>(),
Properties = new List<PropertyInfo>()
};

foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
{
try
{
var methodInfo = new MethodInfo
{
Name = method.Name,
ReturnType = method.ReturnType.FullName,
Parameters = method.GetParameters().Select(p => p.ParameterType.FullName + " " + p.Name).ToList()
};
typeInfo.Methods.Add(methodInfo);
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nError processing method {method.Name} in type {type.FullName}: {ex.Message}");
}
}

foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly))
{
try
{
var propertyInfo = new PropertyInfo
{
Name = property.Name,
Type = property.PropertyType.FullName
};
typeInfo.Properties.Add(propertyInfo);
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nError processing property {property.Name} in type {type.FullName}: {ex.Message}");
}
}

assemblyInfo.Types.Add(typeInfo);
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nError processing type {type?.FullName}: {ex.Message}");
}
}
}
catch (ReflectionTypeLoadException ex)
{
ed.WriteMessage($"\nError loading types from DLL {dllPath}:");
foreach (var loaderEx in ex.LoaderExceptions)
{
if (loaderEx != null)
ed.WriteMessage($"\n - LoaderException: {loaderEx.Message}");
}
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nError processing DLL {dllPath}: {ex.Message}");
}

ed.WriteMessage($"\nProcessed {totalTypes} total types, included {includedTypes} in {assemblyInfo.Name}");

string json = JsonConvert.SerializeObject(assemblyInfo, Formatting.Indented);
string outputFile = Path.Combine(outputPath, assemblyInfo.Name + ".json");
File.WriteAllText(outputFile, json);
ed.WriteMessage($"\nOutput written to: {outputFile}");
}
catch (System.Exception ex)
{
ed.WriteMessage($"\nGeneral error: {ex.Message}");
}
}
}

 

Message 5 of 5

Eng_ahmed_maw
Explorer
Explorer

Has anyone tried using Claude, as it is better for coding?

0 Likes