嵌入式Python应用程序中的运行时错误R6034

时间:2013-01-27 21:10:12

标签: visual-c++ python-2.7 visual-studio-2005 manifest boost-python

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

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

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

还有其他人遇到过类似的问题吗?你能解决吗?怎么样?

13 个答案:

答案 0 :(得分:93)

我找到了问题的解决方案。希望这会帮助其他人 - 这些问题可能如此令人沮丧的调试。

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

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

  1. 下载Process Explorer here

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

  3. 启动Process Explorer。在“视图”菜单中,转到“下窗格视图”并选择“DLL”。

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

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

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

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

    path=
    myprogram.exe
    

    就是这样。批处理文件只是在程序运行之前清除路径,因此找不到冲突的运行时DLL。

    希望这有帮助!

答案 1 :(得分: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有同样的问题)

答案 2 :(得分:4)

这篇文章详细阐述了@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)

对于 vim with YouCompleteMe 的情况,您可以将以下放在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

答案 3 :(得分:2)

使用迈克尔上面的答案,我可以通过添加:

来解决这个问题,而无需使用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的库。

谢谢!

答案 4 :(得分:2)

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

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

很复杂的是,我的应用程序是运行在64位IIS Express(VS2013)之上的医疗大型.Net解决方案。

我尝试了Dependency Walker(很棒的程序,但过时了,无法帮助解决这个问题)和Process Monitor(ProcMon - 它可能确实找到了一些提示,但即使我使用过滤器,问题仍然存在于数千个不相关的操作,更好的过滤器可能有帮助。)

然而,非常感谢Michael Cooper!您的步骤和Process Explorer(procexp)让我迅速找到一整天都在躲避我的解决方案。

我可以为迈克尔的优秀帖子添加几个笔记。

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

最终我发现msvcr90.dll来自:

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

通过我的路径我找到了上面和另一个类似的目录,似乎包含32位版本。我删除了这两个,重新启动并且...... STILL 遇到了问题。

所以,我再一次跟着迈克尔的步骤,发现另一个 msvcr90.dll现在正在加载:

  • C:\ Program Files \ Intel \ iCLS Client \

再次浏览我的Path,我发现了上面这个目录的(x86)版本。所以,我删除了这两个,应用了更改,重新启动了VS2013和...

不再R6034错误!

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

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

答案 5 :(得分:2)

这篇文章详细阐述了@Micheal Cooper和@frmdstryr。 一旦确定了有问题的PATH条目,就可以将以下内容放在a前面 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])

关于 vim with YouCompleteMe 的情况,您可以将以下放在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仍然可以在任何地方运行。

答案 6 :(得分: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)])

答案 7 :(得分:0)

在我的情况下,重建链接库和主要项目与类似的&#34;运行时执行库&#34;项目设置有帮助。希望对任何人都有用。

答案 8 :(得分:0)

在我的情况下,我意识到问题出现了,在将应用程序编译成exe文件后,我会重命名该文件。因此,保留exe文件的原始名称不会显示错误。

答案 9 :(得分:0)

本页面的讨论涉及的事情远远超过我。 (我没有代码。)尽管如此,我还是将Process Explorer作为推荐的诊断程序运行。我发现另一个程序在它的程序文件夹中使用并需要msvcr90.dll。不理解这里讨论的任何其他内容,作为一个疯狂的猜测我暂时将dll移动到邻近的程序文件夹。

问题解决了。运行时结束错误消息。

(当我完成生成错误消息的程序时,我将dll移回了。)

谢谢大家的帮助和想法。

答案 10 :(得分:0)

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

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

解决方法是将<PYTHON_ROOT>\msvcr90.dll移至该目录。

PS 。 PyWin32在issue的7年后仍然拥有它!

答案 11 :(得分:0)

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

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

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

答案 12 :(得分:-1)

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