介绍
在unity中实现一种程序检测,当Unity启动后,判断另外一个程序是否启动,如果启动则不处理,未启动 则关闭unity,
- 判断要判断的文件名和文件路径是否正确,避免程序内部出错
- 获取全部的程序名称判断需要检测的程序是否启动
- 根据路径判断,是不是要启动的那个程序,避免重名的程序
警告
第三种未能正确实现,原因暂时没有找到。若要尝试仅需将注释的宏命令解除注释即可。
文件需要是两行,第一行是要检测的文件名,第二行是要检测的程序的路径,但是因为功能未能实现,所以对错都可以,但是要有。
若要尝试第三种需要解除注释的位置包括
1.
//#if !UNITY_EDITOR
// Set_processExePath_Long(processInfoLines);
//#endif
2. //#if !UNITY_EDITOR
//bFilePath = System.AppDomain.CurrentDomain.BaseDirectory
// + Application.productName + "_Data"
// + "/StreamingAssets/"
// + processNamePath;
// txt.text = txt.text + "bFilePath_AppDomain:"+bFilePath + "\n";
// lineCount = 0;
// using (StreamReader sr = new StreamReader(bFilePath))
// {
// while (sr.ReadLine() != null)
// {
// lineCount++;
// }
// }
// if (lineCount == 2)
// {
// return isGetCheckIfProcessInfo = true;
// }
//#endif
3.
//#if !UNITY_EDITOR
// SameNameCheck(processes);
//#endif
代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Unity.VisualScripting;
using UnityEngine;
using Debug = UnityEngine.Debug;
public class NewBehaviourScript : MonoBehaviour
{
[DllImport("User32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern int MessageBox(IntPtr handle, string message, string title, int type, Action action = null);
private string processNamePath = "B.txt";//需要读取的文件的名称的路径
private string processName = "";//要检测的程序名
private string processExePath_Short = "";//被检查程序的名称的相对路径,
string processExePath_Long = "";//要被检测程序的绝对路径
void Start()
{
if (!GetCheckIfProcessInfo())
{
MyQuiitMessageBox("警告", "程序内部检测文件配置错误,联系管理员!_1");
return;
}
string[] processInfoLines = new string[] {"","" };//用于存储读取到的字符串
using (StreamReader sr = new StreamReader(bFilePath))
{
int index = 0;
string line = "";
while ((line = sr.ReadLine()) != null)
{
processInfoLines[index] = line;
index = index + 1;
}
}
//假如文件名加.exe了就将.exe去掉,同时去掉空格
for (int i = 0; i < processInfoLines.Length; i++)
{
if (processInfoLines[i].EndsWith(".exe"))
{
processInfoLines[i] = processInfoLines[i].Replace(" ", "").Substring(0, processInfoLines[i].Length - 4);
}
}
//处理字符串
processName = processInfoLines[0];
if (processName.StartsWith(@"\"))
{
processName = processName.Replace(@"\", "");//处理后赋值
}
//#if !UNITY_EDITOR
// Set_processExePath_Long(processInfoLines);
//#endif
InvokeRepeating(nameof(CheckIfProcessRunning), 3f, 5f);//第一次延迟3S,之后每5s一次开始检测启动程序
}
//对路径进行判断
private void Set_processExePath_Long(string[] lines)
{
processExePath_Short = lines[1];
if (!processExePath_Short.StartsWith(@"\"))//判断是不是"\"开头
{
processExePath_Short = @"\" + processExePath_Short;
}
if (!processExePath_Short.EndsWith(@"\"))判断是不是"\"结尾,允许出错
{
processExePath_Short = processExePath_Short + @"\";
}
processExePath_Long = System.AppDomain.CurrentDomain.BaseDirectory;//C:\Users\bin\Debug\
processExePath_Long = processExePath_Long.Replace(processExePath_Short, "");
processExePath_Long = processExePath_Long + @"\" + processName + ".exe";//赋值
}
private string bFilePath = "";
/// <summary>
/// 获取需要检测的配置文件的信息是否正确
/// 先判断是不是1行
/// </summary>
private bool GetCheckIfProcessInfo()
{
bool isGetCheckIfProcessInfo = false;//有读到信息么?
if (processNamePath.StartsWith(@"\"))
{
processNamePath = processNamePath.Remove(0, 1);
}
bFilePath = Path.Combine(Application.streamingAssetsPath, processNamePath);//假设要读取的文件在streamingAssets下
int lineCount = 0;//总行数
using (StreamReader sr = new StreamReader(bFilePath))
{
while (sr.ReadLine() != null)
{
lineCount++;
}
}
if (lineCount == 2)
{
return isGetCheckIfProcessInfo = true;
}
//#if !UNITY_EDITOR
//bFilePath = System.AppDomain.CurrentDomain.BaseDirectory
// + Application.productName + "_Data"
// + "/StreamingAssets/"
// + processNamePath;
// txt.text = txt.text + "bFilePath_AppDomain:"+bFilePath + "\n";
// lineCount = 0;
// using (StreamReader sr = new StreamReader(bFilePath))
// {
// while (sr.ReadLine() != null)
// {
// lineCount++;
// }
// }
// if (lineCount == 2)
// {
// return isGetCheckIfProcessInfo = true;
// }
//#endif
return isGetCheckIfProcessInfo = false;
}
/// <summary>
/// 检测启动程序
/// </summary>
void CheckIfProcessRunning()
{
Process[] processes = Process.GetProcessesByName(processName);
if (processes.Length == 0)//没有检测到
{
Debug.Log("程序未启动");
MyQuiitMessageBox("警告", "未检测到" + processName + "程序启动,程序退出_2");
}
else
{
//一般情况可以将else里的代码删除,这里是因为是固定的路径所以需要加上
//#if !UNITY_EDITOR
// SameNameCheck(processes);
//#endif
}
}
/// <summary>
/// 假如是相同的名称但是路径不正确也需要关闭
/// 被用到了啊喂喂喂
/// </summary>
/// <param name="processes"></param>
private void SameNameCheck(Process[] processes)
{
//检测到了,判断是不是要被检测的,避免同名
bool isfound = false;//有没有找到
foreach (Process process in processes)
{
string path = process.MainModule.FileName;//返回值参考:C:\Windows\System32\notepad.exe
if (path.Equals(@processExePath_Long, StringComparison.OrdinalIgnoreCase))//找到找到了
{
isfound = true;
break;
}
}
if (isfound == false)//没有找到
{
Debug.Log("程序了,但是是重名的");
MyQuiitMessageBox("警告", "未检测到" + processName + "程序启动,程序退出_3");
}
}
/// <summary>
/// 退出的提示的UI
/// </summary>
/// <param name="title">标题</param>
/// <param name="content">提示的内容</param>
private void MyQuiitMessageBox(string title, string content)
{
//没有检测到就退出
MessageBox(IntPtr.Zero, content, title, (int)0x000000L, () =>
{
ProgramExit();
});
}
/// <summary>
/// 在编辑器下退出,再发布后退出
/// </summary>
private void ProgramExit()
{
#if UNITY_EDITOR
Debug.Log("未检测到启动程序,程序退出!");
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}