The 1st thing that I see, is that some backslashes (\) in the paths are not escaped. It won't be a problem in this particular case, but it's better to always escape them.
I modified your code a bit.
code00.py
#!/usr/bin/env python
import ctypes as ct
import os
import sys
def main(*argv):
src = r"C:\Windows\System32\calc.exe"
dst = os.path.join(os.getcwd(), "calc.exe")
kernel32 = ct.windll.kernel32
copy_file_a = kernel32.CopyFileA
copy_file_w = kernel32.CopyFileW
reta = copy_file_a(src, dst, False)
retw = copy_file_w(src, dst, False)
print("{:s} returned: {:d}\n{:s} returned: {:d}\n".format(copy_file_a.__name__, reta, copy_file_w.__name__, retw))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
Output:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q048927571]> "e:\Work\Dev\VEnvs\py_pc064_02.07.18_test0\Scripts\python.exe" code00.py
Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)] 064bit on win32
CopyFileA returned: 1
CopyFileW returned: 0
Done.
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q048927571]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" code00.py
Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32
CopyFileA returned: 0
CopyFileW returned: 1
Done.
Notes:
According to [MS.Docs]: CopyFile function:
If the function succeeds, the return value is nonzero.
I've added CopyFileW in the mix
According to output, CopyFileA fails with Python 3 (I've figured out that this is your scenario), and CopyFileW fails with Python 2.
That happens because in Python 2, strings are 008bit (char * based), while in Python 3 they are Unicode (016bit (wchar_t * based) on Win).
Check [SO]: Passing utf-16 string to a Windows function (@CristiFati's answer) for more details
Since the ANSI (A) version of a function has some limitations compared to its Wide (W) version, it's recommended to use the latter one
We have a cause for the failure, but we're not quite there yet. Here's a more elaborate example.
code01.py:
#!/usr/bin/env python
import ctypes as ct
import os
import sys
def main(*argv):
src = r"C:\Windows\System32\calc.exe"
dst = os.path.join(os.getcwd(), "calc.exe")
kernel32 = ct.windll.kernel32
copy_file_a = kernel32.CopyFileA
copy_file_a.argtypes = (ct.c_char_p, ct.c_char_p, ct.c_int)
copy_file_a.restype = ct.c_int
copy_file_w = kernel32.CopyFileW
copy_file_w.argtypes = (ct.c_wchar_p, ct.c_wchar_p, ct.c_int)
copy_file_w.restype = ct.c_int
reta = copy_file_a(src.encode(), dst.encode(), False)
retw = copy_file_w(src, dst, False)
print("{:s} returned: {:d}\n{:s} returned: {:d}\n".format(copy_file_a.__name__, reta, copy_file_w.__name__, retw))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
Notes:
Output:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q048927571]> "e:\Work\Dev\VEnvs\py_pc064_02.07.18_test0\Scripts\python.exe" code01.py
Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)] 064bit on win32
CopyFileA returned: 1
CopyFileW returned: 1
Done.
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q048927571]> "e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts\python.exe" code01.py
Python 3.9.9 (tags/v3.9.9:ccb0e6a, Nov 15 2021, 18:08:50) [MSC v.1929 64 bit (AMD64)] 064bit on win32
CopyFileA returned: 1
CopyFileW returned: 1
Done.