JacquesLucke / blender_vscode

Visual Studio Code extension for Blender development.
MIT License
557 stars 76 forks source link

[WinError 183] Cannot create a file when that file already exists #43

Open Teriander opened 5 years ago

Teriander commented 5 years ago

I'm having the same issue that was previously discussed, but the solution was very vague or non-existent. I have no idea how to solve this. I receive the following error when trying to run "Blender: Start", which results in an instant crash of Blender. Blender loads for 2 seconds, then crashes.

Executing task in folder Blender: d:\Program Files\Blender Foundation\Blender\blender.exe --python C:\Users\efelder\.vscode\extensions\jacqueslucke.blender-development-0.0.12\pythonFiles\launch.py 

Read prefs: C:\Users\efelder\AppData\Roaming\Blender Foundation\Blender\2.80\config\userpref.blend
found bundled python: d:\Program Files\Blender Foundation\Blender\2.80\python
archipack: ready
Traceback (most recent call last):
  File "d:\Program Files\Blender Foundation\Blender\2.80\scripts\modules\addon_utils.py", line 351, in enable
    mod = __import__(module_name)
ModuleNotFoundError: No module named 'Blender'
[{'load_dir': 'd:\\Program Files\\PythonProjects\\PythonProjects\\Blender', 'module_name': 'Blender'}, {'load_dir': 'd:\\Program Files\\PythonProjects\\PythonProjects\\TestAddon', 'module_name': 'TestAddon'}]
Traceback (most recent call last):
  File "C:\Users\efelder\.vscode\extensions\jacqueslucke.blender-development-0.0.12\pythonFiles\launch.py", line 18, in <module>
    allow_modify_external_python=os.environ['ALLOW_MODIFY_EXTERNAL_PYTHON'] == "yes",
  File "C:\Users\efelder\.vscode\extensions\jacqueslucke.blender-development-0.0.12\pythonFiles\include\blender_vscode\__init__.py", line 14, in startup
    path_mappings = load_addons.setup_addon_links(addons_to_load)
  File "C:\Users\efelder\.vscode\extensions\jacqueslucke.blender-development-0.0.12\pythonFiles\include\blender_vscode\load_addons.py", line 20, in setup_addon_links
    create_link_in_user_addon_directory(source_path, load_path)
  File "C:\Users\efelder\.vscode\extensions\jacqueslucke.blender-development-0.0.12\pythonFiles\include\blender_vscode\load_addons.py", line 43, in create_link_in_user_addon_directory
    _winapi.CreateJunction(str(directory), str(link_path))
FileExistsError: [WinError 183] Cannot create a file when that file already exists
Saved session recovery to 'C:\Users\efelder\AppData\Local\Temp\quit.blend' 

If the solution is to delete a file that already exist, well that's great. Which file and where??

Teriander commented 5 years ago

Ok, so I figured it out.

...\AppData\Roaming\Blender Foundation\Blender\2.80\scripts\addons

Remove the folder with your project name that already exist here (if its there). This should be considered a bug, because it breaks the launch of Blender from VSCode, and that shouldn't happen.

eldeesmith commented 5 years ago

What would your preferred behavior be? The exception could be caught and handled, but your best case scenario is that blender will continue loading and an older version of your addon will get loaded (likely unnoticed).

possible solutions:

By the way, the load_addons module is pretty straightforward- if you have ideas on how to solve the problem I'm sure Jackques would welcome the pull request.

Teriander commented 5 years ago

Eldeesmith,

A simple solution would be a print in the error of the location of the problem folder. Not sure how difficult that would be. But considering I'm not the first person to have this problem since an identical post was created, it would make sense to provide more detail of the problem.

Currently we're just notified Cannot create a file when that file already exists , without any reference to what file and where. But I agree, having Python delete the folder automatically probably isn't ideal. But at least it could indicate what file and folder is the problem.

eldeesmith commented 5 years ago

Sure, not hard to do- though I think it will actually cause more problems than it solves because the importance of the error gets buried and blender is allowed to continue loading. Try it for yourself:

replace function with the same name in load_addons.py, located in %userprofile%.vscode\extensions\jacqueslucke.blender-development-0.0.12\pythonFiles\include\blender_vscode\

def create_link_in_user_addon_directory(directory, link_path):
     if os.path.exists(link_path):
        try:
            os.remove(link_path)
        except PermissionError as ex:
            print (f"ERROR: Could not remove path {link_path} due to insufficient priveledges.\n{ex}")

    if sys.platform == "win32":
        import _winapi
        try:
            _winapi.CreateJunction(str(directory), str(link_path))
        except FileExistsError as ex:
            print (f"ERROR: Could not create a symbolic link to {link_path} because {directory} already exists! Delete it and try again!\n{ex}")
    else:
        os.symlink(str(directory), str(link_path), target_is_directory=True)
Teriander commented 5 years ago

This issue triggered when I had relocated my workspace folder. So if the folder name already exist previously, it will not execute blender and give the warning.

Perhaps the most simplest solution could be a note on the extensions details page that simply states "If you receive a [WinError 183] error, delete the folder with your workspace name at \AppData\Roaming\Blender Foundation\Blender\2.80\scripts\addons"

If the error is not avoidable through back-end programming.

Mateusz-Grzelinski commented 1 month ago

I would like to revive the topic, I did some tests

Test 1

  1. Use extension to run addon with blender 2.83. Junction (symlink) is created in 2.83/scripts/addons/
  2. Run bledner 2.90 outside of VS code. Load previos version settings.
  3. Use extension to run addon with blender 2.90. PermissionError:
Traceback (most recent call last):
  File "e:\BlenderProjects\blender_vscode\pythonFiles\launch.py", line 29, in <module>
    allow_modify_external_python=os.environ["ALLOW_MODIFY_EXTERNAL_PYTHON"] == "yes",
  File "e:\BlenderProjects\blender_vscode\pythonFiles\include\blender_vscode\__init__.py", line 26, in startup
    path_mappings = load_addons.setup_addon_links(addons_to_load)
  File "e:\BlenderProjects\blender_vscode\pythonFiles\include\blender_vscode\load_addons.py", line 30, in setup_addon_links
    make_temporary_link(addon_info.load_dir, load_path)
  File "e:\BlenderProjects\blender_vscode\pythonFiles\include\blender_vscode\load_addons.py", line 81, in make_temporary_link
    os.remove(link_path)
PermissionError: [WinError 5] Access is denied: 'C:\\Users\\grzel\\AppData\\Roaming\\Blender Foundation\\Blender\\2.90\\scripts\\addons\\ImagePaste'

Vs code can not os.remove the path. Blender can not uninstall addon. No data loss occured.

test 2

  1. Use extension to run addon with blender 2.83. Junction (symlink) is created in 2.83/scripts/addons/
  2. Move/remove your addon. Now junction/symlink is broken.
  3. Use extension to run addon with blender 2.83. Vs code can start but with error- most likely blender internal error
Traceback (most recent call last):
  File "E:\BlenderProjects\bledner.exe\blender-2.80-windows64\blender-2.80-windows64\2.80\scripts\modules\addon_utils.py", line 352, in enable    
    mod.__time__ = os.path.getmtime(mod.__file__)
  File "E:\BlenderProjects\bledner.exe\blender-2.80-windows64\blender-2.80-windows64\2.80\python\lib\genericpath.py", line 55, in getmtime        
    return os.stat(filename).st_mtime
TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType
Traceback (most recent call last):
  File "E:\BlenderProjects\bledner.exe\blender-2.80-windows64\blender-2.80-windows64\2.80\scripts\modules\addon_utils.py", line 351, in enable    
    mod = __import__(module_name)
ModuleNotFoundError: No module named 'leagacy_and_extension23'

test 3

  1. Use extension to run addon with blender 2.83. Junction (symlink) is created in 2.83/scripts/addons/
  2. Move your addon to different directory. Leave addon folder with the same name. Now junction/symlink is broken.
  3. Use extension to run addon with blender 2.83.

Works fine.

test 4

  1. Use extension to run addon with blender 2.83. Junction (symlink) is created in 2.83/scripts/addons/
  2. Use extension to run addon with blender 2.90 (fresh run). Error:
ModuleNotFoundError: No module named 'leagacy_and_extension'

Sending: {'type': 'enableFailure', 'addonPath': 'e:\\BlenderProjects\\test\\leagacy_and_extension'}
  1. Load old settings from splash screen. Blender and vs code explodes:
Traceback (most recent call last):
  File "E:\BlenderProjects\bledner.exe\blender-2.90.1-windows64\blender-2.90.1-windows64\2.90\scripts\startup\bl_operators\userpref.py", line 168, in execute
    preferences_copytree(self._old_path(), self._new_path())
  File "E:\BlenderProjects\bledner.exe\blender-2.90.1-windows64\blender-2.90.1-windows64\2.90\scripts\startup\bl_operators\userpref.py", line 91, in preferences_copytree
    return _preferences_copytree(entries=entries, src=src, dst=dst)
  File "E:\BlenderProjects\bledner.exe\blender-2.90.1-windows64\blender-2.90.1-windows64\2.90\scripts\startup\bl_operators\userpref.py", line 85, in _preferences_copytree
    raise Error(errors)
shutil.Error: ['<', 'D', 'i', 'r', 'E', 'n', 't', 'r', 'y',  ... # way too long output
C:\Users\grzel\AppData\Roaming\Blender Foundation\Blender\2.90\scripts\addons\leagacy_and_extension\__init__.py are the same file<DirEntry __init__.cpython-37.pyc> and C:\Users\grzel\AppData\Roaming\Blender Foundation\Blender\2.90\scripts\addons\leagacy_and_extension\__pycache__\__init__.cpython-37.pyc are the same file'

Summary

Because of those ugly corner case i am prototyping a change the default behaviour of this VS code extension:

  1. Disable "Load Previous settings" blender feature during VS code session.
  2. Make Links to addons temporary - a. option 1: link to addon dir is made only for VS code session - proposed in #55 but not merged. This breaks workflow, so it might need to be new setting or command "Blender: Install addons" b. option 2: modify VS code startup to use separate addon BLENDER_USER_SCRIPTS and dir BLENDER_SYSTEM_EXTENSIONS

So far I am playing with the idea on my repo https://github.com/Mateusz-Grzelinski/blender_vscode/pull/2 I will make PR when some of my other changes get merged.

Please note: using shutil.rmtree results in data loss. I can not provide reproduce steps, but I removed the contents of my test addon.