trexinc / evil-programmers

Misc. Far plugins and tools by evil programmers
66 stars 26 forks source link

Making a plugin using Pygin, have problem importing pywinauto #42

Closed jonisb closed 5 years ago

jonisb commented 5 years ago

Hi, I'm trying to make my first plugin using Pygin on Far 3.0.0.5462 x86 and Python 3.8-32.

I'm trying to import pywinauto and getting this error:

ImportError: DLL load failed while importing win32api: The specified module could not be found.

Traceback (most recent call last):
  File "D:\Program\Tools\Far Manager Test\Adapters\Win32\Release\pygin\_loader.py", line 61, in _load_plugin
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 783, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "D:\Profiles\Far manager Test\Plugins\IndexSearch\IndexSearch.far.py", line 5, in <module>
    from pywinauto import Desktop, Application
  File "D:\Python\Python38-32\lib\site-packages\pywinauto\__init__.py", line 59, in <module>
    import win32api  # noqa: E402

My code works when not using Pygin but running in Far using Python 3.8-32 directly.

The Hello world example plugin works, so I assume I installed Pygin correctly.

alabuzhev commented 5 years ago

Check that your %PATH% environment variable contains the same set of directories in both cases. Probably something like C:\Program Files (x86)\Python38-32\lib\site-packages\pywin32_system32 is missing.

jonisb commented 5 years ago

Both the plugin and Far have "D:\Python\Python38-32\lib\site-packages\pywin32_system32" in the PATH

I did a print of "sys.path" from the plugin and got this:

['D:\\Python\\Python38-32\\python38.zip', 'D:\\Python\\Python38-32\\Lib', 'D:\\Python\\Python38-32\\DLLs', 'D:\\Program\\Tools\\Far Manager Test', 'D:\\Python\\Python38-32', 'D:\\Python\\Python38-32\\lib\\site-packages', 'D:\\Python\\Python38-
32\\lib\\site-packages\\win32', 'D:\\Python\\Python38-32\\lib\\site-packages\\win32\\lib', 'D:\\Python\\Python38-32\\lib\\site-packages\\Pythonwin']

Seems correct, I get mostly the same using Python directly:

['D:\\Documents\\!Projects\\Experimental\\IndexSearch', 'D:\\Python\\Python38-32\\python38.zip', 'D:\\Python\\Python38-32\\DLLs', 'D:\\Python\\Python38-32\\lib', 'D:\\Python\\Python38-32', 'D:\\Python\\Python38-32\\lib\\site-packages', 'D:\\P
thon\\Python38-32\\lib\\site-packages\\win32', 'D:\\Python\\Python38-32\\lib\\site-packages\\win32\\lib', 'D:\\Python\\Python38-32\\lib\\site-packages\\Pythonwin']
alabuzhev commented 5 years ago

Are you using a Debug or Release version of Pygin?

I found a very similar question - 13 years passed, but it looks like the win32api module still has ABI issues.

Release works fine for me (hi:exec("import pywinauto") in Far command line gives no errors), while Debug complains about win32api, similar to yours.

jonisb commented 5 years ago

I'm using the build from here: https://ci.appveyor.com/project/alabuzhev/evil-programmers/branch/master/job/eeu7ileawj45xbp0/artifacts

Is there another source for a build?

alabuzhev commented 5 years ago

There are no other sources, I'm using the same build.

However, I was using Python 3.7. With a fresh Python 3.8 install I can reproduce your problem, and, moreover, it doesn't work even in Python itself.

I debugged it and it looks like it cannot find pywintypes38.dll. This file is normally located in Lib\site-packages\pywin32_system32, but having that directory in PATH doesn't help for some reason. Once I copied both pythoncom38.dll and pywintypes38.dll to the Python root directory and to the Far root directory it started working everywhere.

Here people have the same problem.

jonisb commented 5 years ago

Did you run (as admin) "Python38-32\Scripts\pywin32_postinstall.py"? after that it works in normal Python for me but not via the plugin.

I'll try copying the files and see I get it working, I'll try 3.7 also as I don't really need 3.8 but I didn't have a 32bit version installed when I started working on the plugin.

Thanks for the support.

Edit: Copying the files to the FAR directory works 😋 those files ware in the Python root directory probably from the "pywin32_postinstall.py" script.

alabuzhev commented 5 years ago

As far as I can tell from looking at pywin32_postinstall.py, it copies those dlls to System32 (or SysWOW64) if possible, otherwise - to the Python root directory.

If you see them in the latter - presumably, that script was executed as non-admin initially.

Anyways, good to know that it works now.