Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

file permissions in Windows 10 with Python

Question: How can I change file permissions on a Windows 10 PC with a Python script?

I have written a Python script that takes folders, which are created by proprietary software, and moves them to a network drive with shutil.move().

It seems that the proprietary software creates folders that are read-only by default. I need to change the file permissions for these folders in order for shutil.move() to delete the folders after they are copied to the network drive.

I have searched on SO to discover that os.chmod(path, 0o777) only works to grant access on Unix systems. On Windows, it modifies the read-only attribute of a file or folder. This question seems to yield a solution, which I tried as follows:

import win32security
import ntsecuritycon as con

account = r"admin"

userx, domain, type = win32security.LookupAccountName ("", account)
sd = win32security.GetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION)
dacl = sd.GetSecurityDescriptorDacl()   # instead of dacl = win32security.ACL()
dacl.AddAccessAllowedAce(win32security.ACL_REVISION, con.FILE_GENERIC_READ | con.FILE_GENERIC_WRITE, userx)
sd.SetSecurityDescriptorDacl(1, dacl, 0)   # may not be necessary
win32security.SetFileSecurity(path, win32security.DACL_SECURITY_INFORMATION, sd)

But it does not seem to work. Also, I don't understand what I am doing with the modules win32security and ntsecuritycon. Maybe someone can give an easy explanation.

edit: ok so i looked at stuff. This is the exception that gets raised:

Traceback (most recent call last):
File "copyscript.py", line 108, in <module>
copyscript()# the loop needs to be called as a function to delete all assigned variables after each loop
File "copyscript.py", line 93, in copyscript
shutil.move(run, str(target_dir2))#move files renamed to user folder
File "C:\Users\admin\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 550, in move
rmtree(src)
File "C:\Users\admin\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 488, in rmtree
return _rmtree_unsafe(path, onerror)
File "C:\Users\admin\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 378, in _rmtree_unsafe
_rmtree_unsafe(fullname, onerror)
File "C:\Users\admin\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 383, in _rmtree_unsafe
onerror(os.unlink, fullname, sys.exc_info())
File "C:\Users\admin\AppData\Local\Programs\Python\Python35\lib\shutil.py", line 381, in _rmtree_unsafe
os.unlink(fullname)
PermissionError: [WinError 5] Access is denied: 'THG126.D\\AcqData\\sample_info.xml'
  • the full path of this file is D:\MSD_Data\THG126.D\AcqData\sample_info.xml.
  • the user account is named "admin" and it belongs to the "Administrators" group.
  • "admin" is the owner and has "full control" according to the "advanced security settings" for MSD_Data, THG126.D, sample_info.xml and the python script.
  • i have also tried running the script via CLI using "run as administrator". The same error occurs.

i looked at all files in the folders and found that only sample_info.xml has RA attributes, whereas all other have only A, so i added

path2 = r"D:\\MSD_data\\"+run+r"\\AcqData\\sample_info.xml"
subprocess.check_call(["attrib", "-r", path2, "/S", "/D"])

to the script and it seems to work now. I need to wait a little for new folders to be generated by the other software to see if the script is working correctly now.

like image 801
Chris Avatar asked Aug 31 '25 05:08

Chris


1 Answers

The problem seems to have been that a file had the attribute "RA", which means "read-only" and "archived". Even though the used user account wqas the owner of all files and folders, shutil.move() fails when it tries to delete the file after copying to the target location.

A workaround to this problem is to use

subprocess.check_call(["attrib", "-r", path])

to remove the read-only file attribute. This resolved my issue. If you still have trouble with shutil.move() you could also try this solution.

like image 66
Chris Avatar answered Sep 02 '25 19:09

Chris