gpt4 book ai didi

c# - 从ASP.NET调用的Python脚本在IIS Express中运行良好,但在本地IIS中失败

转载 作者:行者123 更新时间:2023-11-30 23:25:24 24 4
gpt4 key购买 nike

表面上看起来似乎是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脚本。


错误的要点是脚本行“ import acrpy”上的“ RuntimeError:NotInitialized”。这在下面的“错误#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首次尝试的结果相同。

第五次尝试进行故障排除:
  由于该错误似乎引用了环境变量,因此我认为本地IIS_IUSRS组可能存在某些问题,出于安全原因,该进程不允许任何线程访问环境变量。那只是一个猜测。在我看来,微软可能会这样做。
  因此,我在IIS中获得了该应用程序来模拟具有本地管理员权限的帐户。当我再次运行ASP.NET应用程序时,它似乎甚至没有尝试读取Python脚本。包装Python脚本的C#进程捕获StandardError和StandardOutput。使用模拟时,什么也不会抓住。同样,调试器停留在Start()和WaitForExit()方法上的时间可以忽略不计,就好像Process对象中的执行线程甚至没有尝试读取Python脚本一样。
  如果是文件夹安全权限的问题,那么模拟帐户将出现一个错误,就像IIS_IUSRS没有足够的权限时出现的那样。但是,我没有任何错误。看来,使用模拟帐户运行的过程甚至没有尝试执行任何操作。

第六次尝试故障排除:
  由于已安装的Python.exe是Python的32位版本,因此我进入了ASP.NET应用程序使用的应用程序池,并确保在高级设置中启用了32位应用程序设置。无论启用还是禁用IIS模拟,结果都不会改变。

我看到的唯一另一个奇怪的事情是Visual Studio中的ASP.NET项目属性显示它是针对.NET Framework 4.5的,而针对IIS Manager版本设置的应用程序池则表明针对.NET CLR设置了应用程序池版本4.0。当我尝试在IIS管理器中更改.NET Framework版本时,它仅提供v4.03和v2.05两种选择。我不知道这有多重要。

编辑(5/18/2016 4:06 pm):
我做了更多测试。我研究了三种不同条件下的一些环境变量。我使用以下三个设置在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模拟无法运行脚本似乎是合理的。评论和建议将不胜感激。

编辑(5/19/2016 1:40 pm):

我尝试在“ IIS Admin Service”属性和W3SVC属性中启用“允许服务与桌面交互”选项。这没有帮助。

我的下一个尝试是创建一个Web服务,该服务调用Python可执行文件并返回结果。我将使当前的ASP.NET应用程序调用Web服务,然后获取结果。
除非有人对为什么这样做不起作用发表评论,或者对如何使当前的ASP.NET应用程序按需运行有评论,否则我将继续执行Web服务策略。

编辑(5/25/2016)

经过将近3周的研究,看来终于可以完成这项工作了。

尽管我不能确定要使它正常工作的确切方法,但在此遵循我所做的两件事。

我用IIS中托管的basicHttpBinding创建了WCF服务。 wsHttpBinding对我不起作用,因为当我尝试为Windows身份验证配置它并设置mode =“ transport”时,我收到一条错误消息,指出将需要ssl。

更重要的事情似乎是,我将WCF服务的应用程序池的进程标识从ApplicationPoolIdentity更改为具有提升特权的帐户。

现在,当我在任务管理器中查看w3wp.exe用户名时,我看到它正在使用该帐户的名称运行。

我的下一步是开始按顺序撤消所有先前的配置,并进行测试以查看哪些配置不是必需的。例如,我已在包含所使用的Python脚本和可执行文件的文件夹的安全性访问中添加了应用程序池帐户。
现在我认为这可能是不必要的,因为w3wp可以通过其新帐户访问Python脚本。我将开始删除以前添加的其他帐户。

事后看来,我认为创建Web服务在技术上可能是不必要的,因为我可能刚刚能够更改运行ASP.NET应用程序的应用程序池的进程标识。但是,这可能存在安全性问题,因为用户可以直接访问ASP.NET应用程序,并且即使该应用程序是Intranet应用程序且没有外部接口,Web服务也只能间接访问。

任何对我使它起作用的见解(建议和/或建设性批评)将不胜感激。

最佳答案

我对此进行了更多研究,现在我知道为什么我的解决方案有效。此信息回答了我的原始问题。以下是我的研究发现的关于此主题的有用且相关的信息。


信息#1


在计算机上安装ArcGIS Desktop 10.3后,它将创建一个目录,用于存储重要信息。该目录的默认位置取决于启动ArcGIS Desktop应用程序安装的用户的登录帐户名称。例如,如果登录帐户为MS \ AHejlsberg,则默认安装的UNC路径将为C:\ Users \ AHejlsberg.MS \ AppData \ Roaming \ ESRI \ Desktop10.3 \
 该目录将包含基本文件,例如.sde数据库连接,默认情况下位于此处,
 C:\ Users \ AHejlsberg.MS \ AppData \ Roaming \ ESRI \ Desktop10.3 \ ArcCatalog \


资讯#2


调用.NET System.Diagnostics.Process对象的Start()方法时,Process对象将使用与运行ASP.NET应用程序的应用程序池中标识的w3wp.exe工作进程相同的帐户运行。
 因此,如果ASP.NET应用程序在DefaultAppPool下运行,并且该应用程序池具有标识ApplicationPoolIdentity,则Windows的本地安全机构将创建一个新的虚拟帐户,其用户SID为DefaultAppPool,组SID为IIS_IUSRS安全主体在其访问令牌中。
 新的.NET Process对象将在该新虚拟帐户的安全上下文中运行。因此,如果新的Process对象包装了Python.exe文件,则该可执行文件将像在应用程序池标识中标识的相同帐户一样运行。
 再举一个例子,如果ASP.NET应用程序在某个应用程序池下运行,该应用程序池已将身份设置为某些特定用户(例如域帐户),则从ASP.NET应用程序派生的.NET Process对象将在安全上下文下运行。该用户。在这种情况下,Python.exe将像特定用户集(作为应用程序池的标识)所调用那样运行。
 即使ASP.NET应用程序启用了模拟,使得返回的经过身份验证的HTTP上下文标识和WindowsIdentity.GetUser()标识都相同,新的.NET Process对象仍不会在该ASP.NET应用程序标识下运行如果应用程序池的标识不同。

注意:程序员可能会过分地假定:如果启用了ASP.NET模拟功能,并且可以将应用程序池的标识设置为该帐户,则ASP.NET应用程序和新生成的.NET Process对象将以同一帐户身份运行。实际上,它们将在彼此完全相同的安全上下文下运行,实际上,尝试访问可安全对象的ASP.NET应用程序进程中的线程将具有模拟令牌,而代表新生成的.NET来访问可安全对象的线程流程对象将只有一个主访问令牌。


资讯#3


如果Python运行时需要与随ArcGIS Desktop一起安装的ESRI ArcPy一起使用,则运行时需要能够访问我在上面的信息#1部分中提到的AppData \ Roaming \ ESRI子文件夹。在我的Python脚本调用“ import ArcPy”命令时,情况就是如此。
 Windows中的帐户具有与之关联的环境变量的列表。从该帐户创建的任何过程都将引用该环境变量列表。
 这些变量之一将被称为“ AppData”。
 Python运行时将在与触发Python可执行文件的帐户身份相关联的环境变量列表中查找AppData变量。
 该AppData变量将需要计算ArcGIS Destkop安装其ESRI子文件夹的位置。将AppData变量的值设置为所需的UNC路径的一种方法是运行“进程”,该进程以与安装ArcGIS Desktop所用帐户相同的身份触发Python可执行文件。
 因此,例如,如果使用名为MS \ AHejlsberg的帐户安装了ArcGIS Desktop,则从ASP.NET生成的.NET进程(随后将调用Python可执行文件)也需要以MS \ AHejlsberg帐户的身份运行。将托管ASP.NET应用程序池的应用程序池的标识设置为该帐户将实现使ASP.NET应用程序使用该所需帐户创建.NET Process对象的目标。

一个人可以检索运行ASP.NET应用程序的身份的环境变量列表,如下所示:

var envVars = Environment.GetEnvironmentVariables();


如果为MS \ AHejlsberg启用了ASP.NET模拟,则AppData变量将如下所示:

// ["APPDATA"] = "C:\\Users\\AHejlsberg.MS\\AppData\\Roaming"


一个人可以检索环境变量列表,以获取从ASP.NET应用程序生成的进程的标识,如下所示:

ProcessStartInfo procInfo = proc.StartInfo;


如果承载该ASP.NET应用程序的应用程序池的标识设置为ApplicationPoolIdentity,并且应用程序池的名称恰好是“ .NET v4.5”,则AppData将如下所示:

// Environment = {System.Collections.Specialized.StringDictionary.GenericAdapter}
// Count = 43
// [19] = {[APPDATA, C:\Windows\system32\config\systemprofile\AppData\Roaming]}


另一方面,如果承载该ASP.NET应用程序的应用程序池的标识设置为MS \ AHejlsberg,则AppData将如下所示:

// Environment = {System.Collections.Specialized.StringDictionary.GenericAdapter}
// Count = 49
// [21] = {[APPDATA, C:\Users\AHejlsberg.MS\AppData\Roaming]}


现在,Python运行时将能够找到ArcGIS Desktop安装的子文件夹。

如果程序员不能将应用程序池的身份设置为特定的用户帐户(如上图所示的域帐户),则另一种选择是将所有ESRI子文件夹复制到对该身份可见的位置应用程序池,例如
C:\ Windows \ system32 \ config \ systemprofile \ AppData \ Roaming
如上图所示,其中应用程序池的名称为“ .NET 4.5”,标识为ApplicationPoolIdentity。
我认为那应该起作用;但是我还没有测试过。可能还需要更改其他变量设置。

注意我的错误的倒数第二行:
    envset =(set(用于self._gp.listEnvironments()中env的env))

我们可以看到Python运行时显然正在尝试访问环境变量。

当我将应用程序池标识设置为ApplicationPoolIdentity时,从ASP.NET派生的.NET Process对象在Windows创建的虚拟帐户的标识下运行,因此Python运行时在错误的UNC路径中查找AppData。这导致了运行时未初始化的错误,我们在回溯的最后一行中看到了。

当我将应用程序池的标识设置为与安装ArcGIS Destkop的帐户相同的标识时,则从ASP.NET应用程序产生的.NET Process对象可以引用AppData变量,从而评估Python的路径运行时可以成功用于“导入ArcPy”语句。

这解决了在IIS Express上成功但在本地IIS上失败的Python运行时的奥秘。

关于c# - 从ASP.NET调用的Python脚本在IIS Express中运行良好,但在本地IIS中失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37304769/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com