PDA

View Full Version : سوال: جلوگیری از تکراری باز شدن برنامه



123456za
جمعه 27 آذر 1388, 11:39 صبح
سلام
دوستان توی انجمن خیلی گشتم و یک کدی هم پیدا شد ولی نتونستم جواب بگیرم
من یک برنامه دارم که با c# نوشتم و این برنامه من توسط یک برنامه دیگه چند بار اجرا می شه می خوام که در هر بار اجرا شدن اگر برنامه ای که خودم نوشتم باز هست دیگه اچرا نکنه یعنی چند برنامه باز شده نباشه تا حافظه اشغال نشه
چطوری تشخیص بدم برنامه در حال اجرا هست و اگر ورودی برای برنامه داشته باشیم چطوری بگیرم با همون فرم اولی که اجرا شده
نمی دونم واضح گفتم یا نه:ناراحت:

com_eng_abasszadeh
جمعه 27 آذر 1388, 13:15 عصر
سلام
دوستان توی انجمن خیلی گشتم و یک کدی هم پیدا شد ولی نتونستم جواب بگیرم
من یک برنامه دارم که با c# نوشتم و این برنامه من توسط یک برنامه دیگه چند بار اجرا می شه می خوام که در هر بار اجرا شدن اگر برنامه ای که خودم نوشتم باز هست دیگه اچرا نکنه یعنی چند برنامه باز شده نباشه تا حافظه اشغال نشه
چطوری تشخیص بدم برنامه در حال اجرا هست و اگر ورودی برای برنامه داشته باشیم چطوری بگیرم با همون فرم اولی که اجرا شده
نمی دونم واضح گفتم یا نه:ناراحت:
سلام دوست عزیز.....من که متوجه نشدم می خوای چی کار کنی...ولی میتونی واسه همون برناهمت یه ناحیه بحرانی بذاری که اگر به این خط رسیدی از ناحیه بحرانیش خارج بشه و اونو اجرا نکنه......براش یه متغییر boolبساز و بار اول بذار false و بعد از اتمام برنامت اونو بذار true و قبل از اجرای برنامت اونو چک کنه بینم true هست یا false.....فکر کنم با همینم کارت بشه.

123456za
جمعه 27 آذر 1388, 13:27 عصر
ممنون از جواب
منظورم اینه که در حالت عادی اگر هر بار یک برنامه رو اجرا کنید یک پنجره جدا براش باز می شه و مستقل از هم من می خوام اگر برنامه در حال اجرا بود دیگه برنامه در پنجره جدید باز نشه و همگی عملیات در همان برنامه ای که اول باز شده انجام بشه
نمونه کد که دوستان گذاشتند

for (int i = 0; i < Application.OpenForms.Count; i++)
{
if (Application.OpenForms[i].Name == "NameForm")

return;
}
یا بهتر بگم اگر برنامه در حال اجرا هست ببنده و بعد خودش لود بشه

mehdi.mousavi
جمعه 27 آذر 1388, 13:37 عصر
این برنامه من توسط یک برنامه دیگه چند بار اجرا می شه می خوام که در هر بار اجرا شدن اگر برنامه ای که خودم نوشتم باز هست دیگه اچرا نکنه

سلام.
شما برای اینکار میتونید از Mutex ها استفاده کنید. (http://www.ai.uga.edu/mc/SingleInstance.html)

موفق باشید

123456za
جمعه 27 آذر 1388, 14:09 عصر
ممنون کمک بزرگی بود یک قسمت دیگه مشکل دارم اینه که چطوری ورودی ها رو بگیرم؟

static void Main(string[] input)
{
bool ok;
Mutex m = new System.Threading.Mutex(true, "Mainform", out ok);

if (!ok)
{
MessageBox.Show("Another instance is already running.");


return;
}

Application.Run(new Mainform(input));

GC.KeepAlive(m); // important!

mehdi.mousavi
جمعه 27 آذر 1388, 20:35 عصر
ممنون کمک بزرگی بود یک قسمت دیگه مشکل دارم اینه که چطوری ورودی ها رو بگیرم؟

خواهش میکنم. اما متوجه نمیشم منظورتون از ورودی چیه... کدوم ورودی رو؟

123456za
جمعه 27 آذر 1388, 22:14 عصر
ممنون
با توجه به کدی گذاشتم
static void Main(string[] input)

روال کلی برنامه بدین صورت هست که برنامه من که با سی شارپ هست توسط یکی دیگه برنامه باز می شه و از اون برنامه یک سری پارامتر فرستاده می شه یک سری کامند هست که من با لود شدن برنامه دریافت می کنم
حالا در هر دفعه که اون برنامه برنامه من را اجرا می کند یک مشکل بود که همزمان چند تا فرم باز می شد که به لطف شما حل شد
الان من مشکل دریافت پارامترهای وردی دارم که اون برنامه برام میفرستم نمی دونم چجوری بگیرم اگر می شه یک مثال بفرستین فرض بگیرین
c:\>test.exe -p1

slashslash2009
جمعه 27 آذر 1388, 22:43 عصر
اگه شما میخواید که وقتی برنامتون در حال اجرا هست و اگر بعدش دوباره بخوایم اون برنامه رو اجرا کنیم اجرا نشه من میتونم کمکتون کنم چون منظورتونو درست نگرفتم چی گفتین

123456za
جمعه 27 آذر 1388, 22:55 عصر
اگه شما میخواید که وقتی برنامتون در حال اجرا هست و اگر بعدش دوباره بخوایم اون برنامه رو اجرا کنیم اجرا نشه من میتونم کمکتون کنم چون منظورتونو درست نگرفتم چی گفتین
ممنون لطفا اگر کمکی از دستتون بر می یاد دریغ نکنید تا فردا بیشتر وقت ندارم

slashslash2009
جمعه 27 آذر 1388, 23:24 عصر
در قسمت solution explorer وارد فایل program.cs شوید این using رو اضافه کنید

using System.Threading;
بعدشم این تغییراتو بده

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{

bool ok;
Mutex m = new Mutex(true, "برنامه من", out ok);
if (!ok)
{
MessageBox.Show("برنامه در حاله اجرا است!!");
return;
}
//
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
Application.Run(new Form1());
}
}

123456za
جمعه 27 آذر 1388, 23:47 عصر
در قسمت solution explorer وارد فایل program.cs شوید این using رو اضافه کنید

using System.Threading;
بعدشم این تغییراتو بده

static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{

bool ok;
Mutex m = new Mutex(true, "برنامه من", out ok);
if (!ok)
{
MessageBox.Show("برنامه در حاله اجرا است!!");
return;
}
//
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(fals e);
Application.Run(new Form1());
}
}
ممنون دوست عزیز اگر دقت کنید در تاپیک های قبلی دوست عزیزمون نمونه برنامه رو گذاشتند و منم گفتم جواب گرفتم
تا اینجا می شه اگر تکرار باز شدن برنامه جلوگیری کرد ولی چجوری پارامتر های ورودی رو برنامه در حال اجرا پاس بدم؟
نمونه برنامه ای که می فرستم ببنید در cmd یک کامند بهش بدین منظورم رو می فهمید
c:>test.exe -p بر فرض -p پارمتر ورودی من هست یا کامند ورودی که من باید در برنامه بگیرم اینو چجوری بگیرم چون برنامه قبل از اجرا با سورس بالا بسته می شه البته پارمترهای ورودی هست ولی نمی دونم چجوری پاس بدم به فرم اصلی
امیدوارم منظورم متوجه شده باشید

123456za
یک شنبه 29 آذر 1388, 10:14 صبح
میشه توضیح بدین که میخواید چیکار کنید شاید داری یه راه سختو پیش میری:متفکر:
خیلی ساده بگم
یک نرم افزار هست که مسیر فایل پروژه اش رو به صورت کامند می فرسته و من به این مسیر نیاز دارم برای برنامه خودم یعنی کامند رو باید بگیرم در هر بار اجرا شدن برنامه
در خود اون نرم افزار من می تونم نرم افرام رو اضافه کنم و اجرا کنم و در هر دفعه اجرا شدن مسیری که من نیاز دارم به صورت پارامتر می فرسته عکس زیر دیگه واضح هست که من نرم افزار خودم به اون نرم افزار اضافه کردم و یک گزینه هم اجرا شدن اون ایجاد میشه

mehdi.mousavi
یک شنبه 29 آذر 1388, 12:18 عصر
ممنون دوست عزیز اگر دقت کنید در تاپیک های قبلی دوست عزیزمون نمونه برنامه رو گذاشتند و منم گفتم جواب گرفتم تا اینجا می شه اگر تکرار باز شدن برنامه جلوگیری کرد ولی چجوری پارامتر های ورودی رو برنامه در حال اجرا پاس بدم؟ نمونه برنامه ای که می فرستم ببنید در cmd یک کامند بهش بدین منظورم رو می فهمید c:>test.exe -p بر فرض -p پارمتر ورودی من هست یا کامند ورودی که من باید در برنامه بگیرم اینو چجوری بگیرم چون برنامه قبل از اجرا با سورس بالا بسته می شه البته پارمترهای ورودی هست ولی نمی دونم چجوری پاس بدم به فرم اصلی امیدوارم منظورم متوجه شده باشید

آهان! شما یک Instance جدید رو با Command Argument های دلخواه خودتون اجرا می کنید. Instance جدید، با استفاده از Mutex متوجه میشه که Instance دیگه ای در حال اجرا هستش، بنابراین اجرا رو متوقف میکنه و از برنامه خارج میشه. در صورتیکه شما میخواهید قبل از خروج از برنامه، Command Line Argument پاس شده به Instance جدید رو، به دست فرم موجود در Instance اولی برسونید. تا اینجا درسته؟

اگر منظورتون این باشه، شما فقط یک راه دارید. شما باید با استفاده از IPC، یا همون Interprocess Communication مقدار مورد نظرتون رو بدست Process اولی برسونید. IPC خودش مجموعه ای از 8-9 روش هستش، که هر کدوم جایگاه و موارد استفاده خودشون رو دارن:


Clipboard
COM
DDE
Pipe
RPC
Windows Sockets
Data Copy
و ...

تو این موردی که شما میگید، به نظر من، Data Copy میتونه روش مناسب و کم هزینه ای باشه. مکانیزم به این صورت هستش که شما Data مورد نظر رو (Command Line Arguments، در این مورد) با استفاده از WM_COPYDATA بدست Instance اجرا شده قبلی میرسونید. وقتی این پیام، در Instance قبلی دریافت شد، اونوقت میتونید بر اساس ساختار Data ای که Copy کرده اید، اونو Extract کرده و ازش استفاده کنید.

روشهای دیگه، استفاده از تکنولوژیهای جدید هستش، بعنوان مثال IPC with WCF و ...

موفق باشید.

mehdi.mousavi
یک شنبه 29 آذر 1388, 17:30 عصر
ممنون توضیح کاملی بود mehdi6755 من سی شارپ رو تازه کشف کردم چه چیز خوبیه و خیلی مشکل برخوردم تا الان اگر ممکنه یک روشی که گفتید مثال بفرستید ممون می شم

جالبه! اجازه بدید من یکی دیگه از کشفیات بشر رو بهتون معرفی کنم: موتور جستجوی گوگل. باور کنید اینم چیز خوبیه. کافیه توش یک C# WM_COPYDATA میزدید و بعد دکمه مربوطه رو فشار میدادید و نظاره گر، اعجاز گوگل میشدید. در هر حال، میتونید به این سایت رجوع کنید. (http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/)

موفق باشید.