0

Let's say a third-party module moduleXYZ.py (that I don't want to fork/modify) does:

import ctypes
from ctypes.util import find_library
find_library("gsdll64.dll")

In my code main.py I'm importing it with

import moduleXYZ

This DLL is in C:\Program Files\gs\gs9.56.1\bin which is not in my global system path.

Question: how to add this directory to the path (for the duration of the script run, not permanently for the system) from inside my script main.py such that find_library will succeed?

I tried:

import os
os.environ['PATH'] += ';C:\Program Files\gs\gs9.56.1\bin'
sys.path += ['C:\Program Files\gs\gs9.56.1\bin']
import mymoduleXYZ

but it still fails.

Note:

  • my script is always run with python main.py, and I don't want to have to add this directory to path from a batch file or from terminal or from command-line: all this should be done inside the main.py script itself.

  • I've always read Permanently adding a file path to sys.path in Python, How to add to the PYTHONPATH in Windows, so it finds my modules/packages?, and similar questions but this doesn't apply here

  • I don't want to add this directory permanently to the system PATH

  • a general solution to add a directory to path for the currently ran script would be interesting, if possible not specific to ctypes/DLL but to everything using path in general


Edit: os.add_dll_directory looked promising but it doesn't work here:

import os
from ctypes.util import find_library 
os.add_dll_directory(r'C:\Program Files\gs\gs9.56.1\bin')
find_library(r'gsdll64.dll')  # None.........

find_library(r'C:\Program Files\gs\gs9.56.1\bin')  # working
Basj
  • 41,386
  • 99
  • 383
  • 673
  • Have you tried `import sys` `sys.path.append("the path to the folder")`? – user3808430 Aug 21 '22 at 09:17
  • @user3808430 No it doesn't work (I just tried), also this is similar to `sys.path += ['/path/to']`. – Basj Aug 21 '22 at 09:20
  • `+=` creates a new list in memory, whereas append updates the old one, so I figured it was possible that it could have a different effect. But yeah I'm a bit stumped :/ – user3808430 Aug 21 '22 at 09:26
  • I think is.add_dll_directory should do the trick for more or less current python versions, see https://docs.python.org/3/library/os.html#os.add_dll_directory – ead Aug 21 '22 at 09:38
  • Thanks @ead. This will probably work for ctypes' `find_library`, but more generally, how to add something to the path for the currently-ran script? (without export to environment variable outside the python script) – Basj Aug 21 '22 at 09:40
  • @ead Strangely it doesn't work: `import os; os.add_dll_directory(r'C:\Program Files\gs\gs9.56.1\bin'); from ctypes.util import find_library; print(find_library('gsdll64.dll'))` but this DLL file is present in this folder. (See edit in my answer) – Basj Aug 21 '22 at 09:58
  • [\[SO\]: Dynamic c++ Library in Python - can't find dylib file (@CristiFati's answer)](https://stackoverflow.com/a/73077158/4788546), [\[SO\]: PyWin32 and Python 3.8.0 (@CristiFati's answer)](https://stackoverflow.com/a/58632354/4788546). *sys.path* has nothing to do here. – CristiFati Aug 21 '22 at 15:25

2 Answers2

1

Oops, this was a noob mistake: I forgot to escape the string which contains \b with r'...'. This works:

main.py

import os, sys
os.environ['PATH'] += r';C:\Program Files\gs\gs9.56.1\bin'
import moduleXYZ

moduleXYZ.py

from ctypes.util import find_library 
print(find_library(r'gsdll64.dll'))

But a more general answer that would change the system path for the currently being-ran script, from the script itself would still be interesting.

Basj
  • 41,386
  • 99
  • 383
  • 673
0

I have same code in my project, worked in 3.8 and 3.9 , not work in 3.10.0 and 3.10.7

import os
from ctypes.util import find_library 
os.add_dll_directory(r'C:\Program Files\gs\gs9.56.1\bin')
find_library(r'gsdll64.dll')
Civil
  • 1
  • 1