工作中资源更新需要重复行操作软件,这不符合程序的一贯作风,所以使用pywinauto 这个python 模块,实现自动化操作软件。只需鼠标一点,就可以不用管了。是不是很方便。
1当前的需求: 技术人员在每次资源更新的时候,需要重复操作软件来进行版本号的制作,安装包的制作,希望减少这种工作量。
2 用到的工具 pycharm + Unity
1我需要在Unity中 将更新的资源按照选定的项目 复制到 指定的文件夹中
2使用exe制作版本号及资源列表。
3使用SUFDesign 软件进行安装包制作。
复制这部分直接跳过,个人需要注意的点
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 ();
}
Unity并不能执行python脚本,C#是编译型语言,需要先编译,python是解释型语言,直接就可以运行 但是需要解释器,我使用的就是python3.7,安装pycharm 还有Anaconda
Unity开启一个线程 调用解释器 然后解释器执行py 脚本,py脚本进行自动化操作,这就是整个流程。
#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
和我们使用CMD一样 使用某一软件执行文件,
start.FileName = FilePath;参数是解释器的位置
start.Arguments = file + " " + currentItemType;第一个参数是文件位置 ,第二个是我选择的项目类型
注意参数之间是用空格隔开
我在使用的时候 我一般使用conda 来下载模块包 但是这个模块使用conda 是不能下载的 我是用的pip下载的 当然最后我使用的不是conda安装时的编译器。
1我们如何在脚本中获取 传递过来的参数
我们使用 sys 模块 sys.argv[1]是第一个参数 一次类推
self.CurrentType = int(sys.argv[1]))
self.CurrentModel = int(sys.argv[2])
2 如果判断类型呢
我们使用enum枚举
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,
我们在使用的时候 可以 吧数字对应成 项目名 使用
self.modelType = ModelType(self.CurrentModel)
3 最重要的来了 pywinauto模块
我们需要判断当前软件窗口的类型 uia 还是win32
链接:https://pan.baidu.com/s/1VQv_SKGGCHwVZIqxa5iyMQ
提取码:x5nt
确定之后 使用模块调用软件创建联系
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)
都可以通过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() 在窗体的周边划线
找到按钮进行点击
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")
对应快捷键的写法
我遇到的问题 就是选择combobox里面的选项
# 选择组合框中的
dlg_Mul.ComboBoxWrapper.select("Always overwrite existing file")
4 在使用pywinauto 的时候 报错 坑了很久 是程序是32的 而我使用的是64位python.exe
# 解决不能运行自己做的exe的问题
import os
os.environ.update({"__COMPAT_LAYER":"RUnAsInvoker"})
# 解决报错 是32位程序需要 使用32位python.exe
import warnings
warnings.simplefilter('ignore', category=UserWarning)
在使用过程中 需要不断的试错 适当的时候让程序sleep 因为没有程序没有完全打开 脚本就不能进行下去
我们可以获取当前焦点
dlg_Pro.get_active()
dlg_Pro.get_focus()
SUFDesign 就是这样
下附全部脚本
Unity C#
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System.Diagnostics;
///
/// 将I盘下的各个工程的资源和播放器移动到H盘下 方便制作安装包
///
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:/工作安装包/网页版本打包项";
///
/// 目的资源路径
///
private static string Source_player_module = "module";
private static string Source_weike = @"WeiKe/WKPlayerResources/WKAssets";
///
/// 当前资源路径
///
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 ("复制完成{0} ", currentItemType));
}
///
/// 复制选择的文件夹
///
/// 源文件路径
/// 目标文件路径
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 ();
}
///
/// 复制全部的文件夹
///
///
///
private static void CopyMultipleDirectory ()
{
}
///
/// 获得互动名称
///
///
///
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;
}
///
/// 获得wk名称
///
///
///
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);
}
}
}
///
/// 工具类
///
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);
}
}
}
这是python脚本
# 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()
另一个python脚本
# 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()
如果有哪里写的不对 欢迎指出来。完了!