防止程序二次运行(C#/VB.NET)

C#

using System.Reflection;
using System.Runtime.InteropServices;
namespace 防止程序二次运行
{
  static class Program
  {
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    /// <summary>
    /// 该函数设置由不同线程产生的窗口的显示状态。
    /// </summary>
    /// <param name="hWnd">窗口句柄</param>
    /// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分。</param>
    /// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。</returns>
    [DllImport("User32.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int cmdShow);
    /// <summary>
    /// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
    /// </summary>
    /// <param name="hWnd">将被激活并被调入前台的窗口句柄。</param>
    /// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns>
    [DllImport("User32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
    private const int SW_SHOWNORMAL = 1;
    /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main()
    {
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Process processes = RunningInstance();
      if (processes == null)
      {
        Application.Run(new FrmMain());
      }
      else
      {
        HandleRunningInstance(processes);
      }
    }
    /// <summary>
    /// 获取正在运行的实例,没有运行的实例返回null;
    /// </summary>
    public static Process RunningInstance()
    {
      Process current = Process.GetCurrentProcess();
      Process[] processes = Process.GetProcessesByName(current.ProcessName);
      foreach (Process process in processes)
      {
        if (process.Id != current.Id)
        {
          if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)
          {
            return process;
          }
        }
      }
      return null;
    }
    /// <summary>
    /// 显示已运行的程序。
    /// </summary>
    public static void HandleRunningInstance(Process instance)
    {
      try
      {
        IntPtr formHwnd = FindWindow(null, "程序主窗口标题");
        ShowWindow(formHwnd, SW_SHOWNORMAL);  //显示
        SetForegroundWindow(formHwnd);     //放到前端
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.Message);
      }
    }
  }
}

 

VB.NET

Imports System.Runtime.InteropServices
Imports System.Reflection

Namespace 防止程序重复运行
     Module Program
        <DllImport("user32.dll")> _
        Public  Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
        End Function
        ''' <summary>
        ''' 该函数设置由不同线程产生的窗口的显示状态。
        ''' </summary>
        ''' <param name="hWnd">窗口句柄</param>
        ''' <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分。</param>
        ''' <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。</returns>
        <DllImport("User32.dll")> _
        Private  Function ShowWindow(hWnd As IntPtr, cmdShow As Integer) As Boolean
        End Function
        ''' <summary>
        ''' 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。
        ''' </summary>
        ''' <param name="hWnd">将被激活并被调入前台的窗口句柄。</param>
        ''' <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns>
        <DllImport("User32.dll")> _
        Private  Function SetForegroundWindow(hWnd As IntPtr) As Boolean
        End Function
        Private Const SW_SHOWNORMAL As Integer = 1
        ''' <summary>
        ''' 应用程序的主入口点。
        ''' </summary>
        <STAThread> _
         Sub Main()
            Application.EnableVisualStyles()
            Application.SetCompatibleTextRenderingDefault(False)
            Dim processes As Process = RunningInstance()
            If processes Is Nothing Then
                Application.Run(New FrmMain())
            Else
                HandleRunningInstance(processes)
            End If
        End Sub
        ''' <summary>
        ''' 获取正在运行的实例,没有运行的实例返回null;
        ''' </summary>
        Public  Function RunningInstance() As Process
            Dim current As Process = Process.GetCurrentProcess()
            Dim processes As Process() = Process.GetProcessesByName(current.ProcessName)
            For Each process As Process In processes
                If process.Id <> current.Id Then
                    If Assembly.GetExecutingAssembly().Location.Replace("/", "\") = current.MainModule.FileName Then
                        Return process
                    End If
                End If
            Next
            Return Nothing
        End Function
        ''' <summary>
        ''' 显示已运行的程序。
        ''' </summary>
        Public  Sub HandleRunningInstance(instance As Process)
            Try
                Dim formHwnd As IntPtr = FindWindow(Nothing, "程序主窗口标题")
                ShowWindow(formHwnd, SW_SHOWNORMAL)
                '显示
                    '放到前端
                SetForegroundWindow(formHwnd)
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub
    End Module
End Namespace

 

posted @ 2022-11-01 11:54  烟熏牛肉干  阅读(163)  评论(0编辑  收藏  举报