Unity 打包pc端.exe C#防止多个程序

来源:互联网 发布:sqlserver删除表字段 编辑:程序博客网 时间:2024/06/14 15:38

通过C#调用的window中自带的动态库,来防止exe重复启动,仅供小白参考


using System;
using System.Runtime.InteropServices;
using System.Threading;
using UnityEngine;


public class Exe_control : MonoBehaviour
{
    public string m_WindowClass = "UnityWndClass";


    private static Exe_control m_Instance;


    private Mutex m_Mutex;


    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);


    [DllImport("user32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);


    [DllImport("user32.dll")]
    private static extern bool IsIconic(IntPtr hWnd);


    [DllImport("user32.dll")]
    private static extern IntPtr FindWindow(string className, string windowName);


    private void Awake()
    {
        if (Exe_control.m_Instance != null)
        {
            UnityEngine.Object.Destroy(base.gameObject);
            return;
        }
        Exe_control.m_Instance = this;
        UnityEngine.Object.DontDestroyOnLoad(this);
        if (this.IsAlreadyRunning())
        {
            this.BringToFront();
            Application.Quit();
        }
    }


    private void OnApplicationQuit()
    {
        if (this.m_Mutex != null)
        {
            this.m_Mutex.ReleaseMutex();
        }
    }


    private bool IsAlreadyRunning()
    {
        bool flag;
        this.m_Mutex = new Mutex(true, Application.productName, out flag);
        if (!flag)
        {
            this.m_Mutex = null;
        }
        return !flag;
    }


    private void BringToFront()
    {
        if (string.IsNullOrEmpty(Application.productName))
        {
            return;
        }
        IntPtr value = new IntPtr(-1);
        IntPtr intPtr = Exe_control.FindWindow((!string.IsNullOrEmpty(this.m_WindowClass)) ? this.m_WindowClass : null, Application.productName);
        if (intPtr == value)
        {
            return;
        }
        if (Exe_control.IsIconic(intPtr))
        {
            Exe_control.ShowWindow(intPtr, 9);
        }
        Exe_control.SetForegroundWindow(intPtr);
    }
}


通过调用user32中的接口,完成窗口的现实和隐藏。亲测有效


思维拓展:也可以通过socket来判断,每次启动都在创建一个客户端去发送消息,如果通过socket通信连接上了服务端(服务端也是该exe创建的,详情接着看),证明已经启动了相同的exe,就关闭该exe;如果没有检查到,就创建一个服务端来接受是否后续有客户端来上报消息,即可;


会发现要想更好的更彻底的去了解Unity以及扩展其中的功能,学好C++应该是重中之重,以后会每周间断的总结最近项目中遇到的一些问题


来自一个想要了解学习更多知识的 lambert 同学。