Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Find C4D's directory without C4D

    Cinema 4D SDK
    python
    3
    9
    4.4k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • merkvilsonM
      merkvilson
      last edited by

      Hello PluginCafe 🙂

      I'm writing a standalone application which will be used for installing my C4D plugins.
      I need to find an appropriate way of finding plugins directory.

      Currently, I'm using a simple expression to define the preferences folder.
      Then I'm iterating through each file in the preferences folder and then creating plugins directory with os module.

      here is the code.

      import os
      from getpass import getuser as user
      
      def plugins_path(release_number):
          if os.name == 'nt': MAXON = r"C:\Users\{}\AppData\Roaming\MAXON".format(user()) #Windows
          if os.name != 'nt': MAXON = r"/Users/{}/Library/Preferences/MAXON".format(user()) #OSX
      
          plugins_path = ""
          for i in os.listdir(MAXON):
              if release_number.upper() in i.upper(): plugins_path = os.path.join(MAXON, i, "plugins")
      
          if os.path.exists(plugins_path): return plugins_path
      
      user_input = "R20"
      print(plugins_path(user_input))
      

      The problem is that some users are installing C4D in a custom directory and my code is very limited for this task.

      Is it possible to find an exact directory of C4D's plugins folder?

      1 Reply Last reply Reply Quote 0
      • M
        m_adam
        last edited by m_adam

        Hi @merkvilson thanks for reaching us,

        Here is a script to retrieves the Cinema 4D preference folder of a specific installation stored in temp folder working from R17 to R20.

        """
        Copyright: MAXON Computer GmbH
        Author: Maxime Adam
        
        Description:
            - Retrieves the path of the preference folder according to an installation path without the need to launch Cinema 4D.
        
        Note:
            - From Cinema 4D c4d.storage.GeGetC4DPath(c4d.C4D_PATH_STARTUPWRITE) can be called to retrieves the current installation path.
        
        Compatible:
            - Win / Mac
            - R17, R18, R19, R20
        """
        import os
        import platform
        
        
        def CRC(rawString):
            # Performs CRC 32 BIT on the input byte
            crc = 0xffffffff
        
            crc32tab_o32 = [
                0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
                0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,
                0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
                0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,
                0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,
                0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
                0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,
                0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,
                0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
                0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,
                0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,
                0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
                0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,
                0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,
                0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
                0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,
                0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,
                0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
                0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,
                0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,
                0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
                0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,
                0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,
                0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
                0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,
                0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,
                0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
                0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,
                0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,
                0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
                0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
                0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351]
        
            for s in rawString:
                k = ord(s)
                crc = crc32tab_o32[(crc & 0xff) ^ (k & 0xff)] ^ (crc >> 8)
                k >>= 8
                crc = crc32tab_o32[(crc & 0xff) ^ (k & 0xff)] ^ (crc >> 8)
                k >>= 8
                crc = crc32tab_o32[(crc & 0xff) ^ (k & 0xff)] ^ (crc >> 8)
                k >>= 8
                crc = crc32tab_o32[(crc & 0xff) ^ (k & 0xff)] ^ (crc >> 8)
        
            return format(crc ^ 0xffffffff, 'x').upper()
        
        
        def GetTempFolder(instalDir):
            # Retrieves the temp folder
            tempFolder = None
            if platform.system() == "Windows":
                tempFolder = os.getenv('APPDATA')
            elif platform.system() == "Darwin":
                libPath = os.path.expanduser('~/Library')
                tempFolder = os.path.join(libPath, "Preferences")
        
            if not os.path.exists(tempFolder) or tempFolder is None:
                raise RuntimeError("Failed to retrieves appdata folder.")
        
            # Cleanups the input path
            instalDir = os.path.normpath(instalDir)
            instalDir = instalDir.replace('\\\\', '\\')
            parentDirLower = instalDir.lower()
        
            # Retrieves only the name of the last folder
            parentName = os.path.split(instalDir)[1]
            if not parentName:
                raise RuntimeError("Failed to retrieves parent Name folder")
        
            parentName = parentName.replace(':', '_')
        
            # Computes the crc of the dir in lowercase.
            crc = CRC(parentDirLower)
        
            # Builds the final path
            finalPath = os.path.join(tempFolder, "MAXON", parentName + "_" + crc)
        
            return finalPath
        
        
        def main():
            # Path must be in unicode, it can be retrieved from c4d with c4d.storage.GeGetStartupPath()
            winInstallationPath = unicode("C:\Program Files\MAXON\Cinema 4D R20")
            macInstallationPath = unicode("/Users/m_adam/Application/MAXON/Cinema 4D R20")
            print "Path:", GetTempFolder(winInstallationPath)
        
        
        if __name__ == '__main__':
            main()
        

        As a side note in R20 plugins can be installed everywhere as long as the path is set in the preferences.
        And finally, there is no reliable way to know where Cinema 4D is installed from outside of Cinema 4D.

        If you have any question, please let me know.
        Cheers,
        Maxime.

        MAXON SDK Specialist

        Development Blog, MAXON Registered Developer

        1 Reply Last reply Reply Quote 2
        • merkvilsonM
          merkvilson
          last edited by

          Thanks, Maxime!

          Can you tell me about Copyright and EULA? How can I use this code in my software?

          1 Reply Last reply Reply Quote 0
          • M
            m_adam
            last edited by m_adam

            @merkvilson, sorry this code is planned to be part of our github, so like any of our examples, they are under the Apache License.

            For more information see Apache License from our Github repository.
            Cheers,
            Maxime.

            MAXON SDK Specialist

            Development Blog, MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • merkvilsonM
              merkvilson
              last edited by

              Thanks, Maxime! 🙂

              I tested the code, and it works.
              But this is not what I exactly wanted.

              As I mentioned, the problem is that some users are installing C4D in a custom directory and I can't find preferences path nor an actual installation path.

              I also tried os.walk() Method to find MAXON directory, but it has two significant problems.

              1. It's too slow
              2. there are several folders called MAXON

              The only thing that users can define is the release number, and I have to find it according to the string, for example, "R20".

              Here is how the installer works.

              alt text

              It works on most of the computers but some users already reported that it can't find their directory so they are forced to manually define it but most of them are defining global directory. If you remember, I had to remove symbolcache file and this is one of the reasons why I made this installer.

              1 Reply Last reply Reply Quote 1
              • M
                m_adam
                last edited by m_adam

                Unfortunately, Cinema 4D does not track this, and there is no way to know it currently since Cinema 4D is almost a portable application (you can copy/paste Cinema 4D folder to anywhere as long as dependencies have been installed once it will work).

                In any case, it's a request we already made to our development team, I'll push the topic again and will see 😉.
                Cheers,
                Maxime.

                MAXON SDK Specialist

                Development Blog, MAXON Registered Developer

                1 Reply Last reply Reply Quote 1
                • merkvilsonM
                  merkvilson
                  last edited by merkvilson

                  Thanks, Maxime! This script is still quite useful.
                  Is it possible to use it in order to find C4D executable on Windows as well as on mac?

                  Let's assume the directory is C:\Program Files\MAXON\Cinema 4D R20\ which contains several exe. How to define which one is the Cinema 4D itself?

                  I tried this way but I guess there should be a better option

                  
                  def MAXON_P():
                      if os.name == 'nt': MAXON = r"C:\Program Files\MAXON"
                      if os.name != 'nt': MAXON = r"/Applications/MAXON"
                      if os.path.exists(MAXON): return MAXON
                      else: return ""
                  
                  def c4d_executable_path(ver):
                  
                      user_ver = ""
                      versions = os.listdir(MAXON_P())
                      for i in versions:
                          if ver.upper() in i.upper() and "demo".upper() not in i.upper():
                              user_ver = i
                  
                      c4d_folder = os.path.join(MAXON_P(), user_ver,)
                      files = os.listdir(c4d_folder)
                  
                      for file in files:
                          if os.name == 'nt' and "CINEMA 4D" in file.upper() and "exe" in file and len(file) < 18: ex = file
                          if os.name != 'nt' and "CINEMA 4D" in file.upper() in file and len(file) < 18: ex = file
                  
                      return os.path.join(c4d_folder, ex)
                  
                  
                  
                  print c4d_executable_path("R20")
                  
                  1 Reply Last reply Reply Quote 0
                  • M
                    mp5gosu
                    last edited by mp5gosu

                    On Windows, you can use a little trick: To retrieve the currently used Cinema 4D installation, you can query the registry for the program associated with *.c4d files.
                    This gives you only a single installation - probably the most current one.

                    Is it possible to use it in order to find C4D executable on Windows as well as on mac?

                    On Win+Mac, filenames must be unique. So, Cinema 4D.exe/app should be sufficient.

                    1 Reply Last reply Reply Quote 0
                    • merkvilsonM
                      merkvilson
                      last edited by

                      Thanks, buddy! 🙂
                      But the problem is that the most current one is not a way to go.

                      If the user installed the plugin for R16, then the installer should open R16 itself.

                      I'm trying to find and open it by the name, but the name is always different. It can be Cinema 4D / Cinema 4D R16 / Cinema 4D R16 Demo / Cinema 4D Demo / etc.
                      Well. This is considerably easier on windows since I can check if it exists by using os.path.exists() function, but I have no Idea how to do this on Mac.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post