【发布时间】:2016-05-18 16:03:21
【问题描述】:
这可能表面上看起来像 Python ArcGIS ArcPy RuntimeError: NotInitialized 的副本,但这是不同的,因为
- 使用ArcGIS 10.0 以后有很大区别 我正在使用的 10.3 等版本
- 指的是安装了多个 Python 版本,而我只 有一个
- 指的是我已经完成的卸载和重新安装
- 指的是不同的操作系统(我在 Win 2012 上运行)
-
指的是在我得到 仅来自 IIS 的错误
我有一个调用 Python 脚本的 ASP.NET 应用程序。该代码使用 System.Diagnostics.Process 对象调用 Python.exe 并向其传递参数,例如 Python 脚本的位置和其他参数。 该 Process 对象在 C# 中如下所示
Process proc = new Process(); proc.StartInfo.Verb = "runas"; proc.StartInfo.FileName = pathToPythonExe; proc.StartInfo.Arguments = procArgs; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.UseShellExecute = false; proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; proc.Start(); proc.WaitForExit(); errorToConsole = proc.StandardError.ReadToEnd(); proc.WaitForExit(); messageToConsole = proc.StandardOutput.ReadToEnd(); proc.WaitForExit();Path 和 PYTHONPATH 环境变量指向 Python 可执行文件所在的确切位置。
当我在 Visual Studio 2015 的 IIS Express 中从 ASP.NET C# 应用程序运行 Python 脚本时,一切运行正常。当我通过命令控制台运行 Python 脚本时,一切运行良好。当我从 IDLE 运行 Python 脚本时,一切运行良好。但是,当我将应用程序发布到 IIS 8.5 并运行它时,Python 脚本中出现错误。此外,当我从 Visual Studio 运行应用程序并使用本地 IIS 而不是 IIS Express 时,Python 脚本再次失败。
所以,这里是它起作用的条件的回顾:
- 在 IIS Express 中从 ASP.NET C# 应用程序运行 Python 脚本 Visual Studio 2015。
- 通过命令控制台运行 Python 脚本。
- 从 IDLE 运行 Python 脚本。
以下是它不起作用的条件的回顾:
- 在本地 IIS Express 中从 ASP.NET C# 应用程序运行 Python 脚本 在 Visual Studio 2015 中。
- 从 IIS 上的 ASP.NET C# 应用程序运行 Python 脚本。
错误的要点是脚本行上的“RuntimeError: NotInitialized”,“import acrpy”。这在下面的“错误 #1”下列出。我看到在 VS(本地 IIS 或 IIS Express)与常规 IIS 中运行它的唯一区别是权限。
当我在 Visual Studio 中运行它时,Visual Studio 应用程序具有管理员权限。 在 IIS 中,身份验证设置为启用 Windows 身份验证。其他一切都被禁用。 以下是应用在 IIS 8.5 中运行以及在带有本地 IIS 的 Visual Studio 中运行时出现的完整错误消息。
错误 #1:
Traceback (most recent call last):
File "E:\Application Development\PublishServiceDefinition\MapPublisher\MapSdDraftCreator.py", line 1, in <module>
import arcpy
File "E:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\__init__.py", line 21, in <module>
from arcpy.geoprocessing import gp
File "E:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\geoprocessing\__init__.py", line 14, in <module>
from _base import *
File "E:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\geoprocessing\_base.py", line 598, in <module>
env = GPEnvironments(gp)
File "E:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\geoprocessing\_base.py", line 595, in GPEnvironments
return GPEnvironment(geoprocessor)
File "E:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\geoprocessing\_base.py", line 551, in __init__
self._refresh()
File "E:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\geoprocessing\_base.py", line 553, in _refresh
envset = (set(env for env in self._gp.listEnvironments()))
RuntimeError: NotInitialized
这是我迄今为止为解决问题所做的工作。
第一次故障排除尝试: 我完全卸载并重新安装了 Desktop 10.3(包括 Python 文件和 arcpy 文件)。那没有帮助。我遇到了同样的错误。
第二次故障排除尝试: 我在另一台 Windows 2012 服务器上安装了 Desktop 10.3(和 Python.exe),并在该机器上设置了 IIS(第二台机器上没有 Visual Studio)。发生了同样的错误。在第二台机器上安装之前,我确保所有 ESRI 产品都已被删除(包括从注册表中删除)。
第三次故障排除尝试: 我在第一行添加了“import arcinfo”,使得 Python 脚本的前两行如下所示:
import arcinfo
import arcpy
这导致了以下错误:
错误 #2:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "e:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\__init__.py", line 21, in <module>
from arcpy.geoprocessing import gp
File "e:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\geoprocessing\__init__.py", line 14, in <module>
from _base import *
File "e:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\geoprocessing\_base.py", line 598, in <module>
env = GPEnvironments(gp)
File "e:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\geoprocessing\_base.py", line 595, in GPEnvironments
return GPEnvironment(geoprocessor)
File "e:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\geoprocessing\_base.py", line 551, in __init__
self._refresh()
File "e:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\geoprocessing\_base.py", line 553, in _refresh
envset = (set(env for env in self._gp.listEnvironments()))
RuntimeError: NotInitialized
Traceback (most recent call last):
File "E:\Application Development\PublishServiceDefinition\MapPublisher\MapSdDraftCreator.py", line 1, in <module>
import arcinfo
File "E:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcinfo.py", line 18, in <module>
gp.setProduct("ArcInfo")
RuntimeError: ERROR 999999: Error executing function.
第四次故障排除尝试: 由于 Windows 身份验证使用本地 IIS_IUSRS 帐户,因此我完全控制该帐户以 • 包含 Python.exe 文件的文件夹, • ArcGIS\Desktop10.3 文件夹 • 包含 Python 脚本的文件夹 • Python 脚本访问的任何文件夹
我从 Python 脚本中删除了“import arcinfo”。结果和我第一次从 IIS 尝试的结果一样。
第 5 次故障排除尝试: 由于该错误似乎引用了环境变量,我认为本地 IIS_IUSRS 组可能出于安全原因不允许其进程中的任何线程访问环境变量。那只是一个猜测。在我看来,微软可能会做一些事情。 因此,我在 IIS 中获取了应用程序来模拟具有本地管理员权限的帐户。当我再次运行 ASP.NET 应用程序时,它似乎甚至没有尝试读取 Python 脚本。包装 Python 脚本的 C# 进程捕获 StandardError 和 StandardOutput。使用模拟时没有捕获任何内容。此外,调试器停留在 Start() 和 WaitForExit() 方法上的时间可以忽略不计,就好像 Process 对象中的执行线程甚至没有尝试读取 Python 脚本一样。 如果这是文件夹安全权限的问题,那么当 IIS_IUSRS 没有足够的权限时,模拟帐户就会出现错误。但是,我没有收到任何错误。看起来使用模拟帐户运行的进程甚至没有尝试做任何事情。
第 6 次故障排除尝试: 由于已安装的 Python.exe 是 32 位版本的 Python,因此我前往 ASP.NET 应用程序使用的应用程序池,并确保在高级设置中启用了 32 位应用程序设置。这不会改变打开或关闭 IIS 模拟的结果。
我看到的唯一其他奇怪的事情是,Visual Studio 中的 ASP.NET 项目属性显示它针对 .NET Framework 4.5,而应用程序池设置为版本 IIS 管理器显示应用程序池设置为.NET CLR 4.0 版。当我尝试在 IIS 管理器中更改 .NET Framework 版本时,它只提供了 v4.03 和 v2.05 两种选择。我不知道这有多重要。
编辑(2016 年 5 月 18 日下午 4:06): 我又做了一些测试。我查看了三种不同条件下的一些环境变量。我使用以下三个设置在 Visual Studio 中运行 ASP.NET 应用程序:
- 本地 IIS,已禁用模拟
- 本地 IIS,启用模拟,身份 = x12345
- IIS Express
以下是这些测试的一些结果。
本地 IIS,已禁用模拟:
Environment.UserDomainName = "IIS APPPOOL"
Environment.UserName = .NET v4.5
本地 IIS,启用模拟,身份 = x12345:
Environment.UserDomainName = x12345
Environment.UserName = ABC
IIS Express:
Environment.UserDomainName = x12345
Environment.UserName = ABC
请注意,在启用模拟的情况下运行与使用 IIS Express 运行的相同身份会导致相同的环境变量。 这告诉我,也许我应该专注于在启用 ASP.NET 模拟的同时使其工作,因为正如我之前提到的,使用 IIS Express 运行始终是成功的。尝试尽可能地模仿那些已知的成功条件似乎对我有益。 对我来说,将精力集中在尝试找出与 IIS Express 相同的环境用户模拟 ASP.NET 无法运行脚本的原因似乎是合理的。评论和建议将不胜感激。
编辑(2016 年 5 月 19 日下午 1:40):
我尝试在“IIS Admin Service”属性和 W3SVC 属性中启用“允许服务与桌面交互”选项。这没有帮助。
我的下一个尝试是创建一个调用 Python 可执行文件并返回结果的 Web 服务。我将让当前的 ASP.NET 应用程序调用 Web 服务,然后返回结果。 除非有人知道为什么这不起作用,或者知道如何让当前的 ASP.NET 应用程序按需要运行,否则我将继续使用 Web 服务策略。
编辑(2016 年 5 月 25 日)
经过将近 3 周的工作,我终于可以完成这项工作了。
虽然我没有确切知道我做了什么来让它工作,但这里遵循我所做的两个主要事情。
我使用托管在 IIS 中的 basicHttpBinding 创建了一个 WCF 服务。 wsHttpBinding 对我不起作用,因为当我尝试为 Windows 身份验证配置它并设置 mode="transport" 时,我收到一条错误消息,指出需要 ssl。
更重要的似乎是我将 WCF 服务的应用程序池的进程标识从 ApplicationPoolIdentity 更改为具有提升权限的帐户。
现在,当我在任务管理器中查看 w3wp.exe 用户名时,我发现它正在使用该帐户的名称运行。
我的下一步是开始按顺序撤消所有以前的配置并测试哪些配置是不必要的。例如,我在包含使用的 Python 脚本和可执行文件的文件夹的安全访问中添加了应用程序池帐户。 现在我认为这可能是不必要的,因为 w3wp 可以通过其新帐户访问 Python 脚本。我将开始删除我之前添加的其他帐户。
事后看来,我认为创建 Web 服务在技术上可能是不必要的,因为我可能刚刚能够更改运行 ASP.NET 应用程序的应用程序池的进程标识。但是,这可能存在安全问题,因为用户可以直接访问 ASP.NET 应用程序,并且 Web 服务只能间接访问,即使此应用程序是 Intranet 应用程序并且没有面向外部的接口。
任何关于我如何让它发挥作用的见解(建议和/或建设性批评)将不胜感激。
【问题讨论】:
-
在 IIS Express 上进行调试时,与开发桌面应用程序几乎没有区别。但这只是错误的路径,因为 IIS 运行方式不同。除非 Python 的东西可以通过其供应商明确地与 IIS 一起使用,否则您将不得不破解源代码。
-
ASP.NET 中从 IIS Express 调用 Python 的 System.Diagnostics.Process 对象与从本地 IIS 调用 Python 的 ASP.NET 中的 System.Diagnostics.Process 对象相同。更改供应商源代码是一个红鲱鱼。需要做的是改变本地 IIS 的配置、安全访问、帐户权限和环境变量,以充分匹配它在其他条件下的工作方式。问题是如何以及具体需要以不同方式进行配置。
-
存在会话等根本区别。因此,您作为该产品的用户而非开发人员的所有尝试很可能会失败,因为您不知道实际上需要哪些资源以及这些差异如何影响您。我不会在这些事情上浪费时间。
-
如果我创建一个 Web 服务来运行 Python 脚本并从 ASP.NET 调用该 Web 服务会怎样?
-
如果你确定 Python 代码是这样工作的,那么我想你可以试试。
标签: c# python asp.net iis arcgis