Repository: pyinstaller/pyinstaller

Issue:
shapely hook doesn't work on windows
Using current develop, the shapely hook fails when it runs `binaries += [(os.path.join(lib_dir, f), '') for f in os.listdir(lib_dir)]`. `lib_dir` here equals `Lib/site-packages/shapely/DLLs`. The actual directory on my conda python 3.6 installation is `Library/bin/`. My old spec file uses the following ugly code to copy these libraries over:

```
    lib_dir = sys.executable.replace("python.exe", os.path.join("Library", "bin"))
    binaries += [(os.path.join(lib_dir, 'geos_c.dll'), '')]
    binaries += [(os.path.join(lib_dir, 'geos.dll'), '')]
    binaries += [(os.path.join(lib_dir, 'mkl_*.dll'), '')]
```

Is there a better way to get a hold of this Library directory with some pyinstaller utility function? Does anyone know if other python environments (non-conda) have the directory used in the hook or @durden did you just guess on the Windows path?

Side issue: Shapely 1.6+ doesn't seem to work on at least windows (haven't updated on other platforms). It fails to find the geos libraries mentioned above unless you execute the pyinstaller-made (inno setup packaged) executable from the install directory (`C:\Program Files (x86)\myprgm\bin\`). For now I'm just downgrading to 1.5.17.
shapely hook doesn't work on windows
Using current develop, the shapely hook fails when it runs `binaries += [(os.path.join(lib_dir, f), '') for f in os.listdir(lib_dir)]`. `lib_dir` here equals `Lib/site-packages/shapely/DLLs`. The actual directory on my conda python 3.6 installation is `Library/bin/`. My old spec file uses the following ugly code to copy these libraries over:

```
    lib_dir = sys.executable.replace("python.exe", os.path.join("Library", "bin"))
    binaries += [(os.path.join(lib_dir, 'geos_c.dll'), '')]
    binaries += [(os.path.join(lib_dir, 'geos.dll'), '')]
    binaries += [(os.path.join(lib_dir, 'mkl_*.dll'), '')]
```

Is there a better way to get a hold of this Library directory with some pyinstaller utility function? Does anyone know if other python environments (non-conda) have the directory used in the hook or @durden did you just guess on the Windows path?

Side issue: Shapely 1.6+ doesn't seem to work on at least windows (haven't updated on other platforms). It fails to find the geos libraries mentioned above unless you execute the pyinstaller-made (inno setup packaged) executable from the install directory (`C:\Program Files (x86)\myprgm\bin\`). For now I'm just downgrading to 1.5.17.


Discussion:
You would enhance the hook to something like this:
```python
if is_win:
   …
   # most distributions use 'DLL', some use 'bin'
   for dir in ('DLL', 'bin):
      lib_dir = os.path.join(pkg_dir, dir)
      if not os.path.is_dir(lib_dir):
        continue
     binaries += [ … ]
```
I'd appreciate a pull-request :-)
@htgoebel I'm fine making a PR for this, but I was hoping to avoid unused directories. That's why I'm hoping @durden sees this and can let me know.
Maybe there was a change in Shapely itself?  Are you using Anaconda or just a vanilla Python setup on Windows?

The hook file definitely worked for me on 64-bit Windows.  That's the setup I found the issue on first and wrote the hook for.  [Here's the PR](https://github.com/pyinstaller/pyinstaller/pull/2569) where I documented what I did, the setup, and submitted a bug to Shapely too.
Also, I was using Python 2.7, not 3.6.  I've never tested Shapely with Python 3 so maybe it installs the dll, etc. in a slightly different way?
There's also [this commit](https://github.com/Toblerity/Shapely/commit/e0e67f058e131af1a0241eb31da13b4ecc73f8ae) on Shapely from the past week or so.  That change looks like it does some dll related stuff.  Maybe try using a different version of Shapely?  Not sure, but that commit looks a bit suspicious so would be worth trying a few commits before that or the previous release, etc.
I'm building on a Windows 7 64-bit virtual machine using Anaconda Python 3.6 with packages from conda-forge. I'll try to find some time to look at this today and see what results I get from shapely's master branch.
Sounds good, could be a number of things. I was using Python 2.7, no packages from condo-forge, and a proper release from Shapely that's now a few months old. So, could be any of those I suppose.  Thanks for looking into it!
@durden Just to be clear, you were using a python 2.7 conda environment (not a vanilla python)?
And where were you installing shapely from?
The directories I'm seeing are definitely from conda-forge's build process:
https://github.com/conda-forge/shapely-feedstock/blob/master/recipe/bld.bat
http://conda-test.pydata.org/docs/build.html#environment-variables-set-during-the-build-process
@durden If you have your windows environment available, would you mind testing the newest version of shapely that you have access to in whatever way you installed it previously?
https://github.com/Toblerity/Shapely/pull/523
my $0.02.
if you install shapely (64 bit) from these [precompiled packages](https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely) there is no geos.dll, only a geos_c.dll.
because of this, pyinstaller hook fails because it can't find geos.dll

```
    4246 INFO: Loading module hook "hook-shapely.py"...
    Unable to find "c:\python27amd64\lib\site-packages\shapely\DLLs\geos.dll" when adding binary and data files.
```

@joycepg Is that an actual failure or just a warning? Is the `geos.dll` named something different?
it's a failure. 
the only file in c:\python27amd64\lib\site-packages\shapely\DLLs is "geos_c.dll".
I worked around it (hack, hack) by copying geos_c.dll to geos.dll

https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/hook-shapely.py#L28 seems to look for both geos_c.dll and geos.dll.
perhaps the file is named differently depending on the distribution, but it's either or, not both?
@joycepg There was a lot of time in between me originally making my spec file (mentioned in the original post) and the PR I made to fix this issue (https://github.com/pyinstaller/pyinstaller/pull/2838). So it is possible things changed or became optional or worked differently in the hook versus my custom spec file. The fix should be easy enough if we just change the hook to check if the library exists before trying to add it.

However, looking at my PR again, it should fail even for the conda packages unless both of those files exists which by your description (memory is failing me) there is only ever one of the library files for every install. Or is that wrong?
i'm not really sure about conda, because I've never used it, but another package that includes GEOS is [OSGeo4W](https://trac.osgeo.org/osgeo4w/). If you click down through the PackageListing to the [pkg-geos](https://trac.osgeo.org/osgeo4w/wiki/pkg-geos) package, it says there

> Provides DLL (bin/geos_c.dll)


Also, the [Shapely installation instructions](http://toblerity.org/shapely/project.html#installation) has this:

Warning
Windows users: do not under any circumstances use pip (or easy_install) to uninstall Shapely versions < 1.2.17. Due to the way Shapely used to install its GEOS DLL and a distribute or setuptools bug, your Python installation may be broken by an uninstall command. Shapely 1.2.17 will uninstall safely.

So it's possible that it has changed name from geos.dll to geos_c.dll. I think it would be safe just to check for either/both and copy what you find.

The only thing with that warning for shapely is that 1.2.17 is an old version. My spec was for at least 1.5 so I don't see why I would have handled both geos_c.dll and geos.dll in my original spec. It's also possible geos.dll is used by another library like gdal and geos_c.dll is used by C libraries like shapely. Now that I think about it that would be my main guess is that one has C++ APIs and one has C APIs, but it is just a guess and I don't have time this week to look in to it. Sorry.
FYI for OSX with a conda environment with python 3.6:

```bash
$ ll libgeos*
-rwxrwxr-x  6 davidh  staff  3415148 Nov  8  2017 libgeos-3.6.2.dylib
-rw-rw-r--  6 davidh  staff  8928696 Nov  8  2017 libgeos.a
lrwxr-xr-x  1 davidh  staff       19 Jan 27 08:46 libgeos.dylib -> libgeos-3.6.2.dylib
-rwxrwxr-x  1 davidh  staff      950 Jan 27 08:46 libgeos.la
-rwxrwxr-x  6 davidh  staff   413752 Nov  8  2017 libgeos_c.1.dylib
-rw-rw-r--  6 davidh  staff   511200 Nov  8  2017 libgeos_c.a
lrwxr-xr-x  1 davidh  staff       17 Jan 27 08:46 libgeos_c.dylib -> libgeos_c.1.dylib
-rwxrwxr-x  1 davidh  staff     1015 Jan 27 08:46 libgeos_c.la
```
> my main guess is that one has C++ APIs and one has C APIs

You are right. 

TLDR:

geos.lib = static lib of the C++ source

geos.dll = shared lib of the C++ source
geos_i.lib = imports lib for geos.dll

geos_c.dll = shared lib of the C++ source with a C wrapper. Linked with geos.lib, so no dependencies
geos_c_i.lib = imports lib for geos_c.dll


detail:
The [makefile](https://git.osgeo.org/gitea/geos/geos/src/branch/master/src/Makefile.vc#L351) for geos builds both a geos.dll and a geos_c.dll. The link command for geos_c.dll links the "capi/" source files and the rest of the source via the static lib geos.lib. So geos_c.dll does not depend on geos.dll.  

The actual symbols for the names are defined in an included [nmake.opt](https://git.osgeo.org/gitea/geos/geos/src/branch/master/nmake.opt#L249) as 
DLLNAME = geos$(BUILD_PREFIX).dll
CDLLNAME = geos_c$(BUILD_PREFIX).dll

BUILD_PREFIX is just "_d" for debug builds, or "" for release.




btw, looking at the shapely [source](https://github.com/Toblerity/Shapely/blob/master/shapely/geos.py#L124), it only loads geos_c.dll on windows
So really it sounds like we need a libgeos hook and the hook provided for shapely is a special case (if it chooses to install its own version). However, maybe the quickest solution is to just check if a certain library file exists before trying to import it.
How about this？
https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/hook-shapely.py#L28
```python
pattern = os.path.join(lib_dir, 'geos*.dll')
binaries += [(os.path.join(lib_dir, f), '.') for f in glob.glob(pattern)]
```
It works for me, the environment is python 3.5 x32 on windows. I don't use conda, so I don't know if it works fine with conda. 
I can confirm that with vanilla Python 2.7, PyInstaller 3.3 properly imported shapely on windows, and since PyInstaller 3.3.1 and onwards it has been broken. I am using shapely 1.6.2 and 1.6.4 from [Christoph Gohlke's Unofficial Windows Binaries](https://www.lfd.uci.edu/~gohlke/pythonlibs/).

I think the desired behavior for vanilla python is to import all of the files in the `site-packages/shapely/DLLs` folder, as this folder only contains DLLs used by shapely. With conda, the DLLs are in a global `Library/bin/` folder, which potentially contains other unwanted DLLs, so the ones to be imported must be specified by name.
@jonnyhsu What error messages are you getting? What DLLs are missing? In my PR that was supposed to fix this issue I specifically check for `geos_c.dll` and `geos.dll` (https://github.com/pyinstaller/pyinstaller/pull/2838/files#diff-46543a7dc222543b79209d4655876e9cR28). Are the ones provided by Gohke's binaries named differently?
Here's the error message:
```
12560 INFO: Loading module hook "hook-shapely.py"...
Unable to find "xxxxxxxxxx\.venv\lib\site-packages\shapely\DLLs\geos.dll" when adding binary and data files.
```
The problem is that it's trying to include files that don't exist. I've addressed it in this pull request: https://github.com/pyinstaller/pyinstaller/pull/3842

Let me know what you think of this solution.
Initial workaround does not work (at least in my case with virtualenvs), is there a more general-purpose workaround ?
This is still an issue with me, at least some version of it:

```
OSError: [WinError 126] The specified module could not be found
Traceback:
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\streamlit\ScriptRunner.py", line 324, in _run_script
    exec(code, module.__dict__)
  File "C:\Users\cfonnesbeck\repos\Analytics\pitcher_heat_maps\app.py", line 13, in <module>
    from plotting import plot_heatmap, plot_heatmaps, heatmap_cmap
  File "C:\Users\cfonnesbeck\repos\Analytics\pitcher_heat_maps\plotting.py", line 9, in <module>
    from shapely.geometry import Point
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\geometry\__init__.py", line 4, in <module>
    from .base import CAP_STYLE, JOIN_STYLE
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\geometry\base.py", line 18, in <module>
    from shapely.coords import CoordinateSequence
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\coords.py", line 8, in <module>
    from shapely.geos import lgeos
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\geos.py", line 145, in <module>
    _lgeos = CDLL(os.path.join(sys.prefix, 'Library', 'bin', 'geos_c.dll'))
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\ctypes\__init__.py", line 356, in __init__
    self._handle = _dlopen(self._name, mode)
```
Is there any way to get Shapely working on windows?
fonnesbeck,

You need to install shapely through conda forge if using anacaonda
Like so:
conda config --add channels conda-forge
conda install shapely

I had the same error as you, and this worked for me.
You would enhance the hook to something like this:
```python
if is_win:
   …
   # most distributions use 'DLL', some use 'bin'
   for dir in ('DLL', 'bin):
      lib_dir = os.path.join(pkg_dir, dir)
      if not os.path.is_dir(lib_dir):
        continue
     binaries += [ … ]
```
I'd appreciate a pull-request :-)
@htgoebel I'm fine making a PR for this, but I was hoping to avoid unused directories. That's why I'm hoping @durden sees this and can let me know.
Maybe there was a change in Shapely itself?  Are you using Anaconda or just a vanilla Python setup on Windows?

The hook file definitely worked for me on 64-bit Windows.  That's the setup I found the issue on first and wrote the hook for.  [Here's the PR](https://github.com/pyinstaller/pyinstaller/pull/2569) where I documented what I did, the setup, and submitted a bug to Shapely too.
Also, I was using Python 2.7, not 3.6.  I've never tested Shapely with Python 3 so maybe it installs the dll, etc. in a slightly different way?
There's also [this commit](https://github.com/Toblerity/Shapely/commit/e0e67f058e131af1a0241eb31da13b4ecc73f8ae) on Shapely from the past week or so.  That change looks like it does some dll related stuff.  Maybe try using a different version of Shapely?  Not sure, but that commit looks a bit suspicious so would be worth trying a few commits before that or the previous release, etc.
I'm building on a Windows 7 64-bit virtual machine using Anaconda Python 3.6 with packages from conda-forge. I'll try to find some time to look at this today and see what results I get from shapely's master branch.
Sounds good, could be a number of things. I was using Python 2.7, no packages from condo-forge, and a proper release from Shapely that's now a few months old. So, could be any of those I suppose.  Thanks for looking into it!
@durden Just to be clear, you were using a python 2.7 conda environment (not a vanilla python)?
And where were you installing shapely from?
The directories I'm seeing are definitely from conda-forge's build process:
https://github.com/conda-forge/shapely-feedstock/blob/master/recipe/bld.bat
http://conda-test.pydata.org/docs/build.html#environment-variables-set-during-the-build-process
@durden If you have your windows environment available, would you mind testing the newest version of shapely that you have access to in whatever way you installed it previously?
https://github.com/Toblerity/Shapely/pull/523
my $0.02.
if you install shapely (64 bit) from these [precompiled packages](https://www.lfd.uci.edu/~gohlke/pythonlibs/#shapely) there is no geos.dll, only a geos_c.dll.
because of this, pyinstaller hook fails because it can't find geos.dll

```
    4246 INFO: Loading module hook "hook-shapely.py"...
    Unable to find "c:\python27amd64\lib\site-packages\shapely\DLLs\geos.dll" when adding binary and data files.
```

@joycepg Is that an actual failure or just a warning? Is the `geos.dll` named something different?
it's a failure. 
the only file in c:\python27amd64\lib\site-packages\shapely\DLLs is "geos_c.dll".
I worked around it (hack, hack) by copying geos_c.dll to geos.dll

https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/hook-shapely.py#L28 seems to look for both geos_c.dll and geos.dll.
perhaps the file is named differently depending on the distribution, but it's either or, not both?
@joycepg There was a lot of time in between me originally making my spec file (mentioned in the original post) and the PR I made to fix this issue (https://github.com/pyinstaller/pyinstaller/pull/2838). So it is possible things changed or became optional or worked differently in the hook versus my custom spec file. The fix should be easy enough if we just change the hook to check if the library exists before trying to add it.

However, looking at my PR again, it should fail even for the conda packages unless both of those files exists which by your description (memory is failing me) there is only ever one of the library files for every install. Or is that wrong?
i'm not really sure about conda, because I've never used it, but another package that includes GEOS is [OSGeo4W](https://trac.osgeo.org/osgeo4w/). If you click down through the PackageListing to the [pkg-geos](https://trac.osgeo.org/osgeo4w/wiki/pkg-geos) package, it says there

> Provides DLL (bin/geos_c.dll)


Also, the [Shapely installation instructions](http://toblerity.org/shapely/project.html#installation) has this:

Warning
Windows users: do not under any circumstances use pip (or easy_install) to uninstall Shapely versions < 1.2.17. Due to the way Shapely used to install its GEOS DLL and a distribute or setuptools bug, your Python installation may be broken by an uninstall command. Shapely 1.2.17 will uninstall safely.

So it's possible that it has changed name from geos.dll to geos_c.dll. I think it would be safe just to check for either/both and copy what you find.

The only thing with that warning for shapely is that 1.2.17 is an old version. My spec was for at least 1.5 so I don't see why I would have handled both geos_c.dll and geos.dll in my original spec. It's also possible geos.dll is used by another library like gdal and geos_c.dll is used by C libraries like shapely. Now that I think about it that would be my main guess is that one has C++ APIs and one has C APIs, but it is just a guess and I don't have time this week to look in to it. Sorry.
FYI for OSX with a conda environment with python 3.6:

```bash
$ ll libgeos*
-rwxrwxr-x  6 davidh  staff  3415148 Nov  8  2017 libgeos-3.6.2.dylib
-rw-rw-r--  6 davidh  staff  8928696 Nov  8  2017 libgeos.a
lrwxr-xr-x  1 davidh  staff       19 Jan 27 08:46 libgeos.dylib -> libgeos-3.6.2.dylib
-rwxrwxr-x  1 davidh  staff      950 Jan 27 08:46 libgeos.la
-rwxrwxr-x  6 davidh  staff   413752 Nov  8  2017 libgeos_c.1.dylib
-rw-rw-r--  6 davidh  staff   511200 Nov  8  2017 libgeos_c.a
lrwxr-xr-x  1 davidh  staff       17 Jan 27 08:46 libgeos_c.dylib -> libgeos_c.1.dylib
-rwxrwxr-x  1 davidh  staff     1015 Jan 27 08:46 libgeos_c.la
```
> my main guess is that one has C++ APIs and one has C APIs

You are right. 

TLDR:

geos.lib = static lib of the C++ source

geos.dll = shared lib of the C++ source
geos_i.lib = imports lib for geos.dll

geos_c.dll = shared lib of the C++ source with a C wrapper. Linked with geos.lib, so no dependencies
geos_c_i.lib = imports lib for geos_c.dll


detail:
The [makefile](https://git.osgeo.org/gitea/geos/geos/src/branch/master/src/Makefile.vc#L351) for geos builds both a geos.dll and a geos_c.dll. The link command for geos_c.dll links the "capi/" source files and the rest of the source via the static lib geos.lib. So geos_c.dll does not depend on geos.dll.  

The actual symbols for the names are defined in an included [nmake.opt](https://git.osgeo.org/gitea/geos/geos/src/branch/master/nmake.opt#L249) as 
DLLNAME = geos$(BUILD_PREFIX).dll
CDLLNAME = geos_c$(BUILD_PREFIX).dll

BUILD_PREFIX is just "_d" for debug builds, or "" for release.




btw, looking at the shapely [source](https://github.com/Toblerity/Shapely/blob/master/shapely/geos.py#L124), it only loads geos_c.dll on windows
So really it sounds like we need a libgeos hook and the hook provided for shapely is a special case (if it chooses to install its own version). However, maybe the quickest solution is to just check if a certain library file exists before trying to import it.
How about this？
https://github.com/pyinstaller/pyinstaller/blob/develop/PyInstaller/hooks/hook-shapely.py#L28
```python
pattern = os.path.join(lib_dir, 'geos*.dll')
binaries += [(os.path.join(lib_dir, f), '.') for f in glob.glob(pattern)]
```
It works for me, the environment is python 3.5 x32 on windows. I don't use conda, so I don't know if it works fine with conda. 
I can confirm that with vanilla Python 2.7, PyInstaller 3.3 properly imported shapely on windows, and since PyInstaller 3.3.1 and onwards it has been broken. I am using shapely 1.6.2 and 1.6.4 from [Christoph Gohlke's Unofficial Windows Binaries](https://www.lfd.uci.edu/~gohlke/pythonlibs/).

I think the desired behavior for vanilla python is to import all of the files in the `site-packages/shapely/DLLs` folder, as this folder only contains DLLs used by shapely. With conda, the DLLs are in a global `Library/bin/` folder, which potentially contains other unwanted DLLs, so the ones to be imported must be specified by name.
@jonnyhsu What error messages are you getting? What DLLs are missing? In my PR that was supposed to fix this issue I specifically check for `geos_c.dll` and `geos.dll` (https://github.com/pyinstaller/pyinstaller/pull/2838/files#diff-46543a7dc222543b79209d4655876e9cR28). Are the ones provided by Gohke's binaries named differently?
Here's the error message:
```
12560 INFO: Loading module hook "hook-shapely.py"...
Unable to find "xxxxxxxxxx\.venv\lib\site-packages\shapely\DLLs\geos.dll" when adding binary and data files.
```
The problem is that it's trying to include files that don't exist. I've addressed it in this pull request: https://github.com/pyinstaller/pyinstaller/pull/3842

Let me know what you think of this solution.
Initial workaround does not work (at least in my case with virtualenvs), is there a more general-purpose workaround ?
This is still an issue with me, at least some version of it:

```
OSError: [WinError 126] The specified module could not be found
Traceback:
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\streamlit\ScriptRunner.py", line 324, in _run_script
    exec(code, module.__dict__)
  File "C:\Users\cfonnesbeck\repos\Analytics\pitcher_heat_maps\app.py", line 13, in <module>
    from plotting import plot_heatmap, plot_heatmaps, heatmap_cmap
  File "C:\Users\cfonnesbeck\repos\Analytics\pitcher_heat_maps\plotting.py", line 9, in <module>
    from shapely.geometry import Point
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\geometry\__init__.py", line 4, in <module>
    from .base import CAP_STYLE, JOIN_STYLE
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\geometry\base.py", line 18, in <module>
    from shapely.coords import CoordinateSequence
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\coords.py", line 8, in <module>
    from shapely.geos import lgeos
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\site-packages\shapely\geos.py", line 145, in <module>
    _lgeos = CDLL(os.path.join(sys.prefix, 'Library', 'bin', 'geos_c.dll'))
  File "c:\users\cfonnesbeck\appdata\local\continuum\anaconda3\lib\ctypes\__init__.py", line 356, in __init__
    self._handle = _dlopen(self._name, mode)
```
Is there any way to get Shapely working on windows?
fonnesbeck,

You need to install shapely through conda forge if using anacaonda
Like so:
conda config --add channels conda-forge
conda install shapely

I had the same error as you, and this worked for me.

Resolving patch:
diff --git a/PyInstaller/hooks/hook-shapely.py b/PyInstaller/hooks/hook-shapely.py
--- a/PyInstaller/hooks/hook-shapely.py
+++ b/PyInstaller/hooks/hook-shapely.py
@@ -10,6 +10,7 @@
 #-----------------------------------------------------------------------------
 
 import os
+from ctypes.util import find_library
 
 from PyInstaller.utils.hooks import get_package_paths
 from PyInstaller.utils.hooks import is_module_satisfies
@@ -23,12 +24,25 @@
 
 binaries = []
 if compat.is_win:
+    # Search conda directory if conda is active, then search standard
+    # directory. This is the same order of precidence used in shapely.
+    standard_path = os.path.join(pkg_dir, 'DLLs')
+    lib_paths = [standard_path, os.environ['PATH']]
     if compat.is_conda:
-        lib_dir = os.path.join(compat.base_prefix, 'Library', 'bin')
-    else:
-        lib_dir = os.path.join(pkg_dir, 'DLLs')
-    dll_files = ['geos_c.dll', 'geos.dll']
-    binaries += [(os.path.join(lib_dir, f), '.') for f in dll_files]
+        conda_path = os.path.join(compat.base_prefix, 'Library', 'bin')
+        lib_paths.insert(0, conda_path)
+    original_path = os.environ['PATH']
+    try:
+        os.environ['PATH'] = os.pathsep.join(lib_paths)
+        dll_path = find_library('geos_c')
+    finally:
+        os.environ['PATH'] = original_path
+    if dll_path is None:
+        raise SystemExit(
+            "Error: geos_c.dll not found, required by hook-shapely.py.\n"
+            "Please check your installation or provide a pull request to "
+            "PyInstaller to update hook-shapely.py.")
+    binaries += [(dll_path, '.')]
 elif compat.is_linux:
     lib_dir = os.path.join(pkg_dir, '.libs')
     dest_dir = os.path.join('shapely', '.libs')


Test patch: