使用Unity启动关闭进程,包括进程的挂起与继续

7 篇文章 0 订阅

使用Unity启动关闭进程,包括进程的挂起与继续

在unity的开发中,有时需要通过当前的unity程序取控制其他程序的开启与关闭,这时就需要一些进程的操作,可以参考以下的代码。
这些代码都是我根据自己的需求,从网上找的材料,然后改写的,参考的网址我会放在文章的最后。有些代码的含义我也还没有搞明白,发现问题欢迎指正。

进程访问枚举,无符号整型

public enum ProcessAccess : uint {
    /// <summary>
    /// Required to terminate a process using TerminateProcess.
    /// 需要使用TerminateProcess终止进程
    /// </summary>
    Terminate = 0x1,

    /// <summary>
    /// Required to create a thread.
    /// 需要创建一个线程
    /// </summary>
    CreateThread = 0x2,

    /// <summary>
    /// Undocumented.
    /// 未公开的;无文件证明的
    /// </summary>
    SetSessionId = 0x4,

    /// <summary>
    /// Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).
    /// 需要对进程的地址空间执行操作(参见VirtualProtectEx和WriteProcessMemory)。
    /// </summary>
    VmOperation = 0x8,

    /// <summary>
    /// Required to read memory in a process using ReadProcessMemory.
    /// 需要使用ReadProcessMemory读取进程中的内存。
    /// </summary>
    VmRead = 0x10,

    /// <summary>
    /// Required to write to memory in a process using WriteProcessMemory.
    /// 在进程中写入内存时需要使用WriteProcessMemory
    /// </summary>
    VmWrite = 0x20,

    /// <summary>
    /// Required to duplicate a handle using DuplicateHandle.
    /// 需要使用DuplicateHandle复制句柄
    /// </summary>
    DupHandle = 0x40,

    /// <summary>
    /// Required to create a process.
    /// </summary>
    CreateProcess = 0x80,

    /// <summary>
    /// Required to set memory limits using SetProcessWorkingSetSize.
    /// 需要创建一个进程
    /// </summary>
    SetQuota = 0x100,

    /// <summary>
    /// Required to set certain information about a process, such as its priority class (see SetPriorityClass).
    /// 需要设置进程的某些信息,比如它的优先级类(参见SetPriorityClass)。
    /// </summary>
    SetInformation = 0x200,

    /// <summary>
    /// Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob).
    /// 需要检索进程的某些信息,比如它的令牌、退出代码和优先级类(参见OpenProcessToken、GetExitCodeProcess、GetPriorityClass和IsProcessInJob)。
    /// </summary>
    QueryInformation = 0x400,

    /// <summary>
    /// Undocumented.
    /// 未公开的;无文件证明的
    /// </summary>
    SetPort = 0x800,

    /// <summary>
    /// Required to suspend or resume a process.
    /// 需要挂起活继续一个进程
    /// </summary>
    SuspendResume = 0x800,

    /// <summary>
    /// Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION.
    /// 需要检索进程的某些信息(参见QueryFullProcessImageName)。具有PROCESS_QUERY_INFORMATION访问权限的句柄会被自动授予PROCESS_QUERY_LIMITED_INFORMATION。
    /// </summary>
    QueryLimitedInformation = 0x1000,

    /// <summary>
    /// Required to wait for the process to terminate using the wait functions.
    /// 需要使用wait函数等待进程终止。
    /// </summary>
    Synchronize = 0x100000
}

进程管理类,可以在其他类中直接使用其中的方法

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

public class ProcessMgr  {
    [DllImport("ntdll.dll")]
    private static extern uint NtResumeProcess([In] IntPtr processHandle);

    [DllImport("ntdll.dll")]
    private static extern uint NtSuspendProcess([In] IntPtr processHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr OpenProcess(
        ProcessAccess desiredAccess,
        bool inheritHandle,
        int processId);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool CloseHandle([In] IntPtr handle);

    public static int processId;
    public static string processName;
    /// <summary>
    /// 启动进程
    /// </summary>
    /// <param name="process"></param>
    /// <param name="processStartInfo"></param>
    public static void StartProcess(Process process, ProcessStartInfo startInfo)
    {
        try
        {
            process.StartInfo = startInfo;
            process.Start();
            process.WaitForExit(1000);
            processId = process.Id;
            processName = process.ProcessName;

        }
        catch (Exception e)
        {
            return;
        }
        
    }

    /// <summary>
    /// 挂起进程
    /// </summary>
    /// <param name="processId"></param>
    public static void SuspendProcess(int processId)
    {
        IntPtr hProc = IntPtr.Zero;
        try
        {
            //得到进程的句柄
            hProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);
            if (hProc != IntPtr.Zero)
            {
                NtSuspendProcess(hProc);
            }
                
        }
        finally
        {
            // 不要忘记关闭创建的句柄
            if (hProc != IntPtr.Zero)
            { 
                CloseHandle(hProc);
            }
                
        }
    }

    /// <summary>
    /// 继续进程
    /// </summary>
    /// <param name="processId"></param>
    public static void ResumeProcess(int processId)
    {
        IntPtr hProc = IntPtr.Zero;
        try
        {
            //得到进程的句柄
            hProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);
            if (hProc != IntPtr.Zero)
            { 
                NtResumeProcess(hProc);
            }   
        }
        finally
        {
            // 不要忘记关闭创建的句柄
            if (hProc != IntPtr.Zero)
            {
                CloseHandle(hProc);
            }
        }
    }

    /// <summary>
    /// 关闭进程
    /// </summary>
    /// <param name="process"></param>
    public static void StopProcess(Process process)
    {
        try
        {
            //关闭窗口
            process.CloseMainWindow();
            //释放
            process.Close();
        }
        catch 
        {
            return;
        }
    }

}

测试类,在unity中直接测试,将测试类挂载在场景中的空物体上

using UnityEngine;
using UnityEngine.UI;
using System.Diagnostics;

public class Test : MonoBehaviour {
    //四个人控制按钮
    public Button readButton;
    public Button suspendButten;
    public Button resumeButton;
    public Button stopButton;

    ProcessStartInfo startInfo;
    Process process;
    
    //需要发开的程序的路径
    private string fileName;
    void Start () {
		fileName = @"C:\Users\ZLYaL\Desktop\Build\Inject.exe";
        
        startInfo = new ProcessStartInfo();
        process = new Process();

        startInfo.UseShellExecute = false;
        startInfo.FileName = fileName;
        startInfo.CreateNoWindow = false;
        startInfo.WindowStyle = ProcessWindowStyle.Maximized;

        readButton.onClick.AddListener(() =>
       {
           UnityEngine.Debug.Log("程序开始");
           ProcessMgr.StartProcess(process, startInfo);
       });

        suspendButten.onClick.AddListener(() =>
        {
            UnityEngine.Debug.Log("程序挂起");
            ProcessMgr.SuspendProcess(ProcessMgr.processId);
        });

        resumeButton.onClick.AddListener(() =>
        {
            UnityEngine.Debug.Log("程序继续");
            ProcessMgr.ResumeProcess(ProcessMgr.processId);
        });

        stopButton.onClick.AddListener(() =>
      {
          UnityEngine.Debug.Log("程序结束");
          ProcessMgr.StopProcess(process);
      });
    }
	
}

测试使用的UI布局
UI布局
参考网址:
挂起与继续的参考网址
https://www.cnblogs.com/crwy/p/6622319.html
Process类的官方解释,开始与停止参考的官方文档
https://docs.microsoft.com/zh-cn/dotnet/api/system.diagnostics.process?view=net-5.0

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值