C# 設定程式只能執行一次

C# 設定程式只能執行一次

C# 設定程式只能執行一次

 


資料來源:http://blog.xuite.net/gbisland/csharp/13497681-%E5%A6%82%E4%BD%95%E9%99%90%E5%88%B6%E7%A8%8B%E5%BC%8F%E5%8F%AA%E5%9F%B7%E8%A1%8C%E4%B8%80%E6%AC%A1

http://www.go4expert.com/articles/hiding-windows-c-sharp-t973/


.NET6之前

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;

using System.Diagnostics;               // For prcesss related information
using System.Runtime.InteropServices;   // For DLL importing 

namespace CS_Forms_OnlyOne
{
    static class Program
    {
        /*
        SW_HIDE             0
        SW_SHOWNORMAL       1
        SW_NORMAL           1
        SW_SHOWMINIMIZED    2
        SW_SHOWMAXIMIZED    3
        SW_MAXIMIZE         3
        SW_SHOWNOACTIVATE   4
        SW_SHOW             5
        SW_MINIMIZE         6
        SW_SHOWMINNOACTIVE  7
        SW_SHOWNA           8
        SW_RESTORE          9
        SW_SHOWDEFAULT      10
        SW_FORCEMINIMIZE    11
        SW_MAX              11
        */
        private const int SW_HIDE = 0;
        private const int SW_MINIMIZE = 6;
        private const int SW_SHOWNORMAL = 1;
        [DllImport("User32")]
        public static extern int ShowWindow(int hwnd, int nCmdShow);


 
        /// <summary>
        /// 應用程式的主要進入點。
        /// </summary>
        [STAThread]
        static void Main()
        {
			//---
            //判斷應用程式是否己經開啟?
            //http://blog.xuite.net/gbisland/csharp/13497681-%E5%A6%82%E4%BD%95%E9%99%90%E5%88%B6%E7%A8%8B%E5%BC%8F%E5%8F%AA%E5%9F%B7%E8%A1%8C%E4%B8%80%E6%AC%A1
            if((Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1))
            {
                int hWnd;
                MessageBox.Show("應用程式 "+Process.GetCurrentProcess().ProcessName + " 己在執行中,請先關閉舊視窗。Application already execution, please close old form.",Application.ProductName, MessageBoxButtons.OK,MessageBoxIcon.Warning);


 
                //http://www.go4expert.com/articles/hiding-windows-c-sharp-t973/
                Process[] processRunning = Process.GetProcesses();
                foreach (Process pr in processRunning)
                {
                    if (pr.ProcessName == Process.GetCurrentProcess().ProcessName)
                    {
                        hWnd = pr.MainWindowHandle.ToInt32();
                        ShowWindow(hWnd, SW_SHOWNORMAL);
                    }
                }
               
                Application.Exit();
                return;
            }
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
			//---判斷應用程式是否己經開啟?
			
            Application.Run(new Form1());
        }
    }
}

.NET6

using System.Diagnostics;// For prcesss related information
using System.Runtime.InteropServices;// For DLL importing 

namespace CS_Forms_OnlyOne
{
    internal static class Program
    {
        /*
        SW_HIDE             0
        SW_SHOWNORMAL       1
        SW_NORMAL           1
        SW_SHOWMINIMIZED    2
        SW_SHOWMAXIMIZED    3
        SW_MAXIMIZE         3
        SW_SHOWNOACTIVATE   4
        SW_SHOW             5
        SW_MINIMIZE         6
        SW_SHOWMINNOACTIVE  7
        SW_SHOWNA           8
        SW_RESTORE          9
        SW_SHOWDEFAULT      10
        SW_FORCEMINIMIZE    11
        SW_MAX              11
        */
        private const int SW_HIDE = 0;
        private const int SW_MINIMIZE = 6;
        private const int SW_SHOWNORMAL = 1;
        [DllImport("User32")]
        public static extern int ShowWindow(int hwnd, int nCmdShow);

        [STAThread]
        static void Main()
        {
            //---
            //判斷應用程式是否己經開啟?
            //http://blog.xuite.net/gbisland/csharp/13497681-%E5%A6%82%E4%BD%95%E9%99%90%E5%88%B6%E7%A8%8B%E5%BC%8F%E5%8F%AA%E5%9F%B7%E8%A1%8C%E4%B8%80%E6%AC%A1
            if ((Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1))
            {
                int hWnd;
                MessageBox.Show("應用程式 " + Process.GetCurrentProcess().ProcessName + " 己在執行中,請先關閉舊視窗。Application already execution, please close old form.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);



                //http://www.go4expert.com/articles/hiding-windows-c-sharp-t973/
                Process[] processRunning = Process.GetProcesses();
                foreach (Process pr in processRunning)
                {
                    if (pr.ProcessName == Process.GetCurrentProcess().ProcessName)
                    {
                        hWnd = pr.MainWindowHandle.ToInt32();
                        ShowWindow(hWnd, SW_SHOWNORMAL);
                    }
                }

                Application.Exit();
                return;
            }
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //---判斷應用程式是否己經開啟?

            ApplicationConfiguration.Initialize();
            Application.Run(new Form1());
        }
    }
}


4 thoughts on “C# 設定程式只能執行一次

  1. C# Console BAT 命令模式 程式 只能執行一次

    //---
    //程式重複執行防呆機制
    //http://blog.xuite.net/gbisland/csharp/13497681-%E5%A6%82%E4%BD%95%E9%99%90%E5%88%B6%E7%A8%8B%E5%BC%8F%E5%8F%AA%E5%9F%B7%E8%A1%8C%E4%B8%80%E6%AC%A1
    if ((Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1))
    {
    //http://www.go4expert.com/articles/hiding-windows-c-sharp-t973/
    Process[] processRunning = Process.GetProcesses();
    foreach (Process pr in processRunning)
    {
    if (pr.ProcessName == Process.GetCurrentProcess().ProcessName)
    {
    ShowWindow(pr.MainWindowHandle, SW_SHOWNORMAL);
    }
    }

    Environment.Exit(0);
    return;
    }
    //---程式重複執行防呆機制

  2. C# MAUI 專案 如何確保只能被執行一次

    //---
    //.net MAUI how to maximize application on startup
    //https://stackoverflow.com/questions/72128525/net-maui-how-to-maximize-application-on-startup
    using Microsoft.Maui.LifecycleEvents;
    using CommunityToolkit.Maui;
    using UraniumUI;
    using UraniumUI.Material;
    using System.Text;

    #if WINDOWS
    using Microsoft.UI;
    using Microsoft.UI.Windowing;
    using Windows.Graphics;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    #endif
    //---.net MAUI how to maximize application on startup

    using Microsoft.Extensions.Logging;

    namespace VPOS
    {
    public static class MauiProgram
    {
    //https://blog.csdn.net/sensor_WU/article/details/139041024
    private const int PROCESS_DPI_UNAWARE = 0;//非感知DPI。应用程序不会根据 DPI 的变化进行缩放,并始终假定缩放系数为 100% (96 DPI)。在任何其他 DPI 设置下,系统都会自动缩放
    private const int PROCESS_SYSTEM_DPI_AWARE = 1;//支持系统 DPI。应用程序不会根据 DPI 的变化进行缩放。它会查询一次 DPI,并在应用程序的整个生命周期中使用该值。如果 DPI 发生变化,应用程序不会根据新的 DPI 值进行调整。当 DPI 与系统值相比发生变化时,系统会自动放大或缩小该应用。
    private const int PROCESS_PER_MONITOR_DPI_AWARE = 2;//支持每个显示器的 DPI。此应用程序在创建时会检查 DPI,并在 DPI 发生变化时调整缩放因子。系统不会自动缩放这些应用程序。
    /*
    SW_HIDE 0
    SW_SHOWNORMAL 1
    SW_NORMAL 1
    SW_SHOWMINIMIZED 2
    SW_SHOWMAXIMIZED 3
    SW_MAXIMIZE 3
    SW_SHOWNOACTIVATE 4
    SW_SHOW 5
    SW_MINIMIZE 6
    SW_SHOWMINNOACTIVE 7
    SW_SHOWNA 8
    SW_RESTORE 9
    SW_SHOWDEFAULT 10
    SW_FORCEMINIMIZE 11
    SW_MAX 11
    */
    private const int SW_HIDE = 0;
    private const int SW_MINIMIZE = 6;
    private const int SW_SHOWNORMAL = 1;
    private const int SW_MAXIMIZE = 3;
    #if WINDOWS
    [DllImport("Shcore.dll")]
    static extern int SetProcessDpiAwareness(int awareness);

    [DllImport("User32")]
    public static extern int ShowWindow(int hwnd, int nCmdShow);
    #endif

    public static MauiApp CreateMauiApp()
    {
    var builder = MauiApp.CreateBuilder();
    builder
    .UseMauiApp()
    .UseMauiCommunityToolkit()
    .UseUraniumUI()//URANIUM UI
    .UseUraniumUIMaterial()//URANIUM UI
    .ConfigureFonts(fonts =>
    {
    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
    });

    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);//載入.net Big5編解碼函數庫(System.Text.Encoding.CodePages)
    //---
    //.net MAUI how to maximize application on startup
    https://stackoverflow.com/questions/72128525/net-maui-how-to-maximize-application-on-startup
    #if WINDOWS
    //---
    //程式啟動時,先檢查VATU.exe是否執行,VATU.exe執行中VPOS關閉
    foreach (var process in Process.GetProcessesByName("VATU"))
    {
    System.Environment.Exit(0);//關閉應用程式
    }
    //---程式啟動時,先檢查VATU.exe是否執行,VATU.exe執行中VPOS關閉

    String StrPath = (MainPage.m_blnParentDir) ? Directory.GetParent(LogFile.m_StrSysPath.Substring(0, LogFile.m_StrSysPath.Length - 1)).FullName + "\\" : LogFile.m_StrSysPath;

    //---
    //程式啟動時,檢查 vatu.script檔案中,是否有等待更新的清單。
    String Strvatu_script = "";
    if (File.Exists(StrPath + "vatu.script"))
    {
    StreamReader sr = new StreamReader(StrPath + "vatu.script");
    Strvatu_script = sr.ReadLine();
    sr.Close();// 關閉串流

    }
    //---程式啟動時,檢查 vatu.script檔案中,是否有等待更新的清單。

    //---
    //若有,則呼叫[VATU.exe]更新程式,並且待入參數為 RUN_UPDATE,此時便將 VTPOS程式進行關閉。
    if (Strvatu_script.Trim().Length>4)
    {
    if((Process.GetProcessesByName("VATU").Length==0) && (File.Exists(StrPath + "vpos.vlcs")))
    {
    String StrVLCS = StringEncrypt.AesDecrypt(FileLib.ReadTxtFile("vpos.vlcs"));
    VLCS VLCSBuf = JsonClassConvert.VLCS2Class(StrVLCS);//執行取得認證資訊
    if( VLCSBuf != null )
    {
    ProcessStartInfo start = new ProcessStartInfo();
    start.FileName = StrPath + "VATU.exe";
    start.Arguments = $"RUN_UPDATE {VLCSBuf.terminal_sid} {VLCSBuf.api_token}";
    start.UseShellExecute = false;
    start.RedirectStandardOutput = false;
    start.UseShellExecute = true;
    start.WindowStyle = ProcessWindowStyle.Normal;
    Process p01 = Process.Start(start);
    }

    }

    System.Environment.Exit(0);//關閉應用程式
    }
    //---若有,則呼叫[VATU.exe]更新程式,並且待入參數為 RUN_UPDATE,此時便將 VTPOS程式進行關閉。

    //---
    //程式啟動時,先檢查是否有[VATU.tmp]檔案,若有則先將刪除[VATU.exe]後,將[VATU.tmp]修改成[VATU.exe]
    if (File.Exists(StrPath+ "VATU.tmp"))
    {
    File.Delete(StrPath + "VATU.exe");
    File.Move(StrPath + "VATU.tmp", StrPath + "VATU.exe");
    }
    //---程式啟動時,先檢查是否有[VATU.tmp]檔案,若有則先將刪除[VATU.exe]後,將[VATU.tmp]修改成[VATU.exe]

    //---
    //判斷應用程式是否己經開啟?
    //http://blog.xuite.net/gbisland/csharp/13497681-%E5%A6%82%E4%BD%95%E9%99%90%E5%88%B6%E7%A8%8B%E5%BC%8F%E5%8F%AA%E5%9F%B7%E8%A1%8C%E4%B8%80%E6%AC%A1
    if ((Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1))
    {
    int hWnd;
    //http://www.go4expert.com/articles/hiding-windows-c-sharp-t973/
    Process[] processRunning = Process.GetProcesses();
    foreach (Process pr in processRunning)
    {
    if (pr.ProcessName == Process.GetCurrentProcess().ProcessName)
    {
    hWnd = pr.MainWindowHandle.ToInt32();
    //ShowWindow(hWnd, SW_MAXIMIZE);
    }
    }

    System.Environment.Exit(0);//關閉應用程式
    }
    //---判斷應用程式是否己經開啟?

    builder.ConfigureLifecycleEvents(events =>
    {
    events.AddWindows(wndLifeCycleBuilder =>
    {
    wndLifeCycleBuilder.OnWindowCreated(window =>
    {
    IntPtr nativeWindowHandle = WinRT.Interop.WindowNative.GetWindowHandle(window);
    WindowId win32WindowsId = Win32Interop.GetWindowIdFromWindow(nativeWindowHandle);
    AppWindow winuiAppWindow = AppWindow.GetFromWindowId(win32WindowsId);

    SetProcessDpiAwareness(PROCESS_DPI_UNAWARE);
    winuiAppWindow.Move(new Windows.Graphics.PointInt32(0, 0)); //C# MAUI WINDOWS 程式指定視窗起始位置

    if(winuiAppWindow.Presenter is OverlappedPresenter p)
    {
    p.Maximize();
    }

    //---
    //[Windows] How to completely hide the TitleBar?
    //https://github.com/dotnet/maui/issues/15142
    //https://www.cnblogs.com/whuanle/p/17060473.html [疯狂吐槽 MAUI 以及 MAUI 入坑知识点]
    window.ExtendsContentIntoTitleBar = false;
    // 保留任务栏
    switch (winuiAppWindow.Presenter)
    {
    case Microsoft.UI.Windowing.OverlappedPresenter overlappedPresenter:
    overlappedPresenter.SetBorderAndTitleBar(false, false);
    overlappedPresenter.Maximize();
    break;
    }
    // 全屏时去掉任务栏
    winuiAppWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
    //---[Windows] How to completely hide the TitleBar?
    });
    });
    });
    #endif
    //---.net MAUI how to maximize application on startup
    #if DEBUG
    builder.Logging.AddDebug();
    #endif

    return builder.Build();
    }
    }
    }

  3. C# Avalonia 專案 如何確保只能被執行一次


    using Avalonia;
    using System;
    using System.Diagnostics;

    namespace VPOS_Avalonia
    {
    internal sealed class Program
    {
    // Initialization code. Don't use any Avalonia, third-party APIs or any
    // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
    // yet and stuff might break.
    [STAThread]
    public static void Main(string[] args)
    {
    //---
    //判斷應用程式是否己經開啟?
    //http://blog.xuite.net/gbisland/csharp/13497681-%E5%A6%82%E4%BD%95%E9%99%90%E5%88%B6%E7%A8%8B%E5%BC%8F%E5%8F%AA%E5%9F%B7%E8%A1%8C%E4%B8%80%E6%AC%A1
    if ((Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1))
    {
    int hWnd;
    //http://www.go4expert.com/articles/hiding-windows-c-sharp-t973/
    Process[] processRunning = Process.GetProcesses();
    foreach (Process pr in processRunning)
    {
    if (pr.ProcessName == Process.GetCurrentProcess().ProcessName)
    {
    hWnd = pr.MainWindowHandle.ToInt32();
    //ShowWindow(hWnd, SW_MAXIMIZE);
    }
    }

    System.Environment.Exit(0);//關閉應用程式
    }
    //---判斷應用程式是否己經開啟?
    BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
    }

    // Avalonia configuration, don't remove; also used by visual designer.
    public static AppBuilder BuildAvaloniaApp()
    => AppBuilder.Configure()
    .UsePlatformDetect()
    .WithInterFont()
    .LogToTrace();
    }
    }

    1. Avalonia 專案 如何確保只能被執行一次 & 如果有先前執行的UI就將其顯示出來 [copilot]

      using System;
      using Avalonia;
      using Avalonia.Controls.ApplicationLifetimes;
      using Avalonia.ReactiveUI;
      using System.Runtime.InteropServices;
      using System.Threading;

      namespace MyAvaloniaApp
      {
      static class Program
      {
      // 初始化具名互斥的名稱
      private static string mutexName = "MyUniqueAvaloniaApp";

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

      [DllImport("user32.dll", SetLastError = true)]
      private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

      // 主程序入口點
      public static void Main(string[] args)
      {
      bool createdNew;
      using (var mutex = new Mutex(true, mutexName, out createdNew))
      {
      if (!createdNew)
      {
      // 找到已有實例的窗口,並將其設置為前景窗口
      IntPtr hWnd = FindWindow(null, "MyAvaloniaApp");
      if (hWnd != IntPtr.Zero)
      {
      SetForegroundWindow(hWnd);
      }
      return;
      }

      // 啟動應用程式
      BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);

      // 這裡其餘的應用程式代碼
      }
      }

      public static AppBuilder BuildAvaloniaApp()
      => AppBuilder.Configure()
      .UsePlatformDetect()
      .LogToTrace()
      .UseReactiveUI();
      }
      }

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *