나는 Windows 응용 프로그램 (C#)이 있으며 그 응용 프로그램에서 한 인스턴스를 실행하도록 구성해야합니다. 즉, 한 명의 사용자가 .exe 파일을 클릭하여 응용 프로그램이 실행되고 사용자는 실행중인 응용 프로그램의 첫 번째 인스턴스를 닫지 않았으므로 다음 인스턴스를 실행하여 첫 번째 인스턴스가 나타나야하며 새 인스턴스를 열지 않아야합니다.응용 프로그램에서 하나의 인스턴스 실행
어떻게 할 수 있습니까?
미리 감사드립니다.
나는 Windows 응용 프로그램 (C#)이 있으며 그 응용 프로그램에서 한 인스턴스를 실행하도록 구성해야합니다. 즉, 한 명의 사용자가 .exe 파일을 클릭하여 응용 프로그램이 실행되고 사용자는 실행중인 응용 프로그램의 첫 번째 인스턴스를 닫지 않았으므로 다음 인스턴스를 실행하여 첫 번째 인스턴스가 나타나야하며 새 인스턴스를 열지 않아야합니다.응용 프로그램에서 하나의 인스턴스 실행
어떻게 할 수 있습니까?
미리 감사드립니다.
나는 종종 같은 다른 프로세스를 확인하여이 문제를 해결 이름. 이 장점/단점은 당신 (또는 사용자)이 exe의 이름을 변경하여 수표에서 "옆으로"물러날 수 있다는 것입니다. 당신이 원한다면 아마 반환 된 Process-object를 사용할 수있을 것이다. 그것은 당신의 필요에 따라
string procName = Process.GetCurrentProcess().ProcessName;
if (Process.GetProcessesByName(procName).Length == 1)
{
...code here...
}
, 나는 그것 (가끔 서비스로 실행되는 서버 프로세스의) 재 컴파일 우유없는 검사를 우회하는 편리한 것 같아요.
편집 : 질문에 C#이 포함되도록 수정되었습니다. 내 대답은
가 응용 프로그램의 여러 인스턴스를 실행하지 못하도록 단일 인스턴스 응용 프로그램 확인란을 만들기를 선택에만 vb.net 응용 프로그램에 대해 작동합니다. 이 확인란의 기본 설정이 지워져 응용 프로그램의 여러 인스턴스가 실행될 수 있습니다.
당신은 프로젝트에서이 작업을 수행 할 수 있습니다 -> 속성 - C 번호를 사용하면 가정> 응용 프로그램 탭
Afaik 이것은 VB에만 적용되며 C#에는 적용되지 않습니다. –
C#에서 VB 솔루션을 사용하는 방법에 대한 내 제안을 참조하십시오. 체크 박스를 체크하는 것보다 조금 더 많은 것이지 많은 것은 아닙니다. –
을
static Mutex mx;
const string singleInstance = @"MU.Mutex";
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
System.Threading.Mutex.OpenExisting(singleInstance);
MessageBox.Show("already exist instance");
return;
}
catch(WaitHandleCannotBeOpenedException)
{
mx = new System.Threading.Mutex(true, singleInstance);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
정확히 같은 문제가있었습니다. Google은 프로세스 접근 방식을 시도했지만 사용자가 관리자가 아닌 다른 프로세스에 대한 정보를 읽을 권한이없는 경우 실패합니다. 그래서 우리는 아래의 솔루션을 구현했습니다.
기본적으로 독점적 인 읽기 전용 파일을 열려고합니다. 이것이 실패하면 (인스턴스가 이미 이것을 수행했기 때문에) 예외가 발생하고 앱을 종료 할 수 있습니다.
bool haveLock = false;
try
{
lockStream = new System.IO.FileStream(pathToTempFile,System.IO.FileMode.Create,System.IO.FileAccess.ReadWrite,System.IO.FileShare.None);
haveLock = true;
}
catch(Exception)
{
System.Console.WriteLine("Failed to acquire lock. ");
}
if(!haveLock)
{
Inka.Controls.Dialoge.InkaInfoBox diag = new Inka.Controls.Dialoge.InkaInfoBox("App has been started already");
diag.Size = new Size(diag.Size.Width + 40, diag.Size.Height + 20);
diag.ShowDialog();
Application.Exit();
}
VB.Net 팀은 이미 솔루션을 구현했습니다. Microsoft.VisualBasic.dll에 종속성을 가져야하지만, 그렇게해도 문제가되지 않는다면 좋은 해결책이 될 것입니다. 다음 문서의 끝 부분을 참조하십시오 Single-Instance Apps는
다음은 기사에서 관련 부분입니다 :
1)가 microsoft.visualbasic.dll 2에 대한 참조를 추가) 프로젝트에 다음 클래스를 추가합니다.
public class SingleInstanceApplication : WindowsFormsApplicationBase
{
private SingleInstanceApplication()
{
base.IsSingleInstance = true;
}
public static void Run(Form f, StartupNextInstanceEventHandler startupHandler)
{
SingleInstanceApplication app = new SingleInstanceApplication();
app.MainForm = f;
app.StartupNextInstance += startupHandler;
app.Run(Environment.GetCommandLineArgs());
}
}
열린 프로그램.CS는 다음 using 문을 추가 :
using Microsoft.VisualBasic.ApplicationServices;
변경합니다 클래스를 다음과 :
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SingleInstanceApplication.Run(new Form1(), StartupNextInstanceEventHandler);
}
public static void StartupNextInstanceEventHandler(object sender, StartupNextInstanceEventArgs e)
{
MessageBox.Show("New instance");
}
}
이것은 간단한 접근 방법이지만 Scott Hanselman의 블로그 게시물 (http://www.hanselman.com/blog/TheWeeklySourceCode31SingleInstanceWinFormsAndMicrosoftVisualBasicdll.aspx –
)의 토론에서 언급 된 함정이 있음을 지적 해 주셨습니다. 그것의. 연결된 게시물에서 한 가지 함정 만 볼 수 있었으며 Windows가 안전 모드에서 실행 중일 때이 솔루션이 작동하지 않는다는 것이 었습니다. 많은 응용 프로그램에는 아무렇게나 정상 모드로 실행해야하는 기능이 있습니다. 그러면 많은 단점이 없을 수 있습니다. 어쨌든, 문제가 있다는 것을 아는 것이 좋습니다. –
내가이 시나리오에 대한 Mutex
을 사용하십시오. 또는 Semaphore
도 사용할 수 있습니다 (단 Mutex
).
여기 (WPF 응용 프로그램에서, 그러나 동일한 원리는 다른 프로젝트 유형에 적용한다) 내 예제 :
public partial class App : Application
{
const string AppId = "MY APP ID FOR THE MUTEX";
static Mutex mutex = new Mutex(false, AppId);
static bool mutexAccessed = false;
protected override void OnStartup(StartupEventArgs e)
{
try
{
if (mutex.WaitOne(0))
mutexAccessed = true;
}
catch (AbandonedMutexException)
{
//handle the rare case of an abandoned mutex
//in the case of my app this isn't a problem, and I can just continue
mutexAccessed = true;
}
if (mutexAccessed)
base.OnStartup(e);
else
Shutdown();
}
protected override void OnExit(ExitEventArgs e)
{
if (mutexAccessed)
mutex?.ReleaseMutex();
mutex?.Dispose();
mutex = null;
base.OnExit(e);
}
}
내가이 code을 발견, 그것은 작품입니다!
/// <summary>
/// The main entry point for the application.
/// Limit an app.to one instance
/// </summary>
[STAThread]
static void Main()
{
//Mutex to make sure that your application isn't already running.
Mutex mutex = new System.Threading.Mutex(false, "MyUniqueMutexName");
try
{
if (mutex.WaitOne(0, false))
{
// Run the application
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
else
{
MessageBox.Show("An instance of the application is already running.",
"An Application Is Running", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Application Error 'MyUniqueMutexName'",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
finally
{
if (mutex != null)
{
mutex.Close();
mutex = null;
}
}
}
+1 접근 방식을 사용합니다 –
이 방법은 부분적으로 신뢰할 수있는 코드에서는 사용할 수 없습니다. 글로벌 C# 예제로서 이것은 가난한 접근 방식입니다. – Shaamaan