多个可执行程序协同工作

2024-03-15 14:58

本文主要是介绍多个可执行程序协同工作,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景

最近的项目涉及到一个漫游场景和多个小实验室,一开始是把小实验室和漫游场景放置在一个工程下面并且通过场景切换的方式来链接跳转。考虑到网络应用的大趋势和程序的扩展性,这样做下去实在是难以维护日渐增加的小实验室场景和逻辑。

实现

本文将实现一个大场景打开小场景并且可以跳转回大场景和功能,这个功能建立在window平台提供的Api的基础上,涉及到程序窗口的隐藏显示,初始进程参数的传递。还有一点,虽然是在unity3d开发的程序中使用,但最后实现的场景跳转控制器应该能在任何c#开发的程序中使用.

一、设计界面

目的的设计一个程序,可以打开同样的程序可以观察到实现的效果。功能按扭和显示信息的文字组合一个形成如下的一个界面程序:

点击打开子程序将弹出文件选择窗口,实现exe文件的选中,如果打开成功,这个窗口将隐藏。同时被打开的程序中的父级窗口将显示刚才隐藏窗口的句柄(用于还原隐藏的窗口)。如果点击关闭本程序,这样程序的进行将终止,同时还原隐藏的那个程序。这样不可以无缝的实现场景的切换同时兼顾应用程序的扩展性了。

二,接口设计

有了界面显示,当然想写一个通用的场景切换的控制器(Controller),需要实现的也就保存父级句柄,接收程序初始的参数,打开子窗口,关闭子窗口还有自身关闭的清理掉所打开的进程。(bool hideThis,这个变量用于不想隐藏父级窗口)

public interface IWindowSwitchCtrl {
    IntPtr Parent { get; }
    bool OnOpenedByParent(out string[] args);
    bool OpenChildWindow(string path,bool hideThis,params string[] args);
    bool CloseChildWindow();
    void OnCloseThisWindow();
}
三,实现参数传入

unity3d程序可以在程序进行的Awake中调用控制器获取参数,接口的实现部分如下(参数用空格分割,本程序中默认第三位起为用户参数)

/// <summary>
    /// 仅当第二个参数为1时,隐藏父级
    /// </summary>
    /// <param name="pwindow"></param>
    /// <param name="hideParent"></param>
    public bool OnOpenedByParent(out string[] argus)
    {
        hideParent = false;
        parentWindow = IntPtr.Zero;
        argus = null;

        string[] CommandLineArgs = Environment.GetCommandLineArgs();

        if (CommandLineArgs.Length == 1)
        {
            //无参数
            return false;
        }

        if (CommandLineArgs.Length > 1)
        {
            parentWindow = new IntPtr(int.Parse(CommandLineArgs[1]));
        }

        if (CommandLineArgs.Length > 2)
        {
            hideParent = new IntPtr(int.Parse(CommandLineArgs[2])) == (IntPtr)1;
        }

        if (CommandLineArgs.Length > 3)
        {
            argus = new string[CommandLineArgs.Length - 3];
            for (int i = 0; i < argus.Length; i++)
            {
                argus[i] = CommandLineArgs[(i + 3)];
            }
        }

        if (hideParent)
        {
            User32.ShowWindow(parentWindow, WindowShowStyle.Hide);
        }

        return true;
    }

本程序将获取到的参数将显示在对应的小框中,父级句柄显示为3540948...

四、用进程打开程序并传入参数

上面一步已经实现了接收参数的功能,下面是打开进程并传入参数的方法

/// <summary>
    /// 打开一个子窗口,并记录
    /// </summary>
    /// <param name="path"></param>
    /// <param name="hideThis"></param>
    public bool OpenChildWindow(string path, bool hideThis,params string[] args)
    {
        if (childProcess == null|| childProcess.HasExited)
        {
            if (System.IO.File.Exists(path))
            {
                ProcessStartInfo startInfo = new ProcessStartInfo(path);
                startInfo.Arguments = (WindowCalc.GetCurrProcessWnd() + " " + (hideThis ? 1 : 0).ToString()).ToString();
                for (int i = 0; i < args.Length; i++)
                {
                    startInfo.Arguments += " " + args[i];
                }
                startInfo.UseShellExecute = true;
                startInfo.WindowStyle = ProcessWindowStyle.Normal;
                childProcess = new Process();

                childProcess.StartInfo = startInfo;
                childProcess.Start();
                return true;
            }
        }
        return false;
    }

这一中先判断了文件是否存在,不存在将不会开启进行以及后续操作。一但进程开启,将对应的参数传入就可以了。同时如果需要就可将自己的窗口进行隐藏处理

五,隐藏窗口
    /// <summary>
    /// 关闭所有打开的窗口
    /// </summary>
    public void OnCloseThisWindow()
    {
        CloseChildWindow();

        if (hideParent)
        {
            User32.ShowWindow(parentWindow, WindowShowStyle.Show);
        }
    }
在关闭所打开的窗口的同时,要将上一个窗口打开,否则只能去进程管理器关程序啦。

六、Demo其他功能

  window程序开发过程中可以使用很多window自己提供的api接口可以省不少事,比如本程序中打开选择文件的窗口就是调用Comdlg32内的方法实现的


七,程序源码

github地址:https://github.com/zouhunter/WindowSwitch




这篇关于多个可执行程序协同工作的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/812344

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python实现合并与拆分多个PDF文档中的指定页

《Python实现合并与拆分多个PDF文档中的指定页》这篇文章主要为大家详细介绍了如何使用Python实现将多个PDF文档中的指定页合并生成新的PDF以及拆分PDF,感兴趣的小伙伴可以参考一下... 安装所需要的库pip install PyPDF2 -i https://pypi.tuna.tsingh

Python自动化办公之合并多个Excel

《Python自动化办公之合并多个Excel》在日常的办公自动化工作中,尤其是处理大量数据时,合并多个Excel表格是一个常见且繁琐的任务,下面小编就来为大家介绍一下如何使用Python轻松实现合... 目录为什么选择 python 自动化目标使用 Python 合并多个 Excel 文件安装所需库示例代码

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

struts2中的json返回指定的多个参数

要返回指定的多个参数,就必须在struts.xml中的配置如下: <action name="goodsType_*" class="goodsTypeAction" method="{1}"> <!-- 查询商品类别信息==分页 --> <result type="json" name="goodsType_findPgae"> <!--在这一行进行指定,其中lis是一个List集合,但