bvn-architecture / RevitBatchProcessor

Fully automated batch processing of Revit files with your own Python or Dynamo task scripts!
GNU General Public License v3.0
277 stars 75 forks source link

Fail to recognize all Revit versions installed in my PC #97

Closed Bright-Brave closed 1 year ago

Bright-Brave commented 1 year ago

Thanks for building such a nice project! It helps me a lot for saving my time. The problem is that I have several versions of Revit (2018/2019/2020/2022) in my PC, but RBP only gives me one option. PS: BatchRvtAddin was installed.

image

image

Bright-Brave commented 1 year ago

By the way, all revit versions except 2022 is not installed in defalut C directory path.

notionparallax commented 1 year ago

Are they all in places that could be described in a config file? something like:

rvt2019: default
rvt2022: C:\my_weird\path\to_somewhere\revit.exe
[...and so on...]

What would you expect the behaviour for non-default installs to be?

petersmithfromengland commented 1 year ago

Hi @Bright-Brave,

What is the location that your 2021 and earlier versions of Revit are installed to?

Cheers, Pete

Bright-Brave commented 1 year ago

Hi @notionparallax and @punderscoresmithuk, Sorry for getting back to you late. This is the locations of Revit.exe in my pc.

Revit2018: D:\Revit2018\Revit 2018\Revit.exe Revit2019: D:\Revit2019\Revit 2019\Revit.exe Revit2020: D:\Revit2020\Revit 2020\Revit.exe Revit2022: C:\Program Files\Autodesk\Revit 2022\Revit.exe (defalut)

Best Regards.

maciejwypych commented 1 year ago

Instead of hardcoding the Revit install paths in the RevitVersion.cs it could be done like this.


      public enum SupportedRevitVersion {
          Revit2015 = 0,
          Revit2016 = 1,
          Revit2017 = 2,
          Revit2018 = 3,
          Revit2019 = 4,
          Revit2020 = 5,
          Revit2021 = 6,
          Revit2022 = 7
      }
      private const string REVIT_EXECUTABLE_FILE_NAME = "Revit.exe";
      private static List<string?> REVIT_EXECUTABLE_FOLDER_PATHS()
      {
          var revitInstallPaths = new List<string?>();
          foreach (var versionName in Enum.GetNames(typeof(SupportedRevitVersion)))
          {
              var installLocation = GetRevitInstallPath(Enum.Parse<SupportedRevitVersion>(versionName));
              if (installLocation == null)
              {
                  continue;
              }
              revitInstallPaths.Add(GetRevitInstallPath(Enum.Parse<SupportedRevitVersion>(versionName)));
          }

          return revitInstallPaths;
      }

    private static string? GetRevitInstallPath(SupportedRevitVersion revitVersion)
    {
        var versionName= Enum.GetName(revitVersion);
        var version = versionName?.Remove(0, 5);
        var appPath = $@"SOFTWARE\Autodesk\Revit\{version}\REVIT-05:0809";
        if (appPath == null) throw new ArgumentNullException(nameof(appPath));
        using var sk = LocalMachine.OpenSubKey(appPath);
        if (sk is null)
        {
            return null;
        }

        var displayName = sk.GetValue("ProductName");
        var installLocation = sk.GetValue("InstallationLocation");
        return installLocation?.ToString();
    }

    public static string? GetRevitExecutableFolderPath(SupportedRevitVersion revitVersion)
    {

        if (GetRevitInstallPath(revitVersion) == null)
        {
            return null;
        }
        return File.Exists((Path.Combine(GetRevitInstallPath(revitVersion) ?? string.Empty, REVIT_EXECUTABLE_FILE_NAME)))? GetRevitInstallPath(revitVersion) : null ;
    }

    public static List<SupportedRevitVersion> GetInstalledRevitVersions()
    {
        return REVIT_EXECUTABLE_FOLDER_PATHS()
            .Where(IsRevitVersionInstalled)
            .Where(BatchRvt.IsBatchRvtAddinInstalled)
            .ToList();
    }
notionparallax commented 1 year ago

That's elegant.

image

Some questions (Given that I know next to nothing about the windows registry):

Bright-Brave commented 1 year ago

image @notionparallax That is what I care about. My install is REVIT-05:0804.

maciejwypych commented 1 year ago

In that case you could change the GetRevitInstallPath to check for the REVIT-05:.... subkey under each version


private static string? GetRevitInstallPath(SupportedRevitVersion revitVersion)
{
        var versionName= Enum.GetName(revitVersion);
        var version = versionName?.Remove(0, 5);
        var appPath = $@"SOFTWARE\Autodesk\Revit\{version}";
        if (appPath == null) throw new ArgumentNullException(nameof(appPath));
        using var sk = LocalMachine.OpenSubKey(appPath);
        if (sk is null)
        {
            return null;
        }

        string revitSubkey = null;
        foreach (var revitKey in sk.GetSubKeyNames())
        {
            if (!revitKey.Contains("REVIT-05:"))
            {
                continue;
            }

            revitSubkey = revitKey;

        }
        if (revitSubkey == null)
        {
            return null;
        }
        using var rk = sk.OpenSubKey(revitSubkey);
        if (rk is null)
        {
            return null;
        }
        var displayName = rk.GetValue("ProductName");
        var installLocation = rk.GetValue("InstallationLocation");
        return installLocation?.ToString();
}
jchristel commented 1 year ago

Hi, I did a google re whether registry key names are language specific and according to this microsoft doc the key name is not, but the value might be. I cant work out whether that Is an issue for a file path? Looking @Bright-Brave 's screen shot it might not be.

https://learn.microsoft.com/en-us/windows/win32/sysinfo/structure-of-the-registry

petersmithfromengland commented 1 year ago

Hi all,

This will get swept up in v1.9.0 coming early next week. Thanks @maciejwypych for the code!

Cheers, Pete