Author Topic: Acad.exe location  (Read 2574 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6150
Acad.exe location
« on: May 27, 2014, 07:45:49 PM »
Thought it might bring up some ideas or good conversation

For 2013 you have CleanupScales.exe and CleanupRegapp.exe which you are to extract files and copy to same folder as acad.exe then run the tools.

So wanted to be able to use them by passing exe file to Process.Start

So Needed the location of acad.exe and did quick search and did not find a quick way or property of HostApplication other than the registry values,

So making assumptions like accoremgd & acmgd are located in same folder as acad.exe

This is in no way tested thoroughly or would use this for any deployment outside local office but when only a handful of people and are in same office what the hell.

So took a quick dirty approach that worked my for needs.
1 or 2 different ways

Code - C#: [Select]
  1.         [CommandMethod("AcadexeDirty")]
  2.         public void AcadexeDirty()
  3.         {
  4.             //Assuming accoremgd & acmgd will be in same folder as acad.exe
  5.             //Then accoremgd for 2013 and later and acmgd for 2012 and earlier
  6.             //has method used to invoke commands that are registered via CommandMethod Attribute
  7.             //So will get calling assemblies file to look for acad.exe.
  8.             //If called another method that used Assembly.GetCallingAssembly() and returned a string
  9.             //Then would give the location of this assembly and not work.
  10.  
  11.             var callingAssemblyLocation = Assembly.GetCallingAssembly().Location;
  12.             Ed.WriteLine("\nAssembly.GetCallingAssembly = {0}", callingAssemblyLocation);
  13.  
  14.             var callingAssemblyDirectory = Path.GetDirectoryName(callingAssemblyLocation);
  15.             if (callingAssemblyDirectory == null) return;
  16.  
  17.             Ed.WriteLine("\nCallingAssembly Directory = {0}", callingAssemblyDirectory);
  18.  
  19.             DirectoryInfo di = new DirectoryInfo(callingAssemblyDirectory);
  20.             if (di.Exists && di.EnumerateFiles().Any(fi => fi.Name.ToLower() == "acad.exe"))
  21.             {
  22.                 Ed.WriteLine("\nCallingAssembly Directory {0} contain acad.exe",
  23.                     di.EnumerateFiles().Any(fi => fi.Name.ToLower() == "acad.exe")
  24.                     ? "does"
  25.                     : "does not");
  26.             }
  27.  
  28.             HostApplicationServices.Current.Program
  29.  
  30.  
  31.             //Get all assemblies loaded in CurrentDomain
  32.             //Check for accoremgd.dll to check if at least accoreconsole.exe is calling code
  33.             //Check for acmgd.dll to see if acad application
  34.            
  35.             Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
  36.  
  37.             if (assemblies.Any(assem => assem.ManifestModule.Name.ToLower() == "accoremgd.dll"))
  38.             {
  39.                 Ed.WriteLine("\nacadcoreconsole.exe or acad.exe");
  40.  
  41.                 Ed.WriteLine("\n{0}",
  42.                     assemblies.Any(assem => assem.ManifestModule.Name.ToLower() == "acmgd.dll")
  43.                     ? "acad.exe"
  44.                     : "acadcoreconsole.exe");
  45.             }
  46.             Ed.WriteLine();
  47.             Ed.WriteLine("                   ----");
  48.             Ed.WriteLine();
  49.             Ed.WriteLine("\nCurrentDomain.GetAssemblies count = {0}", assemblies.Length);
  50.  
  51.             foreach (var assembly in assemblies)
  52.             {
  53.                 Ed.WriteLine("\nLocation = {0} ManifestModule.Name = {1} ", assembly.Location, assembly.ManifestModule.Name);
  54.             }
  55.         }
  56.  


Oh yeah quick thingy slapped together that will leave as be unless have to modify it more than once from error or what ever

Code - C#: [Select]
  1.         [CommandMethod("RegCleanUpApp")]
  2.         public void RegCleanUpApp()
  3.         {
  4.             var location = Assembly.GetCallingAssembly().Location;
  5.             RunClleanupApp("CleanupRegapp.exe", location);
  6.         }
  7.  
  8.  
  9.         [CommandMethod("ScaleCleanUpApp")]
  10.         public void ScaleCleanUpApp()
  11.         {
  12.             var location = Assembly.GetCallingAssembly().Location;
  13.             RunClleanupApp("CleanupScales.exe", location);
  14.         }
  15.  
  16.  
  17.         private void RunClleanupApp(string exeFilename, string location)
  18.         {
  19.             try
  20.             {
  21.                
  22.                 var path = Path.GetDirectoryName(location);
  23.                 if (path == null)
  24.                 {
  25.                     Ed.WriteLine("{0} is not in directory", location);
  26.                     return;
  27.                 }
  28.                 DirectoryInfo di = new DirectoryInfo(path);
  29.                 FileInfo fi = new FileInfo(Path.Combine(di.FullName, exeFilename));
  30.                 if (di.Exists && fi.Exists)
  31.                 {
  32.                     Process proc = new Process();
  33.                     proc.StartInfo.FileName = fi.FullName;
  34.                     proc.Start();
  35.                 }
  36.                 else
  37.                 {
  38.                     if (!fi.Exists)
  39.                     {
  40.                         Ed.WriteLine(fi.FullName);
  41.                     }
  42.                     if (!di.Exists)
  43.                     {
  44.                         Ed.WriteLine(di.FullName);
  45.                     }
  46.                    
  47.                 }
  48.  
  49.                
  50.             }
  51.             catch (Exception ex)
  52.             {
  53.                 Ed.WriteLine(ex.Message);
  54.             }
  55.         }
  56.  


« Last Edit: May 27, 2014, 07:49:42 PM by Jeff H »

LE3

  • Guest
Re: Acad.exe location
« Reply #1 on: May 27, 2014, 08:55:54 PM »
^ Interesting - Jeff.

I know you mentioned you went or know the registry route, I'll post what I have used on my old NetAppInstaller, posted here in case helps:

Code - C#: [Select]
  1.         private static Dictionary<string, string> GetAutodeskInstalledsoftware()
  2.         {
  3.             var namesAndPaths = new Dictionary<string, string>();
  4.             const string softwareKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
  5.             using (var subKey = Registry.LocalMachine.OpenSubKey(softwareKey))
  6.             {
  7.                 if (subKey == null) return null;
  8.                 foreach (var subKeyName in subKey.GetSubKeyNames())
  9.                 {
  10.                     using (var key = subKey.OpenSubKey(subKeyName))
  11.                     {
  12.                         try
  13.                         {
  14.                             if (key == null || key.GetValue("Publisher") == null) continue;
  15.                             if ((string) key.GetValue("Publisher") != "Autodesk") continue;
  16.                             if (key.GetValue("DisplayName") == null) continue;
  17.                             string name;
  18.                             string path;
  19.                             if (key.GetValue("InstallLocation") == null)
  20.                             {
  21.                                 name = (string) key.GetValue("DisplayName");
  22.                                 path = "Install path not known";
  23.                             }
  24.                             else
  25.                             {
  26.                                 name = (string) key.GetValue("DisplayName");
  27.                                 path = (string) key.GetValue("InstallLocation");
  28.                             }
  29.  
  30.                             if (string.IsNullOrWhiteSpace(name)) continue;
  31.                             if (string.IsNullOrWhiteSpace(path)) continue;
  32.                             if (namesAndPaths.ContainsKey(name)) continue;
  33.  
  34.                             namesAndPaths.Add(name, path);
  35.  
  36. #if SKIP_TOO
  37.                             // also skip any other Autodesk product like: objectARX - Material Library - Language Pack
  38.                             // how about Revit...
  39.                             if (name.Contains("ObjectARX") ||
  40.                                 name.Contains("Material Library") ||
  41.                                 name.Contains("Language Pack") ||
  42.                                 name.Contains("Revit") ||
  43.                                 (path == "Install path not known"))
  44.                             {
  45.                                 // TODO: OR CONTINUE...
  46.                             }
  47. #endif
  48.  
  49.                         }
  50.                         catch (System.Exception ex)
  51.                         {
  52.                             MessageBox.Show(ex.Message);
  53.                         }
  54.                     }
  55.                 }
  56.             }
  57.             return namesAndPaths;
  58.         }
  59.  

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Acad.exe location
« Reply #2 on: May 28, 2014, 02:11:10 PM »
Jeff,

Maybe I have incorrectly understood you... Are you want to get the  location directory of acad.exe or accoreconsole.exe? If "YES" is an answer, then why you have invented these bicycles (in my opinion)?

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: Acad.exe location
« Reply #3 on: May 28, 2014, 11:42:24 PM »
I use
Code - C#: [Select]
  1. using System.Diagnostics
  2.  
  3.  
  4. Process.GetCurrentProcess().MainModule.Filename

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Acad.exe location
« Reply #4 on: May 29, 2014, 01:37:38 AM »
WILL HATCH,

Yes, your way is more nice than the "native" one - through registry (the second way depends on versions of AutoCAD and .NET):
Code - C#: [Select]
  1. using Hs = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices;
  2.  
  3. String exePath = String.Empty;
  4. #if ACAD2009
  5.         // AutoCAD 2009 can use the .NET 2.0 - 3.5 SP1
  6.         // RegistryKey is not implementing the IDisposable for the .NET 2.0 - 3.5 SP1
  7.         exePath = Registry.LocalMachine.OpenSubKey(Hs.Current.RegistryProductRootKey, false).GetValue("Location") as String;
  8. #else
  9.         // RegistryKey implements the IDisposable in the .NET 4.0 and late.                            
  10.         // The MachineRegistryProductRootKey instead of RegistryProductRootKey now.
  11.         using (RegistryKey lmAcad = Registry.LocalMachine.OpenSubKey(Hs.Current.MachineRegistryProductRootKey, false)) {
  12.                 exePath = lmAcad.GetValue("Location") as String;
  13.         }
  14. #endif

Quote from: Jeff H
and did not find a quick way or property of HostApplication other than the registry values
Read the comment in the 10-th code row (if I correctly understood you).
« Last Edit: May 29, 2014, 01:46:43 AM by Andrey Bushman »

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: Acad.exe location
« Reply #5 on: May 29, 2014, 01:52:16 AM »
It's not only cleaner in this instance.  The Process object makes it very easy to 'look up' at the environment around you.  While you are easily able to get the file location through the registry it sounds like Jeff also needs to determine if his process is being called by core console or full acad, and the process object gives you that as well. He was on the right track with Assembly but the scope of that object does not reach that far.