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