Author Topic: Quick recovering AutoCAD for current user  (Read 2013 times)

0 Members and 1 Guest are viewing this topic.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Quick recovering AutoCAD for current user
« on: July 06, 2016, 10:56:20 AM »
If the program is launched at first time at the current user profile, then Windows installs the absent components of this program.

Sometimes AutoCAD 2009 spoils own menu files and some settings. At this case I recover the application state programmatically through the deleting its registry key in HKCU (HKEY_CURRENT_USER\Software\Autodesk\AutoCAD\R<Major>.<Minor>\<ProductCode>:<LCID>) and its folders in the current user profile (RoamableRootFolder, LocalRootFolder). Now I am to install necessary components (they recreate the registry key in HKCU and folders). For this purpose I programmatically launch the application. But I want to kill the process when the necessary components will be installed complettely during the application starting (because AutoCAD launching takes many time).

If I kill the acad.exe process, then the components installing will be killed too. I dont need such behaviour.



Is it possible to define (programmatically, I use C#) the moment when the installing of these components was finished? Or maybe it is possible to define that some components of AutoCAD are not installed on the current user profile still and then to force the launching of these components installing without the `acad.exe` launching (I don't know how to do it). 

BlackBox

  • King Gator
  • Posts: 3770
Re: Quick recovering AutoCAD for current user
« Reply #1 on: July 06, 2016, 11:14:54 PM »
Not sure that this can be done as a plugin, as the required events may not be raised, however you can monitor the Registry via WMI, and take supplementary steps after the fact:

https://code.msdn.microsoft.com/windowsapps/CSMonitorRegistryChange-d297cdf0


Cheers
"How we think determines what we do, and what we do determines what we get."

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Quick recovering AutoCAD for current user
« Reply #2 on: July 07, 2016, 05:56:43 AM »
Thank you for your answer.

Quote from: BlackBox
Not sure that this can be done as a plugin

I do it through external application instead of AutoCAD plugin. I don't need to monitor the registry changing, because I always know that it was changed (or wasn't changed) by me. In ideal, I only need to initialize installation of the AutoCAD components which are absent in the current user profile.

Perhaps my code will help to explain what I want to do:
Code - C#: [Select]
  1. static void Main(string[] args) {
  2.  
  3.     /* We will assume that settings of all AutoCAD were
  4.      * damaged and it is necessary to do the recovery
  5.      * of them. */
  6.  
  7.     /* The AutoCAD applications set which was installed
  8.      * on the current machine. */
  9.     InstalledProduct[] installed_aps = LocalizedProduct
  10.         .GetInstalledProducts();
  11.  
  12.     Console.WriteLine("Installed AutoCAD set:");
  13.  
  14.     foreach (var lm_app in installed_aps) {
  15.         Console.WriteLine("{0}\n{1}\n\n", lm_app
  16.             .Product.Name, lm_app.Location);
  17.     }
  18.  
  19.     /* Get the existing registry keys of AutoCAD
  20.      * products in HKCU. */
  21.     InitializedProduct[] init_apps = LocalizedProduct
  22.         .GetInitializedProducts();
  23.  
  24.     Console.WriteLine("The AutoCAD applications which"
  25.     + " were launched by current user at least once:");
  26.  
  27.     /* Recovery each AutoCAD current user settings. */
  28.     foreach (var cu_app in init_apps) {
  29.  
  30.         Console.WriteLine("{0}\n{1}\n\n", cu_app
  31.             .InstalledProduct.Product.Name, cu_app
  32.             .InstalledProduct.Location);
  33.  
  34.         try {
  35.             if (Directory.Exists(cu_app
  36.                 .RoamableRootFolder)) {
  37.  
  38.                 Directory.Delete(cu_app
  39.                     .RoamableRootFolder, true);
  40.             }
  41.         }
  42.         catch (Exception ex) {
  43.             Console.WriteLine(ex.Message);
  44.         }
  45.  
  46.         try {
  47.             if (Directory.Exists(cu_app.LocalRootFolder
  48.                 )) {
  49.  
  50.                 Directory.Delete(cu_app.LocalRootFolder
  51.                     , true);
  52.             }
  53.         }
  54.         catch (Exception ex) {
  55.             Console.WriteLine(ex.Message);
  56.         }
  57.  
  58.         RegistryKey rk = Registry.CurrentUser
  59.             .OpenSubKey(cu_app.InstalledProduct
  60.             .SubkeyName, false);
  61.  
  62.         bool exists = rk != null;
  63.  
  64.         if (exists) {
  65.  
  66.             rk.Close();
  67.             ((IDisposable) rk).Dispose();
  68.  
  69.             Registry.CurrentUser.DeleteSubKeyTree(
  70.                 cu_app.InstalledProduct.SubkeyName);
  71.         }
  72.  
  73.         /* Now I want to force the install of AutoCAD
  74.          * components which I deleted above. I.e. I
  75.          * recovery the damaged settings to the state
  76.          * which was directly as soon as AutoCAD was
  77.          * installed. */
  78.  
  79.         /* The absent components will be installed
  80.          * during the next AutoCAD session. */
  81.         using (Process proc = new Process()) {
  82.  
  83.             ProcessStartInfo info = new
  84.                 ProcessStartInfo();
  85.  
  86.             info.FileName = Path.Combine(cu_app
  87.                 .InstalledProduct.Location, "acad.exe")
  88.                 ;
  89.  
  90.             info.UseShellExecute = false;
  91.             proc.StartInfo = info;
  92.  
  93.             /* It initializes installing the components
  94.              * also. */
  95.             proc.Start();
  96.  
  97.             /* When all components will be installed
  98.              * the AutoCAD application will be
  99.              * launched. So, I want to catch this
  100.              * moment and close the `acad` process.*/
  101.  
  102.             /* It doesn't close the AutoCAD main
  103.              * window: */
  104.             while (proc.MainWindowHandle == IntPtr
  105.                 .Zero) {
  106.                 proc.Refresh();
  107.             }
  108.             proc.CloseMainWindow();
  109.  
  110.             /* It interrupts also the components
  111.              * installing: */
  112.             // proc.Kill();
  113.  
  114.             proc.Close();
  115.         }
  116.     }
  117. }

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Quick recovering AutoCAD for current user
« Reply #3 on: July 08, 2016, 05:07:11 AM »
I solved my problem:
Code - C#: [Select]
  1. while (true) {
  2.     RegistryKey unpr = Registry.CurrentUser
  3.         .OpenSubKey(cu_app.InstalledProduct
  4.         .SubkeyName +
  5.         @"\Profiles\<<Unnamed Profile>>",
  6.         false);
  7.  
  8.     if (unpr != null) {
  9.         using (unpr) {
  10.             unpr.Close();
  11.         }
  12.         break;
  13.     }
  14. }
  15.  
  16. /* Just in case we wait for half a second -
  17.  * it enough. Code successfully works
  18.  * without this waiting also.*/
  19. Thread.Sleep(500);
  20.  
  21. /* Now the components are installed. */
  22. proc.Kill();
  23. proc.Close();