首页 > 解决方案 > 如果从 C# 控制台应用程序调用,则调用的 Arcpy 脚本不会完成

问题描述

早上好 StackOverflowers,

还有一个问题没有你的帮助我无法解决。我正在开发一个 C# 控制台应用程序 (.NET 5),它调用不同的 Python 脚本来执行 ArcGis 内容 (=> "arcpy"-Lib :)。打电话给他们的方案总是一样的,从来没有问题。在渗透测试过程中,我发现其中一个脚本存在问题:

以下脚本“搜索”要素类中的每一行,放大到它并将其导出为 .png 文件。

通过 cmd (Non Admin & Admin) 或 Python Gui (ArcGis Setup 可用) 执行此操作,它可以完美运行 (=> 创建 138 个图像),但如果我通过 C# App 执行它,它只会创建 36 个图像,之后进程继续运行但不创建图像。创建第 36 个图像后,CPU 使用率从 12% 下降到 0%。

第二个代码片段显示了被调用的方法,但也描述了调用我的 python 脚本的方案。我非常清楚这写得不好,我将在解决这个问题后做一些代码润色:)

我希望有人在那里提供小费。

非常感谢您提前。亲切的问候,简

import arcpy,os, logging

logging.basicConfig(filename='appPython.log', format='%(asctime)s - %(message)s', level=logging.INFO)

#Static Variables
mxdfileName = "D:\DigitalesFahrtenbuch_Datenpunkte\Templates\TemplateTelematik.mxd"

# Set the workspace for ListFeatureClasses
arcpy.env.workspace = str(sys.argv[1])
#arcpy.env.workspace = r"D:\DigitalesFahrtenbuch_Datenpunkte\DigFahrtenbuch_Datenpunkte.gdb"

featureclasses = arcpy.ListFeatureClasses()

try:
    
    # Copy shapefiles to a file geodatabase
    for fc in featureclasses:
        featureName = os.path.splitext(fc)[0]
        if "Dienstverrichtung_" in featureName and "_Projection" in featureName:
            print(featureName)

            #Global Variables
            mxd = arcpy.mapping.MapDocument(mxdfileName)
            df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

            #Create FeatureLayer
            SelectionLayer = arcpy.management.MakeFeatureLayer(fc, "SelectionLayer").getOutput(0)

            #Add Layer to mxd
            arcpy.mapping.AddLayer(df, SelectionLayer, "TOP")

            #Refresh TOC and DataFrames
            arcpy.RefreshActiveView()
            arcpy.RefreshTOC()
            df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

            #Refresh TOC and DataFrames
            arcpy.RefreshActiveView()
            arcpy.RefreshTOC()
            df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

            feature = arcpy.mapping.ListLayers(mxd, SelectionLayer, df)[0]

            fields = ['OID@', 'SHAPE@', 'Name']
            pngPath = r"D:\DigitalesFahrtenbuch_Datenpunkte\Images"

            with arcpy.da.SearchCursor(feature, fields) as cursor:
                for FID, Geometry, Name in cursor:
                    mxd.title = Name
                    print("{} in Bearbeitung.".format(mxd.title))
                    query = "ObjectID = {}".format(str(FID))
                    arcpy.management.SelectLayerByAttribute(feature, "NEW_SELECTION", query)
          
                    df.zoomToSelectedFeatures()
                    df.scale=2500
                    df.referenceScale = 3500
                    arcpy.RefreshActiveView()
       
                    png = "{}\\{}.png".format(pngPath, Name)
        
                    arcpy.mapping.ExportToPNG(mxd, png, df, df_export_width=2200, df_export_height=1300)
                    print("{} erfolgreich exportiert.".format(mxd.title))

    print("Script beendet")

except Exception as e:
    logging.error("Exception occurred", exc_info = True)

public static async Task<Tuple<string, bool>> ZoomToSelectedFeatures(string pPathToPythonExe, string pPathGeoDatabase)
        {
            Tuple<string, bool> resultTuple = null;
            StringBuilder scriptMessageBuilder = new StringBuilder();

            string scriptExceptions = string.Empty;
            string scriptPrints = string.Empty;
            string pythonPath = @"C:/Python27/ArcGIS10.8/python.exe";

            try
            {
                await Task.Run(delegate
                {
                    if (pPathToPythonExe != "")
                    {
                        pythonPath = pPathToPythonExe;
                    }

                    ProcessStartInfo start = new ProcessStartInfo();
                    //python interprater location
                    start.FileName = pythonPath;
                    //argument with file name and input parameters
                    start.Arguments =
                        $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Python_Scripts\\Batch_ZoomToSelectedFeaturesAndExportPNG_2.py")}" +
                        $" {pPathGeoDatabase}";

                    start.UseShellExecute = false; // Do not use OS shell
                    start.CreateNoWindow = true; // We don't need new window
                    start.RedirectStandardOutput = true; // Any output, generated by application will be redirected back
                    start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
                    start.LoadUserProfile = true;

                    using (Process process = Process.Start(start))
                    {
                        process.WaitForExit();

                        using (StreamReader reader = process.StandardOutput)
                        {
                            scriptExceptions = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
                            scriptPrints = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
                            Debug.WriteLine("Batch_ZoomToSelectedFeaturesAndExportPNG_2.py meldet:");
                            Debug.WriteLine(scriptPrints);
                            Debug.WriteLine(scriptExceptions);
                            scriptMessageBuilder.AppendLine(scriptPrints);
                            scriptMessageBuilder.AppendLine(scriptExceptions);
                        }
                    }

                    resultTuple = new Tuple<string, bool>(scriptMessageBuilder.ToString(), true);
                });
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                Debug.WriteLine(scriptExceptions);
                resultTuple = new Tuple<string, bool>(scriptMessageBuilder.ToString(), false);
            }

            return resultTuple;
        }

标签: pythonc#esriarcpy

解决方案


我通过将输出从“打印消息”更改为“日志条目”来解决它。现在....老实说,我不知道为什么,该脚本正确地创建了所有图像。在编辑后的脚本下方。

无论如何,谢谢,祝你有美好的一天!

import arcpy,os,logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG) # process everything, even if everything isn't printed
fh = logging.FileHandler('D:\\appPython.log')
fh.setLevel(logging.DEBUG) # or any level you want
logger.addHandler(fh)

#Define Variables
#Static Variables
mxdfileName = "D:\DigitalesFahrtenbuch_Datenpunkte\Templates\TemplateTelematik.mxd"

# Set the workspace for ListFeatureClasses
arcpy.env.workspace = str(sys.argv[1])
#arcpy.env.workspace = r"D:\DigitalesFahrtenbuch_Datenpunkte\DigFahrtenbuch_Datenpunkte.gdb"

# Use the ListFeatureClasses function to return a list of
#  shapefiles.
featureclasses = arcpy.ListFeatureClasses()


try:
    # Copy shapefiles to a file geodatabase
    for fc in featureclasses:
        featureName = os.path.splitext(fc)[0]
        if "Dienstverrichtung_" in featureName and "_Projection" in featureName:
            logger.info(featureName)

            #Global Variables
            mxd = arcpy.mapping.MapDocument(mxdfileName)
            df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

            #Create FeatureLayer
            SelectionLayer = arcpy.management.MakeFeatureLayer(fc, "SelectionLayer").getOutput(0)

            #Add Layer to mxd
            arcpy.mapping.AddLayer(df, SelectionLayer, "TOP")

            #Refresh TOC and DataFrames
            arcpy.RefreshActiveView()
            arcpy.RefreshTOC()
            df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

            #Refresh TOC and DataFrames
            arcpy.RefreshActiveView()
            arcpy.RefreshTOC()
            df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

            feature = arcpy.mapping.ListLayers(mxd, SelectionLayer, df)[0]

            fields = ['OID@', 'SHAPE@', 'Name']
            pngPath = r"D:\DigitalesFahrtenbuch_Datenpunkte\Images"

            with arcpy.da.SearchCursor(feature, fields) as cursor:
                for FID, Geometry, Name in cursor:
                    mxd.title = Name
                    
                    #print("{} in Bearbeitung.".format(mxd.title))
                    logger.info("{} in Bearbeitung.".format(mxd.title))

                    query = "ObjectID = {}".format(str(FID))
                    arcpy.management.SelectLayerByAttribute(feature, "NEW_SELECTION", query)
          
                    df.zoomToSelectedFeatures()
                    df.scale=2500
                    df.referenceScale = 3500
                    arcpy.RefreshActiveView()
       
                    png = "{}\\{}.png".format(pngPath, Name)
        
                    arcpy.mapping.ExportToPNG(mxd, png, df, df_export_width=2200, df_export_height=1300)
                    
                    logger.info("{} erfolgreich exportiert.".format(mxd.title))
                    #print("{} erfolgreich exportiert.".format(mxd.title))
    logger.info("Script beendet")

except Exception as e:
    logger.error(e)

推荐阅读