From VBA and VB6 I'm calling a dll the creates a Python 开发者_运维知识库interpreter. If I set the PATH
environment variable to point to "C:\python27"
and PYTHONPATH
to "c:\python27\lib"
all is fine.
If I don't set the PATH
then calling Py_Initialise()
crashes XL or my VB6 app, even if I call Py_SetProgramName
with "c:\python27\python27.exe"
first.
I'd like to specify the installation in VB/VBA rather than having it set in the environment as I can't do that in XL (works ok for VB6).
The best answer I've found so far is that it is a bug in Python - http://bugs.python.org/issue6498. The intepreter seems to call exit() on certain errors rather than passing a code back to the caller. Not very friendly if you're embedding python in an app. But there you go.
try to change the working directory before calling the dll:
In your VBA code:
chdir("c:\python27\") '- change the working-directory for python
=> call dll '- call the dll
chdir(app.Path) '- change back to your folder (maybe you want to save your current folder bevore you change it the first time and change back to this?!)
regards Thomas
You can simply check if the needed environment variable is set:
dim PPath as string
PPath = trim(Environ("PYTHONPATH"))
if (PPath<>"")
<call dll>
else
msgbox ("Error!")
end if
Or you can run the dll in a nother Test-Process: if this call works you know that it is OK to call the dll - it depends on the DLL call your using so I'm not sure about that:
Private Declare Function CloseHandle Lib "kernel32" (ByVal _
hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" (ByVal _
dwDesiredAccess As Long, ByVal bInheritHandle As _
Long, ByVal dwProcessId As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Const STILL_ACTIVE = &H103
Const PROCESS_ALL_ACCESS = &H1F0FFF
...
dim IsActive as boolean
dim Handle as long
Dim TaskID As Long
TaskID = Shell("rundll32.exe pyton.dll Py_Initialise()", vbNormalNoFocus)
<wait for some time>
'- check if pyton.dll is still running
Handle = OpenProcess(PROCESS_ALL_ACCESS, False, TaskID)
Call GetExitCodeProcess(Handle, ExitCode)
Call CloseHandle(Handle)
IsActive = IIf(ExitCode = STILL_ACTIVE, True, False)
if (not IsActive) then
msgbox ("Error!")
else
<kill process>
<call dll normally>
end if
Regards Thomas
精彩评论