// Since AutoCAD 2011 the `CustomizationSection.RemovePartialMenu()`
// method has other signature.
// Also, the BUNDLE-package autoloader have appeared since AutoCAD 2012.
static readonly System.Version acad_2011_version = new System.Version(
18, 1, 0, 0);
// Since AutoCAD 2013 the
// 'SystemObjects.DynamicLinker.ProductKey' property
// moved into the 'HostApplicationServices.Current.UserRegistryProductRootKey'.
static readonly System.Version acad_2013_version = new System.Version(
19, 0, 0, 0);
...
#if OLDER_THAN_AUTOCAD_2012
const string acedSetEnv_FileName = "acad.exe";
#else
const string acedSetEnv_FileName = "accore.dll";
#endif
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport(acedSetEnv_FileName, CharSet = CharSet.Auto,
CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 acedSetEnv(String envName, StringBuilder NewValue);
...
// AutoCAD versions older than 2012 haven't BUNDLE-package
// autoloader.
if (cad.Version <= acad_2011_version) {
try {
// Add the record into the 'Support File Search Path' if it is
// not exist still.
string cProfileName = cad.GetSystemVariable("cprofile") as string;
String productKey = string.Empty;
if (cad.Version >= acad_2013_version) {
productKey = (string) HostApplicationServices.Current.GetType().InvokeMember(
"UserRegistryProductRootKey",
BindingFlags.Public | BindingFlags.GetProperty |
BindingFlags.Instance, null, HostApplicationServices.Current, null);
}
else {
productKey = (string)SystemObjects.DynamicLinker.GetType().InvokeMember(
"ProductKey",
BindingFlags.Public | BindingFlags.GetProperty |
BindingFlags.Instance, null, SystemObjects.DynamicLinker, null);
}
String keyName = String.Format(@"{0}\Profiles\{1}\General",
productKey, cProfileName);
RegistryKey regKey = Registry.CurrentUser.OpenSubKey(keyName, true);
String regValue = regKey.GetValue("Acad", string.Empty) as string;
// It is true for .Net Framework new versions.
if (regKey is IDisposable) {
((IDisposable)regKey).Dispose();
}
regValue = regValue.Substring(0, regValue.Length - 1);
List<string> paths = new List<string>(regValue.Split(';')
.Where(n => n.Trim() != string.Empty)
.Select(n => n.ToLower()));
string path = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(
Assembly.GetExecutingAssembly().Location), @"..\..\..\")).ToLower();
string path2 = path.Substring(0, path.Length - 1); // without of the last '\' char.
if (!paths.Contains(path) && !paths.Contains(path2)) {
StringBuilder sbPaths = new StringBuilder();
foreach (string item in paths) {
sbPaths.AppendFormat("{0};", item);
}
sbPaths.Append(path2 + ";"); // I have tried with and without the ';' char...
int setEnvResult = acedSetEnv("Acad", sbPaths); // 5100 i.e. RTNORM
// TODO: The problem is here... The result is RTNORM but the
// `Support File Search Path` and its registry value wasn't changed...
}
}
catch (System.Exception ex) {
doc.Editor.WriteMessage(ex.Message);
}
}