C\#프로그램 이 여러 번 실행 되 는 것 을 방지 하 는 방법
최근 많은 사람들 이 포럼 에서 프로그램 이 여러 번 실행 되 는 것 을 방지 하 는 방법 에 대해 묻 는 것 을 발견 했다.예 를 들 어http://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9그래서 여기 서 기록 하고 똑 같은 문 제 를 만난 친구 에 게 참고 하 는 동시에 자신 에 대한 축적 이기 도 한다.구체 적 인 실현 코드 를 소개 하기 전에 우 리 는 이 문 제 를 해결 하 는 사고방식 이 무엇 인지 명확 해 야 한다.다음은 내 가 생각 하 는 이 문 제 를 공유 하 는 방식 이다.
1.우리 가 exe 파일 을 클릭 하면 이 exe 프로그램 이 실 행 됩 니 다.우 리 는 이 프로그램의 인터페이스 를 볼 수 있 습 니 다.컴퓨터 에 있어 서 시스템 에서 이 프로그램의 진행 을 열 것 입 니 다.이것 은 우리 가 작업 관리 자 를 통 해 볼 수 있 습 니 다.(우리 가 exe 를 클릭 한 후에 프로그램 이 실 행 됩 니 다.시스템 은 프로그램 과 같은 이름 의 프로 세 스 를 만 들 것 입 니 다)
2.우리 가 프로그램 이 여러 번 실행 되 는 것 을 방지 해 야 한다.즉,프로그램 이 한 번 만 실 행 될 수 있다 는 것 이다.운영 체제 의 측면 에서 볼 때 이 프로그램의 프로 세 스 는 유일한 것 일 수 밖 에 없다 는 것 이다.여기 서 우 리 는 자 연 스 럽 게 생각 했다.이 프로그램의 프로 세 스 가 하나 밖 에 없다 는 것 을 확보 하려 면 우 리 는 이 프로그램의 프로 세 스 가 자신의 운영 체제 에서 실행 되 었 는 지 판단 해 야 한다.프로 세 스 가 실행 되 었 다 면 다음 에 exe 를 실행 할 때 이 프로그램 프로 세 스 를 다시 시작 하 는 것 이 아니 라 종료 합 니 다.알림 상 자 를 꺼 내 서 프로그램 이 실행 되 었 음 을 알려 줍 니 다.운영 체제 가 이 프로그램 프로 세 스 를 실행 하지 않 았 다 면 이 프로그램 을 실행 합 니 다.
3.이 문 제 는 이 프로그램의 프로 세 스 의 수량 문 제 를 판단 하 는 것 으로 바 뀌 었 습 니 다.이때 우 리 는.NET 이 이 프로 세 스 이름 을 얻 을 수 있 는 수량 을 제공 하 는 지 생각 합 니 다.만약 수량 이 1 보다 많 으 면 이 프로그램 이 이미 실행 되 었 고 작 으 면 프로그램 이 실행 되 지 않 았 음 을 나타 냅 니 다..NET 라 이브 러 리 에 익숙 한 사람 은.NET 라 이브 러 리 에 process 클래스 가 있다 는 것 을 알 고 있 을 것 이다.이 클래스 는 프로 세 스 의 추상 적 인 뜻 이다.(어떤 사람들 은 내 가 처음에는 이런 종류 가 있 는 지 몰 랐 는데 어 떡 하지?라 고 말한다.그것 은 바로 당신 의 영 어 를 시험 하 는 것 입 니 다.왜냐하면 프로 세 스 의 영 어 는 Process 이기 때 문 입 니 다.그러나 모든 프로 그래 밍 언어의 이름 은 매우 통속 적 이 고 알 기 쉽 습 니 다.이때 Process 로 MSDN 에서 검색 할 수 있 습 니 다.그러면 당신 도 이런 종 류 를 발견 할 수 있 습 니 다)
4.세 번 째 점 에서 프로 세 스 수량 을 찾 는 방향 을 제시 하 는 것 을 제외 하고 또 다른 실현 방향 은 바로-우리 가 프로 세 스 를 실행 할 때 이 프로 세 스 에 변 수 를 가 질 수 있 는 지 없 는 지 하 는 것 이다.이 변 수 는 이 프로 세 스 를 유일 하 게 표시 하 는 것 이다.exe 파일 을 클릭 하여 프로그램 변경 프로 세 스 를 미리 만 들 때 우 리 는 이 변수 가 존재 하 는 지 판단 한다.존재 한다 면 이 프로 세 스 가 실행 되 었 음 을 설명 하고 이번 프로그램 을 종료 하 며 프로그램 이 실행 되 었 음 을 알려 줍 니 다.
위의 분석 과정 에서 알 수 있 듯 이 우리 가 이 문 제 를 해결 하 는 방향 은 바로 프로 세 스 에 착안 하 는 것 이다.세 번 째 사 고 는 바로 프로 세 스 수량 에 착안 하 는 것 이다.네 번 째 사 고 는 프로 세 스 에 착안 하여 하나의 변 화 를 했 을 뿐 하나의 변 수 를 하나의 프로 세 스 를 유일 하 게 표시 하 게 하 는 것 이다.변수 가 존재 할 때 이 프로그램의 프로 세 스 도 실 행 된 것 을 설명 한다.
2.상호 배척 량 Mutex 사용
주요 한 실현 방향 을 알 게 된 후에 코드 의 실현 은 전혀 문제 가 되 지 않 습 니 다.상호 배척 의 실현 을 사용 하 는 것 은 바로 네 번 째 사고의 표현 입 니 다.우 리 는 이 프로그램 프로 세 스 를 위해 상호 배척 의 Mutex 대상 변 수 를 만 듭 니 다.이 프로그램 을 실행 할 때 이 프로그램 프로 세 스 는 서로 배척 하 는 Mutex 변 수 를 가지 게 됩 니 다.만약 에 이 프로그램 을 다시 실행 하면이 상호 배척 변수 가 존재 하 는 지 확인 합 니 다.(이 프로 세 스 가 존재 하 는 지 교체 합 니 다)존재 하면 프로그램 이 실행 되 었 음 을 설명 합 니 다.그렇지 않 으 면 실행 되 지 않 습 니 다.여기 서 주의해 야 할 것 은 제 다 중 스 레 드 동기 화 글 을 통 해 알 수 있 듯 이 Mutex 류 도 스 레 드 를 동기 화 할 수 있 습 니 다.그러면 다른 스 레 드 동기 화 클래스 도 본 주제 의 문 제 를 해결 할 수 있 습 니까?정 답 은 부정 입 니 다.Mutex 류 가 이 문 제 를 해결 할 수 있 는 이 유 는 Mutex 류 가 스 레 드 를 동기 화 할 수 있 을 뿐만 아니 라 프로 세 스 도 동기 화 할 수 있 기 때 문 입 니 다.실현 코드 를 구체 적 으로 살 펴 보 자.
using System;
using System.Threading;
using System.Windows.Forms;
namespace OnlyInstanceRunning
{
static class Program
{
/// <summary>
/// 。
/// </summary>
[STAThread]
static void Main()
{
#region :
bool createNew;
// createdNew:
// , ( , name null ) , true;
// , false
using (Mutex mutex = new Mutex(true, Application.ProductName, out createNew))
{
if (createNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
// ,
else
{
MessageBox.Show(" ...");
System.Threading.Thread.Sleep(1000);
// 。
System.Environment.Exit(1);
}
}
#endregion
}
}
}
3.프로 세 스 가 존재 하 는 지 직접 판단 하 는 방식 으로 이 문 제 를 해결한다.3.1 이 프로그램의 프로 세 스 수 를 판단 하 는 방식
위의 사고 분석 을 한 후에 여러분 들 이 아래 코드 를 보면 한눈 에 알 수 있 을 것 이 라 고 믿 습 니 다.여 기 는 설명 이 많 지 않 고 코드 를 직접 보 겠 습 니 다.
#region :
Process[] processcollection = Process.GetProcessesByName(Application.CompanyName);
// , , ,
if (processcollection.Length >= 1)
{
MessageBox.Show(" 。。");
Thread.Sleep(1000);
System.Environment.Exit(1);
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//
Application.Run(new Form1());
}
#endregion
3.2 프로그램 프로 세 스 가 존재 하 는 지 직접 판단 하 는 방식
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Way3
{
static class Program
{
#region : Win32
/// <summary>
///
/// Win32 :http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
/// </summary>
/// <param name="hWnd"> </param>
/// <param name="cmdShow"> </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 WS_SHOWNORMAL = 1;
#endregion
/// <summary>
/// 。
/// </summary>
[STAThread]
static void Main()
{
#region : Win32 API,
// VS , VS F5 OnlyInstanceRunning.vshost, , OnlyInstanceRunning
// :http://msdn.microsoft.com/zh-cn/library/ms185331(v=vs.100).aspx
// OnlyInstanceRunning.exe OnlyInstanceRunning,
// , currentProcess.ProcessName.Replace(".vshose","") OnlyInstanceRunning
// , ,
Process process = RunningInstance();
if (process == null)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
// ,
MessageBox.Show(" ......");
HandleRunningInstance(process);
}
#endregion
}
#region
/// <summary>
/// , null
/// </summary>
/// <returns></returns>
private static Process RunningInstance()
{
//
Process currentProcess = Process.GetCurrentProcess();
//
// , 1
Process[] processcollection = Process.GetProcessesByName(currentProcess.ProcessName.Replace(".vshost", ""));
foreach (Process process in processcollection)
{
// ID ID
// ,
if (process.Id != currentProcess.Id)
{
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == process.MainModule.FileName)
{
return process;
}
}
}
return null;
}
/// <summary>
///
/// </summary>
/// <param name="instance"></param>
private static void HandleRunningInstance(Process instance)
{
//
ShowWindow(instance.MainWindowHandle, WS_SHOWNORMAL);
//
SetForegroundWindow(instance.MainWindowHandle);
}
#endregion
}
}
3.3 3.2 실현 방식 에 존재 하 는 문제점 해결-최소 화 된 창 만 표시 할 수 있 고 트 레이 에 숨 기 면 실행 중인 프로그램 을 표시 할 수 없습니다.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Way4
{
static class Program
{
#region : Win32
/// <summary>
///
/// :http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx
/// </summary>
/// <param name="lpClassName"> </param>
/// <param name="lpWindowName"> </param>
/// <returns> , null</returns>
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
/// <summary>
/// , SetForegroundWindow
/// </summary>
/// <param name="hWnd"> </param>
/// <param name="fAltTab">True Alt/Ctrl +Tab </param>
[DllImport("user32.dll ", SetLastError = true)]
static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
///// <summary>
/////
///// Win32 :http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx
///// </summary>
///// <param name="hWnd"> </param>
///// <param name="cmdShow"> </param>
///// <returns> , ; , </returns>
[DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
public const int SW_RESTORE = 9;
public static IntPtr formhwnd;
#endregion
/// <summary>
/// 。
/// </summary>
[STAThread]
static void Main()
{
#region :
// ,
// ,
// :http://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9
Process currentproc = Process.GetCurrentProcess();
Process[] processcollection = Process.GetProcessesByName(currentproc.ProcessName.Replace(".vshost", string.Empty));
// ,
if (processcollection.Length >= 1)
{
foreach (Process process in processcollection)
{
if (process.Id != currentproc.Id)
{
// 0, ,
if (process.MainWindowHandle.ToInt32() == 0)
{
//
formhwnd = FindWindow(null, "Form1");
//
ShowWindow(formhwnd, SW_RESTORE);
SwitchToThisWindow(formhwnd, true);
}
else
{
// ,
// ,
SwitchToThisWindow(process.MainWindowHandle, true);
}
}
}
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
#endregion
}
}
}
4.절차 실현 효과네 가지 실현 방식 의 운행 효 과 는 모두 차이 가 많 지 않다.여기 서 실현 방식 을 보 여 주 는 것 으로 구체 적 인 실현 효 과 는 다음 과 같다.
총화
이 주 제 를 쓰 는 이 유 는 어떤 친구 들 이 이런 질문 을 하 는 것 을 보 았 기 때문에 구체 적 인 실현 코드 를 정리 하여 같은 문제 에 부 딪 힌 친 구 를 참고 하 는 동시에 자신의 학습 에 대한 축적 과 복습 이기 도 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
WebView2를 Visual Studio 2017 Express에서 사용할 수 있을 때까지Evergreen .Net Framework SDK 4.8 VisualStudio2017에서 NuGet을 사용하기 때문에 패키지 관리 방법을 packages.config 대신 PackageReference를 사용해야...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.