Python Learning (6) The most complete Pywinauto module automation operation software in history

1 This article has a lot of design content, but it is not difficult, and it is all dry goods. Be patient and read the following.

The update of resources during work requires repeated operation of the software, which does not conform to the consistent style of the program, so the python module pywinauto is used to realize the automatic operation of the software. Just click the mouse and forget about it. Is it very convenient.
1Current requirements: Technicians need to repeatedly operate the software to make version numbers and installation packages every time resources are updated, hoping to reduce this workload.
2 Tools used pycharm + Unity

2 process

1 Using Unity Editor Mode and Pycharm

1. I need to copy the updated resources to the specified folder according to the selected project in Unity.
2. Use exe to make the version number and resource list.
3Use SUFDesign software to make the installation package.

2 copies

Copy this part and skip directly, the points that individuals need to pay attention to

GUIStyle st = GUI.skin.FindStyle ("flow node 2");
st.fontSize = 15;
st.alignment = TextAnchor.UpperCenter;
GUILayout.Space (10);
if (GUILayout.Button ("制作版本号\n(慎点!)",st, GUILayout.Height (50), GUILayout.Width (150)))
 {
   CallBuildTool ();
 }

Use GUI built-in styles
insert image description here

3 Unity executes python script to make version number

Unity cannot execute python scripts. C# is a compiled language, which needs to be compiled first. Python is an interpreted language, which can be run directly but requires an interpreter. I use python3.7, install pycharm and Anaconda Unity to start a thread
call The interpreter and then the interpreter executes the py script, and the py script automates the operation, and this is the whole process.

  #region 调用打包工具
    private static string FilePath = @"F:\workspace\PythonTest\PythonCallHardware\venv\Scripts\python.exe";
    // [MenuItem("PublishTools/制作版本号",false,2)]
    private static void CallBuildTool ()
    {
    
    
        string file = @"F:/workspace/PythonTest/PythonCallHardware/Scripts/CallBuildTools.py";
        ProcessStartInfo start = new ProcessStartInfo ();
        start.FileName = FilePath;
        start.Arguments = file + " " + currentItemType;
        start.UseShellExecute = false;
        //参数用空格分隔
        //start.Arguments = path + " " + type + " " + mode;
        start.RedirectStandardOutput = true;
        start.RedirectStandardInput = true;
        start.RedirectStandardError = true;
        start.CreateNoWindow = false;
        Process process = Process.Start (start);
    }
    #endregion

Execute the file with a software like we use CMD,
start.FileName = FilePath; the parameter is the location of the interpreter
start.Arguments = file + " " + currentItemType; the first parameter is the file location, and the second is my choice Item type
Note that the parameters are usedspaceseparated

4Unity executes the python script to make the installation package

Refer to the above for calling methods in the same way
insert image description here

5 The next highlight is to use the pywinauto module to automate operations

When I use it, I usually use conda to download the module package, but this module cannot be downloaded using conda. I downloaded it with pip. Of course, I did not use the compiler when installing conda.

1 How do we get the parameters passed in the script?
We use the sys module sys.argv[1] is the first parameter by analogy

	self.CurrentType = int(sys.argv[1]))
	self.CurrentModel = int(sys.argv[2])

2 If we judge the type,
we use enum enumeration

class ProjectType(enum.Enum):
	'''
	项目类别
	'''
	CeLiang = 1
	GongYi = 2
	GCLX = 3
	AnZhuangShiTu = 4
	ZhuangPeiShi = 5
	PingFa = 6
	JingZhuangXiu = 7
	GouZhao = 8
	AnQuanWenMingGongDi = 9
	JiLiangJiJia = 10
	DaoLuGongCheng = 11
	QiangLiangGongCheng = 12
	ShouGongSuanLiang = 13
	GangJieGou = 14,
	# 建筑电气施工
	JianZhuDianQiShiGong = 15,
	DaqQiaoShiTu = 16,
	SuiDaoGongCheng = 17,
	# 不确定
	GongChengShiTu = 18,

When we use it, we can use the number to correspond to the project name

self.modelType = ModelType(self.CurrentModel)

3 The most important thing is the pywinauto module.
We need to judge the type of the current software window, uia or win32
Link: https://pan.baidu.com/s/1VQv_SKGGCHwVZIqxa5iyMQ
Extraction code: x5nt
After confirming, use the module to call the software to create a connection

	app = Application(backend='uia').start(r"F:\work\SetupFactory\SUFDesign.exe", timeout=10)
		# 把进程和当前获得句柄联系起来
	app = Application().connect(path=r"F:\work\SetupFactory\SUFDesign.exe", timeout=10)

You can get the subspace and form through app.window()

		# 获取 当前的窗 通过标题
		dlg_new = app.window(title="Start a New Project")
		dlg_new.wait("ready", timeout=5)  # 等待窗体响应  有很多状态 可以看方法内部的介绍
		dlg_new.print_control_identifiers()# 打印出 窗体的结构  你可以查找对应的控件
		# 标识一下
		dlg_new.draw_outline() 在窗体的周边划线 

Find the button to click

		btn_cancle = dlg_new[r'Cancle']
		btn_cancle.click()

use shortcut keys

		dlg_Open = app.window(title=r"Untitled - Setup Factory")
		dlg_Open.wait("exists enabled visible ready", timeout=5)
		dlg_Open.draw_outline()

		# dlg_Open.print_control_identifiers()
		# 使用快捷键 打开suf
		dlg_Open.type_keys("^O")

The problem I encountered with the corresponding shortcut keys
insert image description hereis to select the options in the combobox

		# 选择组合框中的
		dlg_Mul.ComboBoxWrapper.select("Always overwrite existing file")

4 When using pywinauto, I have been reporting an error for a long time. The program is 32 and I am using 64-bit python.exe

# 解决不能运行自己做的exe的问题
import os
os.environ.update({
    
    "__COMPAT_LAYER":"RUnAsInvoker"})
# 解决报错 是32位程序需要 使用32位python.exe
import warnings
warnings.simplefilter('ignore', category=UserWarning)

In the process of use, it is necessary to keep trial and error to let the program sleep when it is appropriate, because the script cannot continue without the program and
we can get the current focus.

		dlg_Pro.get_active()
		dlg_Pro.get_focus()

SUFDesign is like this,
insert image description here
all scripts are attached below
Unity C#

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System.Diagnostics;

/// <summary>
/// 将I盘下的各个工程的资源和播放器移动到H盘下  方便制作安装包
/// </summary>
enum itemType
{
    
    
    测量 = 1,
    工艺 = 2,
    工程力学 = 3,
    安装识图 = 4,
    装配式 = 5,
    平法 = 6,
    精装修 = 7,
    构造 = 8,
    安全文明工地 = 9,
    计量计价 = 10,
    道路工程 = 11,
    桥梁工程 = 12,
    手工算量 = 13,

    钢结构 = 14,
    建筑电气施工 = 15,
    道桥识图 = 16,
    隧道工程 = 17,

    工程识图 = 18,
    造价识图 = 20

}
public class PublishEditorWindow : EditorWindow
{
    
    
    #region 复制文件


    private static itemType currentItemType = itemType.安装识图;
    private static float Window_height = 400;
    private static float Window_width = 1000;
    private static float LeftArea_width;
    private static float RightArea_height;
    private GUIStyle fontStyle;

    //private static string Source_DirvePath = @"H:/PatchTool/RGZSoft/";
    private static string Source_DirvePath = @"D:/工作安装包/PatchTool/RGZSoft";
    //private static string Target_DirvePath = @"I:/rgzsoft/RGZSoft/";
    private static string Target_DirvePath = @"D:/工作安装包/网页版本打包项";
    /// <summary>
    /// 目的资源路径
    /// </summary>
    private static string Source_player_module = "module";
    private static string Source_weike = @"WeiKe/WKPlayerResources/WKAssets";


    /// <summary>
    /// 当前资源路径
    /// </summary>
    private static string Target_player_module = "module";
    private static string Target_weike = @"WeiKe/WKPlayerResources/WKAssets";

    private static string sourceAssetsPath;
    private static string sourcePlayerPath;
    private static List<string> sourceWkPath;
    private static string TargetAssetsPath;
    private static string TargetPlayerPath;
    private static string TargetWkPath;

    private static bool IsAssetCopy = true;
    private static bool IsPlayerCopy = true;
    private static bool IsWkCopy = true;
    private static bool IsWkPlayer = true;
    private static string str;

    private string towkBg;
    private string fromwkBg;
    private string fromwkXml;
    private string towkXml;

    private string fromWkPlayerPath;
    private string toWkPlayerPath;

    [MenuItem ("PublishTools/移动各项目资源", false, 1)]
    private static void PublishWebglTool ()
    {
    
    
        PublishEditorWindow publish = GetWindowWithRect<PublishEditorWindow> (new Rect (0, 0, Window_width, Window_height), false, "移动项目资源");
        publish.ShowPopup ();
        LeftArea_width = Window_width / 3 * 2;
        RightArea_height = Window_width - LeftArea_width;
        sourceWkPath = new List<string> ();
    }

    private void DrawLabel ( string content, GUIStyle style = null )
    {
    
    
        EditorGUILayout.BeginHorizontal ();
        GUILayout.Label ("已选择的源播放器路径:", style);
        GUILayout.TextField (sourcePlayerPath);
        EditorGUILayout.EndHorizontal ();
    }
    private void OnGUI ()
    {
    
    
        fontStyle = GUI.skin.FindStyle ("flow node 0");
        //fontStyle.normal.textColor = Color.white;
        fontStyle.fontSize = 12;
        GUIStyle style = new GUIStyle ();
        style.fixedWidth = 130;
        style.normal.textColor = Color.red;
        GUILayout.BeginArea (new Rect (LeftArea_width, 0, RightArea_height, Window_height), "", "box");
        EditorGUILayout.BeginVertical ();
        EditorGUILayout.LabelField ("请选择要移动的项目:");
        EditorGUILayout.LabelField ("项目名称");

        currentItemType = (itemType)EditorGUILayout.EnumPopup (currentItemType, GUILayout.Height (25));
        if (GUILayout.Button ("确定"))
        {
    
    
            CompactStringPath ();
        }
        EditorGUILayout.LabelField ("如果你选择复制选择的项目,请按下方按钮:");
        if (GUILayout.Button ("复制已选的项目"))
        {
    
    
            CopySelectItem ();
        }
        EditorGUILayout.LabelField ("如果你选择复制全部的项目,请按下方按钮:");
        if (GUILayout.Button ("复制全部项目"))
        {
    
    
            CopyMultipleDirectory ();
        }
        EditorGUILayout.EndVertical ();


        GUILayout.Space (50);
        if (GUILayout.Button ("清理缓存"))
        {
    
    
            EditorUtility.UnloadUnusedAssets ();
        }
        GUILayout.EndArea ();

        //绘制左边
        GUILayout.BeginArea (new Rect (0, 0, LeftArea_width, Window_height), "", "box");
        EditorGUILayout.BeginVertical ();
        GUILayout.Space (5);
        EditorGUILayout.BeginHorizontal ();
        //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath);     
        GUILayout.Label ("已选择的源文件路径:", style);
        GUILayout.TextField (sourceAssetsPath);
        EditorGUILayout.EndHorizontal ();
        GUILayout.Space (2);
        EditorGUILayout.BeginHorizontal ();
        //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath);
        GUILayout.Label ("已选择的源播放器路径:", style);
        GUILayout.TextField (sourcePlayerPath);
        EditorGUILayout.EndHorizontal ();
        GUILayout.Space (2);
        EditorGUILayout.BeginHorizontal ();
        //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath);
        GUILayout.Label ("已选择的源微课资源路径:", style);
        GUILayout.TextField (GetStrByList (sourceWkPath));
        EditorGUILayout.EndHorizontal ();
        GUILayout.Space (2);
        EditorGUILayout.BeginHorizontal ();
        //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath);
        GUILayout.Label ("已选择的微课播放器路径:", style);
        GUILayout.TextField (fromWkPlayerPath);
        EditorGUILayout.EndHorizontal ();
        GUILayout.Space (5);

        EditorGUILayout.BeginHorizontal ();
        GUILayout.Label ("目标互动资源路径:", style);
        GUILayout.TextField (TargetAssetsPath);
        EditorGUILayout.EndHorizontal ();

        GUILayout.Space (2);
        EditorGUILayout.BeginHorizontal ();
        //EditorGUILayout.LabelField ("要复制的目标路径:",TargetPath);
        GUILayout.Label ("目标播放器路径:", style);
        GUILayout.TextField (TargetPlayerPath);
        EditorGUILayout.EndHorizontal ();
        GUILayout.Space (2);
        EditorGUILayout.BeginHorizontal ();
        //EditorGUILayout.LabelField ("要复制的目标路径:",TargetPath);
        GUILayout.Label ("目标微课资源路径:", style);
        GUILayout.TextField (TargetWkPath);
        EditorGUILayout.EndHorizontal ();

        EditorGUILayout.BeginHorizontal ();
        //EditorGUILayout.LabelField ("已选择的源文件路径",CurrentPath);
        GUILayout.Label ("目标微课播放器路径:", style);
        GUILayout.TextField (toWkPlayerPath);
        EditorGUILayout.EndHorizontal ();
        GUILayout.Space (5);

        IsAssetCopy = EditorGUILayout.Toggle ("互动资源", IsAssetCopy);
        IsPlayerCopy = EditorGUILayout.Toggle ("播放器资源", IsPlayerCopy);
        IsWkCopy = EditorGUILayout.Toggle ("微课资源(全部)", IsWkCopy);
        IsWkPlayer = EditorGUILayout.Toggle ("微课播放器", IsWkPlayer);
        EditorGUILayout.EndVertical ();

        GUILayout.Space (20);
        GUIStyle button_style;
        button_style =/* GUI.skin.FindStyle ("flow node 1");*/new GUIStyle ();
        button_style.fontSize = 17;
        button_style.fontStyle = FontStyle.Bold;
        //button_style.margin = new RectOffset (0,0,0,0);
        button_style.alignment = TextAnchor.MiddleLeft;
        button_style.normal.textColor = Color.red;
        EditorGUILayout.BeginHorizontal ();
        GUILayout.Label ("当前已选项目是: ", GUILayout.Width (100));
        button_style.normal.textColor = Color.green;
        GUILayout.Label (currentItemType.ToString (), button_style, GUILayout.Width (200));

        EditorGUILayout.EndHorizontal ();
        GUIStyle st = GUI.skin.FindStyle ("flow node 2");
        st.fontSize = 15;
        st.alignment = TextAnchor.UpperCenter;
        GUILayout.Space (10);
        if (GUILayout.Button ("制作版本号\n(慎点!)",st, GUILayout.Height (50), GUILayout.Width (150)))
        {
    
    
            CallBuildTool ();
        }
        GUILayout.EndArea ();

        //绘制右边

    }


    private void CompactStringPath ()
    {
    
    
        Resources.UnloadUnusedAssets ();

        //源资源
        sourceAssetsPath = PathTool.CombinePath (Source_DirvePath, GetDirNameByType (currentItemType));
        sourcePlayerPath = PathTool.CombinePath (Source_DirvePath, Target_player_module, GetDirNameByType (currentItemType));

        fromWkPlayerPath = PathTool.CombinePath (Source_DirvePath, Source_player_module, "WeiKe");
        toWkPlayerPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType.ToString () + "微课", Target_player_module, "WeiKe");
        str = GetWkNameByType (currentItemType);
        if (str.Contains ("+"))
        {
    
    
            string[] sourceWkPath_Arr = str.Split ('+');
            sourceWkPath.Clear ();
            foreach (var i in sourceWkPath_Arr)
            {
    
    
                if (!sourceWkPath.Contains (i))
                    sourceWkPath.Add (PathTool.CombinePath (Source_DirvePath, Target_weike, i));
            }
        }
        else
        {
    
    
            sourceWkPath.Clear ();
            sourceWkPath.Add (PathTool.CombinePath (Source_DirvePath, Target_weike, GetWkNameByType (currentItemType)));
        }
        TargetAssetsPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType.ToString () + "互动", GetDirNameByType (currentItemType));
        TargetPlayerPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType.ToString () + "互动", Target_player_module, GetDirNameByType (currentItemType));
        TargetWkPath = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType + "微课", Target_weike, GetWkNameByType (currentItemType));

        towkBg = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType + "微课", Target_weike, "WKLoadBG");

        fromwkBg = PathTool.CombinePath (Source_DirvePath, Source_weike, "WKLoadBG");
        towkXml = PathTool.CombinePath (Target_DirvePath, currentItemType.ToString (), currentItemType + "微课", Target_weike, "WK_ID对照表.xml");
        fromwkXml = PathTool.CombinePath (Source_DirvePath, Source_weike, "WK_ID对照表.xml");


        UnityEngine.Debug.Log ("源文件互动路径sourceAssetsPath" + sourceAssetsPath);
        UnityEngine.Debug.Log ("源文件互动播放器路径sourcePlayerPath" + sourcePlayerPath);
        UnityEngine.Debug.Log ("源文件微课资源路径sourceWkPath" + string.Join (" ", sourceWkPath.ToArray ()));
        UnityEngine.Debug.Log ("源文件WK_ID对照表 " + fromwkXml);
        UnityEngine.Debug.Log ("源文件微课背景图路径 " + fromwkBg);
        UnityEngine.Debug.Log ("源文件微课播放路径 " + fromWkPlayerPath);

        UnityEngine.Debug.Log ("目标互动路径TargetAssetsPath" + TargetAssetsPath);
        UnityEngine.Debug.Log ("目标互动播放器路径TargetPlayerPath" + TargetPlayerPath);
        UnityEngine.Debug.Log ("目标微课资源路径TargetWkPath" + TargetWkPath);
        UnityEngine.Debug.Log ("目标微课背景图路径 towkBg" + towkBg);
        UnityEngine.Debug.Log ("目标WK_ID对照表 " + towkXml);
        UnityEngine.Debug.Log ("目标文件微课播放器 " + toWkPlayerPath);
    }
    private string GetStrByList ( List<string> str_list )
    {
    
    
        StringBuilder sb = new StringBuilder ();
        foreach (string s in str_list)
        {
    
    
            sb.Append (s);
            if (s != str_list[str_list.Count - 1])
                sb.Append ("\n");
        }
        return sb.ToString ();
    }

    private void CopySelectItem ()
    {
    
    
        //互动资源
        if (IsAssetCopy)
            CopySelectDirectory (sourceAssetsPath, TargetAssetsPath);
        //互动播放器
        if (IsPlayerCopy)
            CopySelectDirectory (sourcePlayerPath, TargetPlayerPath);
        //微课资源
        if (IsWkCopy)
        {
    
    
            foreach (var i in sourceWkPath)
            {
    
    
                CopySelectDirectory (i, TargetWkPath);
            }
            //背景图
            CopySelectDirectory (fromwkBg, towkBg);
            //wk对照表
            File.Copy (fromwkXml, towkXml, true);
        }
        //微课播放器
        if (IsWkPlayer)
            CopySelectDirectory (fromWkPlayerPath, toWkPlayerPath);

        UnityEngine.Debug.Log (string.Format ("<color=red>复制完成{0}</color>", currentItemType));
    }
    /// <summary>
    /// 复制选择的文件夹
    /// </summary>
    /// <param name="sourcePath">源文件路径</param>
    /// <param name="targetPath">目标文件路径</param>
    private static void CopySelectDirectory ( string sourcePath, string targetPath )
    {
    
    
        if (!Directory.Exists (targetPath))
        {
    
    
            Directory.CreateDirectory (targetPath);
        }
        DirectoryInfo dirInfo = new DirectoryInfo (sourcePath);
        List<FileInfo> fileList = new List<FileInfo> (dirInfo.GetFiles ());
        fileList.ForEach (c =>
        {
    
    
            EditorUtility.DisplayProgressBar ("正在复制", c.FullName, (int)(fileList.IndexOf (c) + 1 / fileList.Count));
            string destPath = PathTool.CombinePath (targetPath, c.Name);
            File.Copy (c.FullName, destPath, true);
            UnityEngine.Debug.Log (c.FullName + "复制到to" + destPath + "成功");
        });

        List<DirectoryInfo> folders = new List<DirectoryInfo> (dirInfo.GetDirectories ());
        folders.ForEach (c =>
        {
    
    
            string targetpath = PathTool.CombinePath (targetPath, c.Name);
            UnityEngine.Debug.Log (string.Format ("文件夹中 源文件{0},目标文件{1}", c.FullName, targetpath));
            CopySelectDirectory (c.FullName, targetpath);
        });
        EditorUtility.ClearProgressBar ();
    }
    /// <summary>
    /// 复制全部的文件夹
    /// </summary>
    /// <param name="sourcePath"></param>
    /// <param name="targetPaht"></param>
    private static void CopyMultipleDirectory ()
    {
    
    

    }
    /// <summary>
    /// 获得互动名称
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    private static string GetDirNameByType ( itemType type )
    {
    
    
        string dirname = string.Empty;
        switch (type)
        {
    
    
            case itemType.安装识图:
                dirname = "AnZhuangShiTu";
                break;
            case itemType.测量:
                dirname = "CeLiang";
                break;
            case itemType.钢结构:
                dirname = "GangJieGou";
                break;
            case itemType.工程识图:
                dirname = "GongChengShiTu";
                break;
            case itemType.工艺:
                dirname = "GongYi";
                break;
            case itemType.构造:
                dirname = "Struct";
                break;
            case itemType.计量计价:
                dirname = "JiLiangJiJia";
                break;
            case itemType.精装修:
                dirname = "jingzhuangxiu";
                break;
            case itemType.工程力学:
                dirname = "GCLX";
                break;
            case itemType.平法:
                dirname = "PingFa";
                break;
            case itemType.造价识图:
                dirname = "CostKnowledge";
                break;
            case itemType.装配式:
                dirname = "ZhuangPeiShi";
                break;
            case itemType.建筑电气施工:
                dirname = "InstallProject";
                break;
            case itemType.桥梁工程:
                dirname = "BridgeProject";
                break;
            case itemType.道桥识图:
                dirname = "BridgeFigure";
                break;
            case itemType.隧道工程:
                dirname = "SuiDaoProject";
                break;
            default:
                break;
        }
        return dirname;
    }
    /// <summary>
    /// 获得wk名称
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    private static string GetWkNameByType ( itemType type )
    {
    
    
        string wkName = string.Empty;
        switch (type)
        {
    
    
            case itemType.安装识图:
                wkName = "AZST";
                break;
            case itemType.测量:
                wkName = "CL";
                break;
            case itemType.钢结构:
                wkName = "GJG";
                break;
            case itemType.工程识图:
                wkName = "GZst";
                break;
            case itemType.工艺:
                wkName = "GRgy";
                break;
            case itemType.构造:
                wkName = "GRgz";
                break;
            case itemType.计量计价:
                wkName = "GRjljj";
                break;
            case itemType.精装修:
                wkName = "ZSzx";
                break;
            case itemType.工程力学:
                wkName = "GCLX";
                break;
            case itemType.平法:
                wkName = "";
                break;
            case itemType.造价识图:
                wkName = "GZst";
                break;
            case itemType.装配式:
                wkName = "ZPS";
                break;
            case itemType.建筑电气施工:
                wkName = "GRaz";
                break;
            case itemType.桥梁工程:
                wkName = "QLGC";
                break;
            case itemType.道桥识图:
                wkName = "";
                break;
            case itemType.隧道工程:
                wkName = "SGGY+GZRZ+WYFJ";
                break;
            default:
                break;
        }
        return wkName;
    }

    #endregion

    #region 调用打包工具
    private static string FilePath = @"F:\workspace\PythonTest\PythonCallHardware\venv\Scripts\python.exe";
    // [MenuItem("PublishTools/制作版本号",false,2)]
    private static void CallBuildTool ()
    {
    
    
        string file = @"F:/workspace/PythonTest/PythonCallHardware/Scripts/CallBuildTools.py";
        ProcessStartInfo start = new ProcessStartInfo ();
        start.FileName = FilePath;
        start.Arguments = file + " " + currentItemType;
        start.UseShellExecute = false;
        //参数用空格分隔
        //start.Arguments = path + " " + type + " " + mode;
        start.RedirectStandardOutput = true;
        start.RedirectStandardInput = true;
        start.RedirectStandardError = true;
        start.CreateNoWindow = false;
        Process process = Process.Start (start);
    }
    #endregion
}

public class PythonCallBuild : EditorWindow
{
    
    
    #region 调用python自动化打包
    static PythonCallBuild window;
    private static itemType CurrentType = itemType.测量;
    private static bool ISWEIKE = false;
    private static bool ISHUDONG = false;
    [MenuItem ("PublishTools/调用Python自动化打包", false, 3)]
    private static void CallBuild ()
    {
    
    
        window = GetWindow<PythonCallBuild> ();
        window.autoRepaintOnSceneChange = false;
        window.maxSize = new Vector2 (430, 305);
        window.Show ();
    }


    //互动2 微课是1
    static string CurrentModeType = "1";
    private void OnGUI ()
    {
    
    
        EditorGUILayout.BeginHorizontal ();
        CurrentType = (itemType)EditorGUILayout.EnumPopup ("选择项目:", CurrentType, GUILayout.Width (300));
        EditorGUILayout.EndHorizontal ();
        GUILayout.Label ("------------------------------------------------------------------------------------------------------------------------------");
        EditorGUILayout.BeginHorizontal ();
        using (var posGroup = new EditorGUILayout.ToggleGroupScope ("类别(只能选一个)", true))
        {
    
    
            ISWEIKE = EditorGUILayout.ToggleLeft ("微课", ISWEIKE);
            ISHUDONG = EditorGUILayout.ToggleLeft ("互动", ISHUDONG);

        }

        EditorGUILayout.EndHorizontal ();
        GUILayout.Space (10);
        GUILayout.BeginHorizontal ();
        GUILayout.Label ("------------------------------------------------------------------------------------------------------------------------------");

        GUILayout.Label ("当前选择项目:");
        GUILayout.Label (CurrentType.ToString ());
        GUILayout.EndVertical ();
        if (GUILayout.Button ("开始调用", GUILayout.Width (100), GUILayout.Height (40)))
        {
    
    
            if (ISWEIKE)
                CurrentModeType = "1";
            else if (ISHUDONG)
                CurrentModeType = "2";
            else
                return;
            CallPythonExe (((int)CurrentType).ToString (), CurrentModeType);
        }
    }
    private static void CallPythonExe ( string type, string mode )
    {
    
    

        ProcessStartInfo StartInfo = new ProcessStartInfo ();
        //python脚本的路径
        string path = @"F:/workspace/PythonTest/PythonCallHardware/Scripts/CallHarware.py";
        //(注意:用的话需要换成自己的)没有配环境变量的话,可以像我这样写python.exe的绝对路径
        //(用的话需要换成自己的)。如果配了,直接写"python.exe"即可
        StartInfo.FileName = @"F:\workspace\PythonTest\PythonCallHardware\venv\Scripts\python.exe";
        //p.StartInfo.FileName = @"C:\Program Files\Python35\python.exe";

        // sArguments为python脚本的路径   python值的传递路线strArr[]->teps->sigstr->sArguments 
        //传递参数时 每个参数需要用空格 隔开
        //在python中用sys.argv[ ]使用该参数
        StartInfo.UseShellExecute = false;
        StartInfo.Arguments = path + " " + type + " " + mode;
        StartInfo.RedirectStandardOutput = true;
        StartInfo.RedirectStandardInput = true;
        StartInfo.RedirectStandardError = true;
        StartInfo.CreateNoWindow = false;
        Process process = Process.Start (StartInfo);
        //process.OutputDataReceived += new DataReceivedEventHandler (Out_RecvData);
        StreamReader reader = process.StandardOutput;
        string result = "";
        while (result != null)
        {
    
    
            result = reader.ReadLine ();
            if (string.IsNullOrEmpty (result))
                break;
            UnityEngine.Debug.Log (result.ToString ());
        }
    }

    //class ProjectType(enum.Enum):
    //'''
    //项目类别
    //'''
    //CeLiang = 1
    //GongYi = 2
    //GCLX = 3
    //AnZhuangShiTu = 4
    //ZhuangPeiShi = 5
    //PingFa = 6
    //JingZhuangXiu = 7
    //GouZhao = 8
    //AnQuanWenMingGongDi = 9
    //JiLiangJiJia = 10
    //DaoLuGongCheng = 11
    //QiangLiangGongCheng = 12
    //ShouGongSuanLiang = 13
    //GangJieGou=14,
    //# 建筑电气施工
    //JianZhuDianQiShiGong=15,
    //DaqQiaoShiTu=16,
    //SuiDaoGongCheng=17,
    //# 不确定
    //GongChengShiTu=18,
    #endregion

    static void Out_RecvData ( object sender, DataReceivedEventArgs e )
    {
    
    
        if (!string.IsNullOrEmpty (e.Data))
        {
    
    
            UnityEngine.Debug.Log (e.Data);
        }
    }



}
/// <summary>
/// 工具类
/// </summary>
public class PathTool
{
    
    
    public static string CombinePath ( params string[] str )
    {
    
    
        string TmpPath = str[0];
        for (int i = 0; i < str.Length; i++)
        {
    
    
            if (i != 0)
                TmpPath = Path.Combine (TmpPath, str[i]);
        }
        TmpPath = TmpPath.Replace ("\\", "/");
        return TmpPath;
    }

    public static void CreatDirectory ( string path )
    {
    
    
        if (!string.IsNullOrEmpty (path))
        {
    
    
            bool isExist = Directory.Exists (path);
            if (isExist == false)
                Directory.CreateDirectory (path);
        }
    }
}


Here is the python script

# coding=utf-8
import os
import sys
from pywinauto.application import Application

import time
import enum
# 解决报错
import warnings
warnings.simplefilter('ignore', category=UserWarning)
class AutoBuild(object):

	def __init__(self):
		self.sufFileName = ""
		self.open_SufPath = ""
		# suf 盘符位置
		self.Drive_path = "D:\工作安装包\网页版本suf"
		# 资源位置
		self.ProjectFile = 'D:\工作安装包\网页版本打包项'
		# self.CurrentType=sys.argv[1]
		self.CurrentType = 1
		self.CurrentModel = 1

	def run(self):
		self.CurrentType = int(sys.argv[1])
		self.CurrentModel = int(sys.argv[2])
		self.ProjecttypeEnum = ProjectType(self.CurrentType)
		self.modelType = ModelType(self.CurrentModel)
		print(self.ProjecttypeEnum)
		print(self.modelType)
		# 获取suf路径
		print('*' * 10)
		self.open_SufPath = self.GetSufByProject(self.ProjecttypeEnum)
		print(self.open_SufPath)
		# 打开sufdesign

		app = Application(backend='uia').start(r"F:\work\SetupFactory\SUFDesign.exe", timeout=10)
		# 把进程和当前获得句柄联系起来
		app = Application().connect(path=r"F:\work\SetupFactory\SUFDesign.exe", timeout=10)
		time.sleep(1)
		# 获取 当前的窗 通过标题
		dlg_new = app.window(title="Start a New Project")
		dlg_new.wait("ready", timeout=5)
		# dlg_spec.menu_select("File->Open")
		# 标识一下
		dlg_new.draw_outline()

		btn_cancle = dlg_new[r'Cancle']
		btn_cancle.click()
		dlg_Open = app.window(title=r"Untitled - Setup Factory")
		dlg_Open.wait("exists enabled visible ready", timeout=5)
		dlg_Open.draw_outline()

		# dlg_Open.print_control_identifiers()
		# 使用快捷键 打开suf
		dlg_Open.type_keys("^O")
		dlg_ReOpen = app.window(title="Open")
		# 找到要打开路劲的文本框
		edit = dlg_ReOpen["Edit"]
		edit.set_text(self.open_SufPath)
		time.sleep(1)
		# 快捷键 打开
		# print(dlg_ReOpen.print_control_identifiers())
		# dlg_ReOpen.type_keys("%o")
		btn_open = dlg_ReOpen.child_window(title="打开(&O)", class_name="Button")
		btn_open.click()
		dlg_Pro = app.window(title=self.sufFileName + " - Setup Factory")
		dlg_Pro.wait("ready", timeout=10)
		time.sleep(2)
		# dlg_Pro=app.window(title="Project")
		dlg_Pro.draw_outline()
		dlg_Pro.type_keys("{INS} ")
		dlg_addFile = app.window(title="Add Files to Project")
		time.sleep(2)
		dlg_addFile.draw_outline()
		dlg_addFile.child_window(title="All files in this folder and all sub folders", class_name="Button").click()
		# print(dlg_addFile.print_control_identifiers())
		# TODO  地址 获取元件 设置值  获取不到 卡在这了
		dlg_addFile.child_window(title="All Files in Tree", class_name="Edit").set_text(
			self.GetProjectSource(self.ProjecttypeEnum) + "\All file in tree")
		# dlg_addFile.child_window(title="地址",class_name="Edit").set_text(self.GetProjectSource(self.ProjecttypeEnum)+"All file in tree")
		time.sleep(2)
		btn_open = dlg_addFile.child_window(title="打开(&O)", class_name="Button")
		btn_open.click()
		time.sleep(2)
		dlg_Pro = app.window(title=self.sufFileName + " - Setup Factory")
		dlg_Pro.wait("exists enabled visible ready", timeout=10)
		# ctrl ^   enter {ENTER}或者~ ALT %
		time.sleep(1)
		dlg_Pro.get_active()
		dlg_Pro.get_focus()
		dlg_Pro.type_keys("^a")
		dlg_Pro.type_keys("^{ENTER}")
		dlg_Mul = app.window(title="Multiple File Properties", class_name="#32770")
		# dlg_Mul.wait("ready",timeout=10)

		# dlg_Mul.child_window(title="Overwrite if existing file is older", class_name="ComboBox").click()
		# print(dlg_Mul.print_control_identifiers())
		# 选择组合框中的
		dlg_Mul.ComboBoxWrapper.select("Always overwrite existing file")
		time.sleep(1)
		dlg_Mul.child_window(title="确定", class_name="Button").click()
		dlg_Pro = app.window(title=self.sufFileName + " - Setup Factory")
		dlg_Pro.draw_outline()
		time.sleep(1)
		dlg_Pro.type_keys("{F7}")
		dlg_pub = app.window(title="Publish Wizard - Select Distribution Media", class_name="#32770")
		# print(dlg_pub.print_control_identifiers())
		dlg_pub.child_window(title="&Next >", class_name='Button').click()
		dlg_pub = app.window(title="Publish Wizard - Select Output Location", class_name="#32770")
		dlg_pub.child_window(title="&Next >", class_name='Button').click()

	def GetProjectSource(self, project):
		'''
		获取要打包的资源路径
		:param project:
		:return:
		'''
		ProjectSource = self.GetProject(self.ProjectFile, project)
		if self.modelType == ModelType.WeiKe:
			ProjectSource = os.path.join(ProjectSource, self.GetProject("", project) + "微课")
		if self.modelType == ModelType.HuDong:
			ProjectSource = os.path.join(ProjectSource, self.GetProject("", project) + "互动")
		print("准备打包的资源路径%s" % ProjectSource)
		return ProjectSource

	def GetSufByProject(self, project):
		"""
		获取项目的最终suf路径
		:param project:
		:return:
		"""
		path = os.path.join(self.GetProject(self.Drive_path, project), self.GetProjectSufName(project))
		print("suf的最终路径%s" % path)
		return path

	def GetProject(self, Drive_path, project):
		'''
		获取盘符和项目路径
		:param project:
		:return:
		'''
		if project == ProjectType.CeLiang:
			return os.path.join(Drive_path, "测量")
		if project == ProjectType.GongYi:
			return os.path.join(Drive_path, "工艺")
		if project == ProjectType.GCLX:
			return os.path.join(Drive_path, "工程力学")
		if project == ProjectType.AnZhuangShiTu:
			return os.path.join(Drive_path, "安装识图")
		if project == ProjectType.ZhuangPeiShi:
			return os.path.join(Drive_path, "装配式")
		if project == ProjectType.PingFa:
			return os.path.join(Drive_path, "平法")
		if project == ProjectType.JingZhuangXiu:
			return os.path.join(Drive_path, "精装修")
		if project == ProjectType.GouZhao:
			return os.path.join(Drive_path, "构造")
		if project == ProjectType.AnQuanWenMingGongDi:
			return os.path.join(Drive_path, "安全文明工地")
		if project == ProjectType.JiLiangJiJia:
			return os.path.join(Drive_path, "计量计价")
		if project == ProjectType.DaoLuGongCheng:
			return os.path.join(Drive_path, "道路工程")
		if project == ProjectType.QiangLiangGongCheng:
			return os.path.join(Drive_path, "桥梁工程")
		if project == ProjectType.ShouGongSuanLiang:
			return os.path.join(Drive_path, "手工算量")
		if project == ProjectType.GangJieGou:
			return os.path.join(Drive_path, "钢结构")
		if project == ProjectType.JianZhuDianQiShiGong:
			return os.path.join(Drive_path, "建筑电气施工")
		if project == ProjectType.SuiDaoGongCheng:
			return os.path.join(Drive_path, "隧道工程")
		if project == ProjectType.DaqQiaoShiTu:
			return os.path.join(Drive_path, "道桥识图")
		if project == ProjectType.GongChengShiTu:
			return os.path.join(Drive_path, "工程识图")

	def GetProjectSufName(self, project):
		'''
		获取suf名称
		:param project:
		:return:
		'''
		filename = ""
		if self.modelType == ModelType.HuDong:

			if project == ProjectType.CeLiang:
				filename = "3.5hd资源.suf"
			if project == ProjectType.GongYi:
				filename = "工艺互动加速包.suf"
			if project == ProjectType.GCLX:
				filename = "工程力学互动加速包.suf"
			if project == ProjectType.AnZhuangShiTu:
				filename = "安装识图互动加速包.suf"
			if project == ProjectType.ZhuangPeiShi:
				filename = "装配式互动/Untitled.suf"
			if project == ProjectType.PingFa:
				filename = "平法互动.suf"
			if project == ProjectType.JingZhuangXiu:
				filename = "精装修互动/精装修互动.suf"
			if project == ProjectType.GouZhao:
				filename = "构造互动.suf"
			if project == ProjectType.AnQuanWenMingGongDi:
				filename = "安全文明工地.suf"
			if project == ProjectType.JiLiangJiJia:
				filename = "计量计价互动加速包.suf"
			if project == ProjectType.DaoLuGongCheng:
				filename = ""
			if project == ProjectType.QiangLiangGongCheng:
				filename = ""
			if project == ProjectType.ShouGongSuanLiang:
				filename = ""
			if project == ProjectType.GangJieGou:
				filename = "3.5WK资源.suf"
			if project == ProjectType.JianZhuDianQiShiGong:
				filename = ""
			if project == ProjectType.DaqQiaoShiTu:
				filename = ""
			if project == ProjectType.SuiDaoGongCheng:
				filename = ""
			if project == ProjectType.GongChengShiTu:
				filename = ""
		if self.modelType == ModelType.WeiKe:
			if project == project.CeLiang:
				filename = "3.5资源.suf"
			if project == ProjectType.GongYi:
				filename = "工艺微课加速包.suf"
			if project == ProjectType.GCLX:
				filename = "工程力学微课加速包.suf"
			if project == ProjectType.AnZhuangShiTu:
				filename = "安装识图微课加速包.suf"
			if project == ProjectType.ZhuangPeiShi:
				filename = "装配式微课/Untitled.suf"
			if project == ProjectType.PingFa:
				filename = ""
			if project == ProjectType.JingZhuangXiu:
				filename = "精装修微课/精装修微课.suf"
			if project == ProjectType.GouZhao:
				filename = "构造微课.suf"
			if project == ProjectType.AnQuanWenMingGongDi:
				filename = ""
			if project == ProjectType.JiLiangJiJia:
				filename = "计量计价微课加速包.suf"
			if project == ProjectType.DaoLuGongCheng:
				filename = ""
			if project == ProjectType.QiangLiangGongCheng:
				filename = ""
			if project == ProjectType.ShouGongSuanLiang:
				filename = ""
			if project == ProjectType.GangJieGou:
				filename = "3.5hd资源.suf"
			if project == ProjectType.JianZhuDianQiShiGong:
				filename = ""
			if project == ProjectType.DaqQiaoShiTu:
				filename = ""
			if project == ProjectType.SuiDaoGongCheng:
				filename = ""
			if project == ProjectType.GongChengShiTu:
				filename = ""
		self.sufFileName = filename
		return filename


class ProjectType(enum.Enum):
	'''
	项目类别
	'''
	CeLiang = 1
	GongYi = 2
	GCLX = 3
	AnZhuangShiTu = 4
	ZhuangPeiShi = 5
	PingFa = 6
	JingZhuangXiu = 7
	GouZhao = 8
	AnQuanWenMingGongDi = 9
	JiLiangJiJia = 10
	DaoLuGongCheng = 11
	QiangLiangGongCheng = 12
	ShouGongSuanLiang = 13
	GangJieGou = 14,
	# 建筑电气施工
	JianZhuDianQiShiGong = 15,
	DaqQiaoShiTu = 16,
	SuiDaoGongCheng = 17,
	# 不确定
	GongChengShiTu = 18,


class ModelType(enum.Enum):
	'''
	模式 互动还是微课
	'''
	WeiKe = 1
	HuDong = 2


if __name__ == '__main__':
	ab = AutoBuild()
	ab.run()

another python script

# coding=utf-8

import sys
import enum
import time
from pywinauto.application import Application
import winerror

# 解决不能运行自己做的exe的问题
import os
os.environ.update({
    
    "__COMPAT_LAYER":"RUnAsInvoker"})
# 解决报错 是32位程序需要 使用32位python.exe
import warnings
warnings.simplefilter('ignore', category=UserWarning)
class BuildVersion(object):


	def run(self):
		"""
		使用该方式用来自动化制作安装包
		:return:
		"""
		#exePath=r'L:\rgzsoft\PatchTool.exe'
		exePath = r'D:\WorkBuild\PatchTool\PatchTool.exe'
		# 选择的项目
		currentType= self.GetNameByInt(sys.argv[1])
		#currentType=self.GetNameByInt(3)
		try:
			app = Application(backend='win32').start(exePath,timeout=10)
			app=Application().connect(path=exePath,timeout=10)
			diolg = app.window(title="PatchTool")
			diolg.draw_outline()
			diolg.ComboBox.select(currentType)
			time.sleep(1)
			# diolg.child_window(title="发布版本", auto_id="release", control_type="System.Windows.Forms.Button").click()
		except BaseException as error :

			raise error

	def GetNameByInt(sefl,index):
		'''
		项目类别
		'''
		str_type=r"测量= 1," \
			r"工艺 = 2," \
			r"工程力学= 3," \
			r"安装识图 = 4," \
			r"装配式 = 5," \
			r"平法 = 6," \
			r"精装修 = 7," \
			r"构造 = 8," \
			r"安全文明工地 = 9," \
			r"计量计价 = 10," \
			r"道路工程 = 11," \
			r"桥梁工程 = 12," \
			r"手工算量 = 13," \
			r"钢结构 = 14," \
			r"建筑电气施工 = 15," \
			r"道桥识图 = 16,"\
			r"SuiDaoGongCheng = 17," \
			r"工程识图 = 18"
		index=str(index)
		pro_dic={
    
    i.split('=')[1].strip(): i.split('=')[0].strip() for i in str_type.split(',')}
		for k in pro_dic.keys():
			if k.strip() == index.strip():
				print(pro_dic[k])
				return pro_dic[k]


if __name__ == '__main__':
	buildVersion = BuildVersion()
	buildVersion.run()

If there is something wrong, please point it out. It's over!

Guess you like

Origin blog.csdn.net/m_cainiaokuaifei/article/details/103768297
Recommended