def _produce_asm_file(extension): # unique assembly filename for this package ext_asm_fileid = _make_ext_asm_fileid(extension) ext_asm_file_path = appdata.get_data_file(file_id=ext_asm_fileid, file_ext=ASSEMBLY_FILE_TYPE) # make unique assembly name for this package ext_asm_file_name = get_file_name(ext_asm_file_path) if _is_pyrevit_ext_already_loaded(ext_asm_file_name): logger.debug('Extension assembly is already loaded: {}'.format(ext_asm_file_name)) _update_component_cmd_types(extension) return ExtensionAssemblyInfo(ext_asm_file_name, ext_asm_file_path, True) elif appdata.is_data_file_available(file_id=ext_asm_fileid, file_ext=ASSEMBLY_FILE_TYPE): logger.debug('Extension assembly file already exists: {}'.format(ext_asm_file_path)) try: loaded_assm = load_asm_file(ext_asm_file_path) for asm_name in loaded_assm.GetReferencedAssemblies(): logger.debug('Checking referenced assembly: {}'.format(asm_name)) ref_asm_file_path = appdata.is_file_available(file_name=asm_name.Name, file_ext=ASSEMBLY_FILE_TYPE) if ref_asm_file_path: logger.debug('Loading referenced assembly: {}'.format(ref_asm_file_path)) try: load_asm_file(ref_asm_file_path) except Exception as load_err: logger.error('Error loading referenced assembly: {} | {}'.format(ref_asm_file_path, load_err)) _update_component_cmd_types(extension) return ExtensionAssemblyInfo(ext_asm_file_name, ext_asm_file_path, False) except Exception as ext_asm_load_err: logger.error('Error loading extension assembly: {} | {}'.format(ext_asm_file_path, ext_asm_load_err)) else: return _create_asm_file(extension, ext_asm_file_name, ext_asm_file_path)
def _create_asm_file(extension, ext_asm_file_name, ext_asm_file_path): # check to see if any older assemblies have been loaded for this package ext_asm_full_file_name = make_canonical_name(ext_asm_file_name, ASSEMBLY_FILE_TYPE) # this means that we currently have this package loaded and # we're reloading a new version is_reloading_pkg = _is_any_ext_asm_loaded(extension) # create assembly logger.debug('Building assembly for package: {}'.format(extension)) pyrvt_ver_int_tuple = get_pyrevit_version().as_int_tuple() win_asm_name = AssemblyName(Name=ext_asm_file_name, Version=Version(pyrvt_ver_int_tuple[0], pyrvt_ver_int_tuple[1], pyrvt_ver_int_tuple[2])) logger.debug('Generated assembly name for this package: {0}'.format( ext_asm_file_name)) logger.debug( 'Generated windows assembly name for this package: {0}'.format( win_asm_name)) logger.debug('Generated assembly file name for this package: {0}'.format( ext_asm_full_file_name)) # get assembly builder asm_builder = AppDomain.CurrentDomain.DefineDynamicAssembly( win_asm_name, AssemblyBuilderAccess.RunAndSave, op.dirname(ext_asm_file_path)) # get module builder module_builder = asm_builder.DefineDynamicModule(ext_asm_file_name, ext_asm_full_file_name) # create classes that could be called from any button (shared classes) # currently only default availability class is implemented. # Default availability class is for resetting buttons back to normal # context state (when reloading and after their context # has changed during a session). make_shared_types(module_builder) # create command classes for cmd_component in extension.get_all_commands(): # create command executor class for this command logger.debug('Creating types for command: {}'.format(cmd_component)) make_cmd_types(extension, cmd_component, module_builder) # save final assembly asm_builder.Save(ext_asm_full_file_name) load_asm_file(ext_asm_file_path) logger.debug('Executer assembly saved.') return ExtensionAssemblyInfo(ext_asm_file_name, ext_asm_file_path, is_reloading_pkg)
def _get_reference_file(ref_name): # First try to find the dll in the project folder addin_file = framework.get_dll_file(ref_name) if addin_file: load_asm_file(addin_file) return addin_file # Then try to find the dll in windows SDK if FRAMEWORK_DIRS: fw_module_file = _get_framework_module(ref_name) if fw_module_file: return fw_module_file # Lastly try to find location of assembly if already loaded loaded_asm = find_loaded_asm(ref_name) if loaded_asm: return loaded_asm[0].Location # if not worked raise critical error mlogger.critical('Can not find required reference assembly: %s', ref_name)
def _get_csharp_cmd_asm(cmd_component): """ Args: cmd_component (pyrevit.extensions.genericcomps.GenericUICommand): Returns: """ script_path = cmd_component.get_full_script_address() source = read_source_file(script_path) script_hash = get_str_hash(source)[:HASH_CUTOFF_LENGTH] command_assm_file_id = '{}_{}'\ .format(script_hash, cmd_component.unique_name) # check to see if compiled c# command assembly is already loaded compiled_assm_list = find_loaded_asm(command_assm_file_id, by_partial_name=True) if len(compiled_assm_list) > 0: return compiled_assm_list[0] # if not already loaded, check to see if the assembly file exits compiled_assm_path = \ appdata.is_data_file_available(file_id=command_assm_file_id, file_ext=ASSEMBLY_FILE_TYPE) if compiled_assm_path: return load_asm_file(compiled_assm_path) # else, let's compile the script and make the types command_assm_file = \ appdata.get_data_file(file_id=command_assm_file_id, file_ext=ASSEMBLY_FILE_TYPE) logger.debug('Compiling script {} to {}'.format(cmd_component, command_assm_file)) compiled_assm_path = compile_csharp([script_path], command_assm_file, reference_list=_get_references()) return load_asm_file(compiled_assm_path)
def _get_reference_file(ref_name): mlogger.debug('Searching for dependency: %s', ref_name) # First try to find the dll in the project folder addin_file = framework.get_dll_file(ref_name) if addin_file: load_asm_file(addin_file) return addin_file mlogger.debug('Dependency is not shipped: %s', ref_name) mlogger.debug('Searching for dependency in loaded assemblies: %s', ref_name) # Lastly try to find location of assembly if already loaded loaded_asm = find_loaded_asm(ref_name) if loaded_asm: return loaded_asm[0].Location mlogger.debug('Dependency is not loaded: %s', ref_name) mlogger.debug('Searching for dependency in installed frameworks: %s', ref_name) # Then try to find the dll in windows installed framework files if DOTNET_DIR: fw_module_file = _get_framework_module(ref_name) if fw_module_file: return fw_module_file mlogger.debug('Dependency is not installed: %s', ref_name) mlogger.debug('Searching for dependency in installed frameworks sdks: %s', ref_name) # Then try to find the dll in windows SDK if DOTNET_TARGETPACK_DIRS: fw_sdk_module_file = _get_framework_sdk_module(ref_name) if fw_sdk_module_file: return fw_sdk_module_file # if not worked raise critical error mlogger.critical('Can not find required reference assembly: %s', ref_name)
def _generate_base_classes_asm(): source_list = [] for source_file in _get_source_files(): source_list.append(source_file) # now try to compile try: mlogger.debug('Compiling base types to: %s', BASE_TYPES_ASM_FILE) compile_csharp(source_list, BASE_TYPES_ASM_FILE, reference_list=_get_references(), resource_list=[]) return load_asm_file(BASE_TYPES_ASM_FILE) except PyRevitException as compile_err: errors = safe_strtype(compile_err).replace('Compile error: ', '') mlogger.critical('Can not compile base types code into assembly.\n%s', errors) raise compile_err
def _generate_base_classes_asm(): source_list = list() source_list.append(_get_asm_attr_source()) for source_file in _get_source_files(): source_list.append(read_source_file(source_file)) # now try to compile try: logger.debug('Compiling base types to: {}'.format(BASE_TYPES_ASM_FILE)) # compile_csharp(source_list, BASE_TYPES_ASM_FILE, # reference_list=_get_references(), resource_list=[_get_resource_file('python_27_lib.zip')]) compile_csharp(source_list, BASE_TYPES_ASM_FILE, reference_list=_get_references()) return load_asm_file(BASE_TYPES_ASM_FILE) except PyRevitException as compile_err: logger.critical( 'Can not compile base types code into assembly. | {}'.format( compile_err)) raise compile_err
def _generate_base_classes_asm(): source_list = list() # source_list.append(_get_asm_attr_source()) for source_file in _get_source_files(): # source_list.append(read_source_file(source_file)) source_list.append(source_file) # now try to compile try: logger.debug('Compiling base types to: {}'.format(BASE_TYPES_ASM_FILE)) compile_csharp(source_list, BASE_TYPES_ASM_FILE, reference_list=_get_references(), resource_list=[]) return load_asm_file(BASE_TYPES_ASM_FILE) except PyRevitException as compile_err: errors = '\n'.join( eval(unicode(compile_err).replace('Compile error: ', ''))) logger.critical( 'Can not compile base types code into assembly.\n{}'.format( errors)) raise compile_err
def _get_base_classes_asm(): if appdata.is_data_file_available(file_id=BASE_TYPES_ASM_FILE_ID, file_ext=ASSEMBLY_FILE_TYPE): return load_asm_file(BASE_TYPES_ASM_FILE) else: return _generate_base_classes_asm()
make_canonical_name(LOADER_BASE_NAMESPACE, 'PyRevitCommandSelectionAvail') # template dynamobim command class DYNOCMD_EXECUTOR_TYPE_NAME = '{}.{}'\ .format(LOADER_BASE_NAMESPACE, 'PyRevitCommandDynamoBIM') SOURCE_FILE_EXT = '.cs' SOURCE_FILE_FILTER = r'(\.cs)' if not EXEC_PARAMS.doc_mode: # get and load the active Cpython engine CPYTHON_ENGINE = user_config.get_active_cpython_engine() if CPYTHON_ENGINE: CPYTHON_ENGINE_ASSM = CPYTHON_ENGINE.AssemblyPath mlogger.debug('Loading cpython engine: %s', CPYTHON_ENGINE_ASSM) load_asm_file(CPYTHON_ENGINE_ASSM) else: raise PyRevitException('Can not find cpython engines.') # create a hash for the loader assembly # this hash is calculated based on: # - basetypes csharp files # - runtime engine version # - cpython engine version BASE_TYPES_DIR_HASH = \ get_str_hash( calculate_dir_hash(INTERFACE_TYPES_DIR, '', SOURCE_FILE_FILTER) + EXEC_PARAMS.engine_ver + str(CPYTHON_ENGINE.Version) )[:HASH_CUTOFF_LENGTH] BASE_TYPES_ASM_FILE_ID = '{}_{}'\