如何从另一个应用程序中取消隐藏一个控制台应用程序

本文关键字:应用程序 控制台 一个 取消 另一个 隐藏 | 更新日期: 2023-09-27 18:27:55

我有一个在后台运行的应用程序(控制台应用程序是隐藏的)。我想说的是,如果用户试图打开这个应用程序的多个实例(点击*.exe文件),新的实例将被关闭,并显示当前运行的实例。

这就是我尝试过的:

[DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();
    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    const int SW_HIDE = 0;
    const int SW_SHOW = 5;

bool moreThanOne = false;
        string processName = System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location);
        System.Diagnostics.Process[] arr = System.Diagnostics.Process.GetProcesses();
        Console.WriteLine("Looking for: " + processName);
        foreach (var a in arr)
        {
            Console.WriteLine(a.ProcessName);
            if (a.ProcessName == processName)
            {
                Console.WriteLine("---------------------------------");
                if (moreThanOne)
                {
                    IntPtr handle = a.MainWindowHandle;
                    ShowWindow(handle, SW_SHOW);
                    Console.WriteLine("close!!!!1111");
                    Environment.Exit(0);
                }
                else
                {
                    moreThanOne = true;
                }
            }
        }

它目前不起作用,我不知道为什么。进程总是能正确找到,但"取消隐藏"以前打开的应用程序有一些问题。我做错什么了吗?

如何从另一个应用程序中取消隐藏一个控制台应用程序

为了避免用户两次启动应用程序,最好使用Mutex,而不是检查进程列表(如果另一个用户再次启动您的应用程序,而第一个用户没有查看该应用程序的权限,则显示该图像)。

你的Main变成那样(使用winform)

[STAThread]
    static void Main()
    {
        try
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
            using (new SingleGlobalInstance(TIMEOUT_START))
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                _mainProgram = new frmMainProgram();
                ApplicationContext appCtx = new ApplicationContext(_mainProgram);
                Application.Run(appCtx);
            }
        }
        catch (Exception unhandled)
        {
            Program.UnhandledExceptionHandler(null, (new UnhandledExceptionEventArgs(unhandled, true)));
        }
    }

然后是隐藏互斥逻辑的对象

public class SingleGlobalInstance : IDisposable
{
    public bool hasHandle = false;
    Mutex mutex;
    private void InitMutex()
    {
        string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
        string mutexId = string.Format("Global''{{{0}}}", appGuid);
        mutex = new Mutex(false, mutexId);
        var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
        var securitySettings = new MutexSecurity();
        securitySettings.AddAccessRule(allowEveryoneRule);
        mutex.SetAccessControl(securitySettings);
    }
    public SingleGlobalInstance(int timeOut)
    {
        InitMutex();
        try
        {
            if (timeOut < 0)
                hasHandle = mutex.WaitOne(Timeout.Infinite, false);
            else
                hasHandle = mutex.WaitOne(timeOut, false);
            if (hasHandle == false)
                throw new TimeoutException("Timeout waiting for exclusive access on SingleInstance");
        }
        catch (AbandonedMutexException)
        {
            hasHandle = true;
        }
    }

    public void Dispose()
    {
        if (mutex != null)
        {
            if (hasHandle)
                mutex.ReleaseMutex();
            mutex.Dispose();
        }
    }
}

如果您需要获得超时,您可以在此处抛出特殊异常,并在退出(从获得超时的应用程序)之前取消隐藏隐藏的应用程序