.NET में, एक ऐप के कई उदाहरणों को एक ही समय में चलने से रोकने का सबसे अच्छा तरीका क्या है? और अगर कोई "सर्वश्रेष्ठ" तकनीक नहीं है, तो प्रत्येक समाधान के साथ विचार करने के लिए कुछ कैवेट क्या हैं?
.NET में, एक ऐप के कई उदाहरणों को एक ही समय में चलने से रोकने का सबसे अच्छा तरीका क्या है? और अगर कोई "सर्वश्रेष्ठ" तकनीक नहीं है, तो प्रत्येक समाधान के साथ विचार करने के लिए कुछ कैवेट क्या हैं?
जवाबों:
म्यूटेक्स का उपयोग करें। GetProcessByName का उपयोग करके ऊपर दिए गए उदाहरणों में से एक में कई चेतावनी हैं। यहाँ इस विषय पर एक अच्छा लेख है:
http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx
[STAThread]
static void Main()
{
using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
{
if(!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance already running");
return;
}
Application.Run(new Form1());
}
}
private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9";
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;जिसे
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
{
AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn);
return;
}
यहां वह कोड है जो आपको यह सुनिश्चित करने की आवश्यकता है कि केवल एक उदाहरण चल रहा है। यह नामांकित म्यूटेक्स का उपयोग करने की विधि है।
public class Program
{
static System.Threading.Mutex singleton = new Mutex(true, "My App Name");
static void Main(string[] args)
{
if (!singleton.WaitOne(TimeSpan.Zero, true))
{
//there is already another instance running!
Application.Exit();
}
}
}
Hanselman के पास Microsoft से WinFormsApplicationBase वर्ग का उपयोग करने के लिए एक पोस्ट है ।
ऐसा लगता है कि 3 मौलिक तकनीकें हैं जो अब तक सुझाई गई हैं।
मुझे याद किया किसी भी चेतावनी?
1 - program.cs -> में एक संदर्भ बनाएँ
using System.Diagnostics;
2 - void Main()कोड की पहली पंक्ति के रूप में डालें ->
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length >1)
return;
बस।
Mutex? क्या कोई पकड़ है?
विजुअल स्टूडियो 2005 या 2008 का उपयोग करते हुए जब आप "एप्लिकेशन" पैनल के अंदर गुणों वाली खिड़कियों पर एक निष्पादन योग्य के लिए एक प्रोजेक्ट बनाते हैं, तो "एक उदाहरण एप्लिकेशन बनाएं" नाम का एक चेक बॉक्स होता है जिसे आप एप्लिकेशन को एकल उदाहरण एप्लिकेशन पर परिवर्तित करने के लिए सक्रिय कर सकते हैं ।
यहाँ मैं जिस विंडो की बात कर रहा हूँ उस पर कब्जा है:
यह एक विजुअल स्टूडियो 2008 विंडोज़ एप्लीकेशन प्रोजेक्ट है।
मैं यहाँ सभी समाधानों की कोशिश की और कुछ भी मेरी सी # .net 4.0 परियोजना में काम नहीं किया। किसी ऐसे व्यक्ति की मदद करने की उम्मीद करना जो मेरे लिए काम करता है:
मुख्य वर्ग चर के रूप में:
private static string appGuid = "WRITE AN UNIQUE GUID HERE";
private static Mutex mutex;
जब आपको यह जांचना होगा कि क्या ऐप पहले से चल रहा है:
bool mutexCreated;
mutex = new Mutex(true, "Global\\" + appGuid, out mutexCreated);
if (mutexCreated)
mutex.ReleaseMutex();
if (!mutexCreated)
{
//App is already running, close this!
Environment.Exit(0); //i used this because its a console app
}
मुझे केवल कुछ शर्तों के साथ अन्य istances बंद करने की आवश्यकता थी, इसने मेरे उद्देश्य के लिए अच्छी तरह से काम किया
http://en.csharp-online.net/Application_Architecture_in_Windows_Forms_2.0 -Single-Instance_Detection_and_Management
कई समाधान की कोशिश के बाद मैं सवाल। मैं यहाँ WPF के लिए उदाहरण का उपयोग कर समाप्त हुआ : http://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/
public partial class App : Application
{
private static Mutex _mutex = null;
protected override void OnStartup(StartupEventArgs e)
{
const string appName = "MyAppName";
bool createdNew;
_mutex = new Mutex(true, appName, out createdNew);
if (!createdNew)
{
//app is already running! Exiting the application
Application.Current.Shutdown();
}
}
}
App.xaml में:
x:Class="*YourNameSpace*.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"
यह आलेख सरलता से बताता है कि आप अपने इंस्टेंस की संख्या पर नियंत्रण के साथ एक विंडोज़ एप्लिकेशन कैसे बना सकते हैं या केवल एकल उदाहरण चला सकते हैं। यह एक व्यावसायिक अनुप्रयोग की बहुत विशिष्ट आवश्यकता है। इसे नियंत्रित करने के लिए पहले से ही कई अन्य संभावित समाधान मौजूद हैं।
http://www.openwinforms.com/single_instance_application.html
यह VB.Net के लिए कोड है
Private Shared Sub Main()
Using mutex As New Mutex(False, appGuid)
If Not mutex.WaitOne(0, False) Then
MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End If
Application.Run(New Form1())
End Using
End Sub
यह C # के लिए कोड है
private static void Main()
{
using (Mutex mutex = new Mutex(false, appGuid)) {
if (!mutex.WaitOne(0, false)) {
MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Application.Run(new Form1());
}
}
आपको System.Diagnostics.Process का उपयोग करना होगा।
बाहर की जाँच करें: http://www.devx.com/tips/Tip/20044
(नोट: यह एक मजेदार समाधान है! यह काम करता है लेकिन इसे प्राप्त करने के लिए खराब GDI + डिज़ाइन का उपयोग करता है।)
अपने ऐप के साथ एक छवि रखें और इसे स्टार्टअप पर लोड करें। ऐप से बाहर निकलने तक इसे दबाए रखें। उपयोगकर्ता दूसरा उदाहरण शुरू करने में सक्षम नहीं होगा। (बेशक म्यूटेक्स समाधान ज्यादा साफ है)
private static Bitmap randomName = new Bitmap("my_image.jpg");
Main()विधि की भी आवश्यकता होती है जो कि WPF के काम करने के तरीके के खिलाफ जाती है।
[STAThread]
static void Main() // args are OK here, of course
{
bool ok;
m = new System.Threading.Mutex(true, "YourNameHere", out ok);
if (! ok)
{
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1()); // or whatever was there
GC.KeepAlive(m); // important!
}
से: .NET अनुप्रयोग का एक भी उदाहरण सुनिश्चित करना
तथा: सिंगल इंस्टेंस एप्लीकेशन म्यूटेक्स
@Smink और @Imjustpondering को एक ट्विस्ट के रूप में समान उत्तर दें:
Cc पर जॉन स्कीट के अक्सर पूछे जाने वाले प्रश्न यह जानने के लिए कि GC.KeepAlive क्यों मायने रखता है
बस एक का उपयोग StreamWriterकैसे, इस बारे में?
System.IO.File.StreamWriter OpenFlag = null; //globally
तथा
try
{
OpenFlag = new StreamWriter(Path.GetTempPath() + "OpenedIfRunning");
}
catch (System.IO.IOException) //file in use
{
Environment.Exit(0);
}
आम तौर पर यह एक नामित म्यूटेक्स (नए म्यूटेक्स ("आपके ऐप का नाम", सत्य) का उपयोग करें) और रिटर्न वैल्यू की जांच) के साथ किया जाता है, लेकिन Microsoft में कुछ समर्थन कक्षाएं भी हैं । विस्सुअलबासिक । यह आपके लिए कर सकता है ।
इसने मेरे लिए शुद्ध C # में काम किया। कोशिश / पकड़ तब है जब संभवतः सूची में एक प्रक्रिया आपके लूप के दौरान बाहर निकल जाती है।
using System.Diagnostics;
....
[STAThread]
static void Main()
{
...
int procCount = 0;
foreach (Process pp in Process.GetProcesses())
{
try
{
if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0)
{
procCount++;
if(procCount > 1) {
Application.Exit();
return;
}
}
}
catch { }
}
Application.Run(new Form1());
}
किसी एप्लिकेशन को किसी एकल आवृत्ति पर प्रतिबंधित करते समय सुरक्षा पर विचार करना सुनिश्चित करें:
पूरा लेख: https://blogs.msdn.microsoft.com/oldnewthing/20060620-13/?p=30813
हम एक निश्चित नाम के साथ एक नामित म्यूटेक्स का उपयोग कर रहे हैं ताकि यह पता लगाया जा सके कि कार्यक्रम की एक और प्रतिलिपि चल रही है या नहीं। लेकिन इसका मतलब यह भी है कि एक हमलावर पहले म्यूटेक्स बना सकता है, जिससे हमारे कार्यक्रम को बिल्कुल भी चलने से रोका जा सके! मैं इस प्रकार के सेवा हमले से कैसे रोक सकता हूं?
...
यदि हमलावर उसी सुरक्षा संदर्भ में चल रहा है जैसा कि आपका कार्यक्रम है (या होगा) में चल रहा है, तो ऐसा कुछ भी नहीं है जो आप कर सकते हैं। जो भी "गुप्त हैंडशेक" आप यह निर्धारित करने के लिए करते हैं कि क्या आपके कार्यक्रम की एक और प्रतिलिपि चल रही है, हमलावर इसकी नकल कर सकते हैं। चूंकि यह सही सुरक्षा संदर्भ में चल रहा है, यह कुछ भी कर सकता है जो "वास्तविक" कार्यक्रम कर सकता है।
...
स्पष्ट रूप से आप अपने आप को एक ही सुरक्षा विशेषाधिकार पर चलने वाले हमलावर से नहीं बचा सकते हैं, लेकिन आप अभी भी अन्य सुरक्षा विशेषाधिकारों पर चल रहे अनपेक्षित हमलावरों से खुद की रक्षा कर सकते हैं।
अपने mutex पर एक DACL सेट करने का प्रयास करें, यहां .NET तरीका है: https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.mutexsecurity(v=vs.1v).aspx
इस जवाब में से किसी ने भी मेरे लिए काम नहीं किया क्योंकि मुझे मोनोकोडेल का उपयोग करके लिनक्स के तहत काम करने की आवश्यकता थी। यह मेरे लिए बहुत अच्छा काम करता है:
इसे पास करने वाली इस विधि को एक विशिष्ट आईडी कहें
public static void PreventMultipleInstance(string applicationId)
{
// Under Windows this is:
// C:\Users\SomeUser\AppData\Local\Temp\
// Linux this is:
// /tmp/
var temporaryDirectory = Path.GetTempPath();
// Application ID (Make sure this guid is different accross your different applications!
var applicationGuid = applicationId + ".process-lock";
// file that will serve as our lock
var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);
try
{
// Prevents other processes from reading from or writing to this file
var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
_InstanceLock.Lock(0, 0);
MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);
// todo investigate why we need a reference to file stream. Without this GC releases the lock!
System.Timers.Timer t = new System.Timers.Timer()
{
Interval = 500000,
Enabled = true,
};
t.Elapsed += (a, b) =>
{
try
{
_InstanceLock.Lock(0, 0);
}
catch
{
MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
}
};
t.Start();
}
catch
{
// Terminate application because another instance with this ID is running
Environment.Exit(102534);
}
}