**Why does it crash?**<br> Your code crashes blender because of a `EXCEPTION_ACCESS_VIOLATION`. For further information, see https://docs.blender.org/api/3.3/info_gotcha.html#help-my-script-crashes-blender. (you already know this, just for the sake of completeness) Looking at the report it states: ``` Stack trace: blender.exe :0x00007FF616E36350 BLI_findstring blender.exe :0x00007FF611AE7CF0 IDP_AddToGroup blender.exe :0x00007FF612013EC0 RNA_property_string_set blender.exe :0x00007FF61658A070 file_browse_exec blender.exe :0x00007FF611DA05D0 wm_handler_fileselect_do blender.exe :0x00007FF611DA1F60 wm_handlers_do_intern blender.exe :0x00007FF611DA1390 wm_handlers_do blender.exe :0x00007FF611DA7920 wm_event_do_handlers blender.exe :0x00007FF611D8D820 WM_main blender.exe :0x00007FF610E82360 main blender.exe :0x00007FF617069750 __scrt_common_main_seh KERNEL32.DLL :0x00007FFB5D017600 BaseThreadInitThunk ntdll.dll :0x00007FFB5EF226D0 RtlUserThreadStart ``` Therefore I assume base on `BLI_findstring` the location of the `folder:StringProperty` has changed in memory after the selection, which then causes an `EXCEPTION_ACCESS_VIOLATION`. Another attempt of explanation could be to add the following to the `folder:StringProperty`: ``` def get_folder(self): return self.get("folder", "") def set_folder(self, value): self["folder"] = value folder: bpy.props.StringProperty(name="Choose Folder", subtype="DIR_PATH", get=get_folder, set=set_folder) ``` This will cause the following error: ``` Traceback (most recent call last): File "\Text", line 18, in set_folder TypeError: unsubscriptable object File "\Text", line 16, in set_folder Traceback (most recent call last): File "\Text", line 16, in get_folder ``` because an instance of `SelectDirExample` is unsubscriptable to `self['key'] = value`. This getter, setter implementation maybe prevent the blender from crashing, because the default and setter, getter function are overwritten. **Solution 2 is preferred** **Solution**<br> I don't think an easy solution like this is possible because you are using a dialog which is a floating window and the folder selection will overwrite the current floating window. Also take a look at the info area/info-log of Blender, the Operator isn't executed/registered. Which means it hasn't returned `{'FINISHED'}` and `execute` was never called. Therefore, to implement something like this, you would need to call operator `SelectDirExample` again. ```python import bpy from bpy.types import Operator, PropertyGroup class SelectDirExample(Operator): bl_idname = "object.select_dir_example" bl_label = "Select Dir Example" bl_options = {'REGISTER', 'UNDO'} instances = 0 invoked = False def setter_getter(name: str): return { 'get': lambda self: getattr(bpy.context.scene.selected_dir, name), 'set': lambda self, value: setattr(bpy.context.scene.selected_dir, name, value) } input1: bpy.props.FloatProperty(name="Input 1", default=1.0, min=0.0, max=100.0, **setter_getter('input1')) input2: bpy.props.FloatProperty(name="Input 2", default=1.0, min=0.0, max=100.0, **setter_getter('input2')) def get_folder(self): return bpy.context.scene.selected_dir.folder def set_folder(self, value): props = bpy.context.scene.selected_dir props.folder = value if SelectDirExample.instances != 0 or not SelectDirExample.invoked: return SelectDirExample.instances += 1 bpy.ops.object.select_dir_example("INVOKE_DEFAULT", input1=props.input1, input2=props.input2, folder=props.folder) SelectDirExample.instances -= 1 SelectDirExample.invoked = False folder: bpy.props.StringProperty(name="Choose Folder", subtype="DIR_PATH", get=get_folder, set=set_folder) def invoke(self, context, event): SelectDirExample.invoked = True return_code = context.window_manager.invoke_props_dialog(self, width = 300) return return_code def execute(self, context): input1 = self.input1 input2 = self.input2 folder = self.folder # My processing goes here print(f"Folder location is: {folder}") # Finished processing. SelectDirExample.invoked = False return {'FINISHED'} class SelectDirExample_Props(PropertyGroup): input1: bpy.props.FloatProperty(name="Input 1", default=1.0, min=0.0, max=100.0) input2: bpy.props.FloatProperty(name="Input 2", default=1.0, min=0.0, max=100.0) folder: bpy.props.StringProperty(name="Choose Folder", subtype="DIR_PATH") def register(): bpy.utils.register_class(SelectDirExample) bpy.utils.register_class(SelectDirExample_Props) bpy.types.Scene.selected_dir = bpy.props.PointerProperty(type=SelectDirExample_Props) def unregister(): bpy.utils.unregister_class(SelectDirExample) bpy.utils.unregister_class(SelectDirExample_Props) del bpy.types.Scene.selected_folder if __name__ == "__main__": register() ``` To not cause an `EXCEPTION_ACCESS_VIOLATION` another variable is used to store the folder path (which could also be inside the `AddonPreferences`). `setter_getter` is used to store the values into the same `PropertyGroup` as the folder. Otherwise, these values could not be moved along with the new operator call. They would be their default values because somehow the `self` in the `set_folder` is not the same as the `self` in the `execute` or `invoke`. A new instance with the stored variables will then be launched immediately, and it looks like before (only a movement in location of the dialog). The `SelectDirExample.invoked` variable is need otherwise it would launch two dialogs if the folder parameter is used on calling the operator e.g., `bpy.ops.object.select_dir_example('INVOKE_DEFAULT', folder='<my_path>')`. This does not apply if the call is from `set_folder`. **EDIT: Solution 2** This is a solution that uses an custom filebrowser operator. ``` import bpy from bpy.types import Operator, PropertyGroup from bpy_extras.io_utils import ExportHelper #, ImportHelper import os class SelectDirExample(Operator): bl_idname = "object.select_dir_example" bl_label = "Select Dir Example" bl_options = {'REGISTER', 'UNDO'} input1: bpy.props.FloatProperty(name="Input 1", default=1.0, min=0.0, max=100.0) input2: bpy.props.FloatProperty(name="Input 2", default=1.0, min=0.0, max=100.0) folder: bpy.props.StringProperty(name="Choose Folder") def draw_folder_selection(self, layout, property): row = layout.row(align=True) row.prop(self, property) ops = row.operator('select.directory_call_operator', text="", icon='FILEBROWSER') ops.operator_call = 'object.select_dir_example' # StringProperties need extra "" and \\ need to be doubled with my_string.replace("\\","\\\\") # E.g. my_string : StringProperty # f'my_string="{self.my_string}"' ops.operator_properties = f'input1={self.input1}, input2={self.input2}' ops.operator_folder_property_name = "folder" ops.old_filepath = self.folder def draw(self, context): layout = self.layout layout.use_property_split = True layout.use_property_decorate = False # No animation. layout.prop(self, 'input1') layout.prop(self, 'input2') self.draw_folder_selection(layout, 'folder') def invoke(self, context, event): return_code = context.window_manager.invoke_props_dialog(self, width = 300) return return_code def execute(self, context): input1 = self.input1 input2 = self.input2 folder = self.folder # My processing goes here print(f"Folder location is: {folder}") # Finished processing. return {'FINISHED'} # Use 'ImportHelper' when something is imported from this directory class Select_OT_directory_call_operator(Operator, ExportHelper): bl_idname = "select.directory_call_operator" bl_label = "Select Directory" bl_description = " " bl_options = {'REGISTER', 'INTERNAL'} filename_ext = "" filter_glob: bpy.props.StringProperty( default="", options={'HIDDEN'}, maxlen=255, # Max internal buffer length, longer would be clamped. ) use_filter_folder = True filepath: bpy.props.StringProperty(name="Folder Path", maxlen=0, default=" ") operator_call : bpy.props.StringProperty(options={'HIDDEN'}, description="operator to call") operator_properties : bpy.props.StringProperty(options={'HIDDEN'}, description="operator properties diffrent from folder") operator_folder_property_name : bpy.props.StringProperty(options={'HIDDEN'}, description="folder property of the operator to apply the new path to") old_filepath : bpy.props.StringProperty(options={'HIDDEN'}, description="old filepath of the operator used for cancel") def call_operator(self, filepath: str): filepath = filepath.replace("\\","\\\\") # needed because a str is placed into a str exec(f'bpy.ops.{self.operator_call}("INVOKE_DEFAULT", {self.operator_properties}, {self.operator_folder_property_name}="{filepath}")') def execute(self, context): user_path = self.properties.filepath if (not os.path.isdir(user_path)): msg = f"Please select a directory not a file\n{user_path}" self.report({'ERROR'}, msg) self.cancel(context) return {'CANCELLED'} self.call_operator(user_path) return {'FINISHED'} def cancel(self, context): self.call_operator(self.old_filepath) def register(): bpy.utils.register_class(SelectDirExample) bpy.utils.register_class(Select_OT_directory_call_operator) def unregister(): bpy.utils.unregister_class(SelectDirExample) bpy.utils.unregister_class(Select_OT_directory_call_operator) if __name__ == "__main__": register() ``` With this solution there is no need define a setter and getter for the properties. Also the data of the properties do not need to be saved external.