41

我正在开发一个使用 Boost.Python 嵌入 Python 解释器的应用程序。这用于运行与主程序交互的用户生成的“脚本”。

不幸的是,一位用户在尝试运行脚本时报告了运行时错误 R6034。主程序启动正常,但我认为加载 python27.dll 时可能会出现问题。

我正在使用 Visual Studio 2005、Python 2.7 和 Boost.Python 1.46.1。该问题仅发生在一个用户的机器上。我以前处理过明显的问题,并设法解决了它们,但在这种情况下,我有点不知所措。

有没有其他人遇到过类似的问题?你能解决吗?如何?

4

13 回答 13

106

我找到了问题的解决方案。希望这会对其他人有所帮助——这些问题调试起来非常令人沮丧

该问题是由第三方软件将自身添加到路径并在其程序文件夹中安装 msvcr90.dll 引起的。在这种情况下,问题是由英特尔的 iCLS 客户端引起的。

那么......如何在类似情况下找到问题?

  1. 在此处下载 Process Explorer 。

  2. 启动您的应用程序并重现运行时错误 R6034。

  3. 启动进程资源管理器。在“查看”菜单中,转到“下窗格视图”并选择“DLL”。

  4. 在顶部窗格中,找到您的应用程序并单击它。底部窗格应显示为您的应用程序加载的 DLLS 列表。

  5. 在列表中找到“msvcr??.dll”。应该有几个。查找不在“winsxs”文件夹中的那个,并记下它。

  6. 现在,在应用程序运行之前检查路径。如果它包含您在第 5 步中记下的文件夹,您可能已经找到了罪魁祸首。

如何解决问题?在运行程序之前,您必须从路径中删除有问题的条目。就我而言,我不需要路径中的任何其他内容,因此我编写了一个简单的批处理文件,如下所示:

path=
myprogram.exe

而已。批处理文件只是在我的程序运行之前清除路径,以便找不到冲突的运行时 DLL。

希望这可以帮助!

于 2013-02-04T05:35:38.537 回答
6

这篇文章详细介绍了@Micheal Cooper 和@frmdstryr,并提供了比我之前的答案更好的选择。您可以将以下内容放在python 脚本前面以清除有问题的条目。

import os, re
path = os.environ['PATH'].split(';')

def is_problem(folder):
    try:
        for item in os.listdir(folder):
            if re.match(r'msvcr\d\d\.dll', item):
                return True
    except:
        pass
    return False

path = [folder for folder in path if not is_problem(folder)]
os.environ['PATH'] = ';'.join(path)

对于带有 YouCompleteMe 的 vim,您可以将以下内容放在您的顶部vimrc

python << EOF
import os, re
path = os.environ['PATH'].split(';')

def is_problem(folder):
    try:
        for item in os.listdir(folder):
            if re.match(r'msvcr\d\d\.dll', item):
                return True
    except:
        pass
    return False

path = [folder for folder in path if not is_problem(folder)]
os.environ['PATH'] = ';'.join(path)
EOF
于 2016-01-25T09:31:24.233 回答
4

更通用的解决方案是:

import os
os.environ['path'] = ";".join(
    [path for path in os.environ['path'].split(";") 
     if "msvcr90.dll" not in map((lambda x:x.lower()), os.listdir(path))])

(我对 VanDyke SecureCRT 有同样的问题)

于 2015-01-08T13:17:13.660 回答
4

(作为评论,这可能比完整的答案更好,但是我尘土飞扬的 SO 帐户。还没有足够的代表。)

与 OP 一样,我也使用嵌入式 Python 2.7 和其他一些本机程序集。

使这件事复杂化的是,我的应用程序是一个运行在 64 位 IIS Express (VS2013) 之上的中型 .Net 解决方案。

我尝试了 Dependency Walker(很棒的程序,但已经过时,无法提供帮助)和 Process Monitor(ProcMon——它可能确实找到了一些提示,但即使我使用过滤器,问题也被隐藏在数千个不相关的操作中,更好的过滤器可能会有所帮助)。

然而,非常感谢迈克尔库珀! 您的步骤和 Process Explorer (procexp) 让我很快找到了一个整天都在躲避我的解决方案。

我可以在 Michael 的优秀帖子中添加一些注释。

  • 我不仅忽略了(即保持不变)\WinSxS\... 文件夹,还忽略了\System32\... 文件夹。

最终我发现 msvcr90.dll 是从以下位置拉进来的:

  • C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64

通过我的路径,我发现了上面和另一个类似的目录,它似乎包含 32 位版本。我删除了这两个,重新启动并且......仍然有问题。

因此,我再次按照 Michael 的步骤进行操作,发现另一个msvcr90.dll 正在从以下位置加载:

  • C:\Program Files\英特尔\iCLS 客户端\

再次通过我的路径,我找到了上面的目录和这个目录的(x86)版本。所以,我删除了这两个,应用了更改,重新启动了 VS2013 并......

不再有 R6034 错误!

我不禁对英特尔这样做感到沮丧。实际上,我在网上的其他地方找到了关于从路径中删除 iCLS 客户端的提示。我试过了,但症状是一样的,所以,我认为这不是问题。可悲的是,iCLS 客户端和 OpenCL SDK 正在标记我的 iisexpress。如果我有幸删除了其中任何一个,R6034 错误仍然存​​在。为了解决这个问题,我不得不切除他们两个。

再次感谢 Michael Cooper 和其他所有人的帮助!

于 2015-06-23T19:46:15.977 回答
3

使用上面迈克尔的回答,我可以在没有 bat 文件的情况下通过添加以下内容来解决这个问题:

import os

# Remove CLS Client from system path
if os.environ['PATH'].find("iCLS Client")>=0:
    os.environ['PATH'] = "".join([it for it in os.environ['PATH'].split(";") if not it.find("iCLS Client")>0])

到应用程序的主要 python 文件。它只是确保系统路径不包括在导入加载 dll 的库之前导致问题的路径。

谢谢!

于 2014-07-11T18:35:03.953 回答
2

这篇文章详细介绍了@Micheal Cooper 和@frmdstryr。一旦您确定了有问题的 PATH 条目,您可以将以下内容放在python 脚本前面 ,假设这里iCLS ClientCMake问题。

import os
for forbidden_substring in ['iCLS Client', 'CMake']:
    os.environ['PATH'] = ';'.join([item for item in os.environ['PATH'].split(';')
                                   if not item.lower().find(forbidden_substring.lower()) >= 0])

关于带有 YouCompleteMe 的 vim案例,您可以将以下内容放在您的顶部vimrc

python << EOF
import os
for forbidden_substring in ['iCLS Client', 'CMake']:
    os.environ['PATH'] = ';'.join([item for item in os.environ['PATH'].split(';')
                                   if not item.lower().find(forbidden_substring.lower()) >= 0])
EOF

如果这些解决方案都不适用于您,您可以尝试手动从 PATH 中删除导致条目的问题,但您要确保不会破坏系统上依赖于这些 PATH 条目的任何其他内容。因此,例如,对于 CMake,您可以尝试删除其 PATH 条目,并且仅将指向 cmake.exe 二进制文件的符号链接(或类似内容)放入 PATH 中的其他目录中,以确保 cmake 仍然可运行从任何地方。

于 2016-01-09T16:34:42.790 回答
1

感谢您的解决方案。我只是稍微修改了这个示例代码,因为我系统中的路径变量包含字符串“ICLS CLIENT”而不是“iCLS Client”

import os
# print os.environ['PATH']
# Remove CLS Client from system path
if os.environ['PATH'].find("iCLS Client") >= 0 or os.environ['PATH'].find("ICLS CLIENT") >= 0:
    os.environ['PATH'] = "".join([it for it in os.environ['PATH'].split(";") if not (it.find("iCLS Client")>0 or it.find("ICLS CLIENT")>0)])
于 2014-11-20T14:08:59.157 回答
0

在我的情况下,重建链接库和具有类似“运行时执行库”项目设置的主项目有帮助。希望这对任何人都有用。

于 2015-02-11T01:23:02.260 回答
0

在使用Universal-CRTPython27.dll从 C 程序嵌入时,我也遇到了同样的问题。

A<PYTHON_ROOT>\msvcr90.dll是罪犯。并且<PYTHON_ROOT>在我的PATH. AFAICS 的唯一用户msvcr90.dllPyWin32模块 <PYTHON_ROOT>\lib\site-packages\win32\win32*.pyd

修复只是移动<PYTHON_ROOT>\msvcr90.dll到该目录。

附言。7 年后,PyWin32 仍然存在这个问题

于 2018-11-14T12:47:46.507 回答
0

就我而言,当我将应用程序编译成 exe 文件后,我将重命名该文件时,我意识到问题来了。所以保留exe文件的原始名称不会显示错误。

于 2015-08-31T09:05:40.270 回答
0

The discussion on this page involves doing things way far advanced above me. (I don't code.) Nevertheless, I ran Process Explorer as the recommended diagnostic. I found that another program uses and needs msvcr90.dll in it's program folder. Not understanding anything else being discussed here, as a wild guess I temporarily moved the dll to a neighboring program folder.

Problem solved. End of Runtime error message.

(I moved the dll back when I was finished with the program generating the error message.)

Thank you all for your help and ideas.

于 2015-10-09T04:48:02.680 回答
0

通过 Process Explorer 检查任何具有用户指定路径的库。除了运行 Python 3 外,我不必msvcr??.dll 解决相同的问题。目前的解决方案没有帮助,因为它们没有指示msvcr90.dll. 我一步一步调试代码,直到行后出现错误对话框(当我的代码导入PyTables模块时调用):

import ctypes
ctypes.cdll.LoadLibrary('libbz2.dll')

然后 Process Explorer 帮助找到libbz2.dll导致问题的路径(@Micheal Cooper 算法的第 3、4 步)

于 2019-06-23T03:51:18.520 回答
-1

为仍在寻找解决方案的人添加此答案。ESRI 针对此错误发布了补丁。只需从他们的网站下载补丁(无需登录),安装即可解决问题。我下载了 10.4.1 的补丁,但可能还有其他版本的补丁。

于 2017-08-08T08:18:09.660 回答