PDA

View Full Version : سوال: ورودی تابع main در console apps



MiniMicro
یک شنبه 16 تیر 1392, 09:56 صبح
سلام خدمت همه دوستان
چرا باید ورودی تابع main در console app آرایه ای از رشته ها باشد؟

مهرداد صفا
یک شنبه 16 تیر 1392, 10:10 صبح
باسلام.
اگر تا به حال با برنامه های تحت کنسول کار کرده باشید حتما دیدید که معمولا یک سری پارامتر را در خط فرمان به عنوان دستورات برنامه به برنامه ارسال میکنند:


application -option1 -option2 ...
application /p1:x /p2 /p3 ...


معمولا برنامه های اجرایی ویندوز (مخصوصا برنامه های کنسول) قابلیت این را دارند که در هنگام اجرا شدن یک یا چند پارامتر در یافت کنند. این پارامتر ها گاها توسط ویندوز و به صورت خودکار به برنامه ارسال میشود و گاهی هم توسط کاربر.
این پارامترها به روال main ارسال شده و به صورت آرایه ای از رشته در اختیار برنامه نویس قرار میگیرد.

MiniMicro
یک شنبه 16 تیر 1392, 10:43 صبح
ممنون دوست عزیز میشه یه مثال در رابطه با ارسال پارامتر به برنامه توسط کاربر بزنید.
همین تابع main وقتی برنامه اجرا میشه عملا کدهای داخل main اجرا میشه پس اون پارامتر هایی که توسط ویندوز به main ارسال میشه چه اتفاقی براشون می افته؟
برنامه نویس چطوری میتونه اون پارامتر هایی که توسط ویندوز به main ارسال میشه و بصورت آرایه ای از رشته ها است رو مدیریت کنه؟
معمولا چه نوع پارامتر هایی براش ارسال میشه؟
و اگر امکان داره یه خورده بیشتر توضیح بدید ممنون میشم.

httplistener
یک شنبه 16 تیر 1392, 12:57 عصر
ممنون دوست عزیز میشه یه مثال در رابطه با ارسال پارامتر به برنامه توسط کاربر بزنید.
همین تابع main وقتی برنامه اجرا میشه عملا کدهای داخل main اجرا میشه پس اون پارامتر هایی که توسط ویندوز به main ارسال میشه چه اتفاقی براشون می افته؟
برنامه نویس چطوری میتونه اون پارامتر هایی که توسط ویندوز به main ارسال میشه و بصورت آرایه ای از رشته ها است رو مدیریت کنه؟
معمولا چه نوع پارامتر هایی براش ارسال میشه؟
و اگر امکان داره یه خورده بیشتر توضیح بدید ممنون میشم.

سلام.
ببینید اگر با برنامه های تحت فرمان کار کرده باشید متوجه می شید جریان از چه قراره،مثلا خیلی ها میگن که
من با دستور داس کامپیوتر رو خاموش در زمان معین خاموش میکنم،منظورشون این کد هست:


shutdown /s /t 3600

البته باید بدونیم که نباید به Command Prompt ویندوز MS-DOS اطلاق بشه اما خوب اینجوری جا افتاده،کاری نداریم،حالا میگن با cmd میایم و ویندوز را شات دان می کنیم،اما در واقع این cmd نیست که شات دان میکنه بلکه این برنامه shutdown هست که این کارو برا ما اجرا میکنه،کاری که cmd برا ما انجام میده ارسال پارامترهای
s /t 3600/ به برنامه هست.قبل از اینکه بحث رو ادامه بدم اگر شما هم بعد از دیدن دستور فوق رفتید به این آدرس Run->CMD و بعد دستور فوق رو زدید و enter رو وارد کردید برای اینکه یک ساعت دیگه سیستمتون خاموش نشه حالا این دستور زیر رو اجرا کنید:


shutdown /a

خوب حالا دستور زیر رو اجرا کنید تا cmd تر و تمیز بشه:


cls
همونطور که معلومه این دستور دیگه برای خود CMD هست،خوب اگر علاقه مندید به یادگیری
دستورات cmd ، حالا دستور HELP رو اجرا کنید تا برخی از دستور های ابتدایی رو داشته باشید.
برگردیم به بحث خودمون:

کد زیر رو کامپایل بکنید :


using System;
using System.IO;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] path)
{
if (path.Length == 0 || !File.Exists(path[0]))
return;
Console.WriteLine("The File Content is : \r\n-------------------\r\n");
Console.WriteLine( File.ReadAllText(path[0]) );
Console.ReadLine();
}
}
}



حالا در Command Prompt دستور زیر رو Enter بکنید :


ExecutableFilePath ACustomTxtFilePath

که در اون ExecutableFilePath نام مسیر کامل برنامه ای هست که کامپایل کردید،و ACustomTxtFilePath هم نام یک فایل متنی در کامپیوتر شما( ANSI باشد)،همونطور که می بینید با برنامه شما اجرا شده و محتوای فایل مذکور را به شما نشون میده،
حالا همین ارسال پارامتر رو با ویندوز (در حقیقت با استفاده از برنامه Explorer ویندوز) انجام بدیم:
روی یک فایل متنی راست کلیک و گزینه OpenWith رو انتخاب نمایید: Choose Program بعد Browse و برنامه خودتون رو انتخاب و OK بکنید،همینطور که می بینید برنامه شما اجرا میشه و محتوای فایل متنی رو به شما نشون میده.
این که گفته شد Ansi باشه به این خاطر هست که Console ؛ Unicode رو ساپورت نمیکنه، و بجز موارد خاص و آموزشی هم معمولا ازش استفاده نمیشه،شما سعی کنید همین کار رو به شکل بهتر با System.Window.Forms انجام بدید.

ویرایش : و اینکه ی دیگه، شاید بپرسید چرا برای برنامه shutdown آدرس کامل داده نشده ،این به خاطر این هست که این برنامه در یک دایرکتوری Enviroment Variable هست (window/system32)،برای ست کردن این نوع آدرس ها می تونید روی MyComputer راست کلیک کنید و از اونجا : Properties->Advanced->Enviroment Variables

پیروز و کامروا باشید.

مهرداد صفا
یک شنبه 16 تیر 1392, 13:50 عصر
سلام خواهش می کنم.

میشه یه مثال در رابطه با ارسال پارامتر به برنامه توسط کاربر بزنید.

اکثر برنامه های پرکاربرد تحت کنسول موجود در ویندوز از سویچها و پارامترهای مختلف استفاده میکنند. مثلا برنامه shutdown با پارامتر /r سیستم را ریبوت می کند و یا با پارامتر /h سیستم را هایبرنت یا خواب میکند که میتوانید در run(start+r key) یا cmd امتحان کنید:


shutdown -h

برای یک نمونه فرمان زیر را در run بنویسید و نتیجه را ببینید:


wmplayer c:\windows\media\chimes.wav


همین تابع main وقتی برنامه اجرا میشه عملا کدهای داخل main اجرا میشه پس اون پارامتر هایی که توسط ویندوز به main ارسال میشه چه اتفاقی براشون می افته؟
برنامه نویس چطوری میتونه اون پارامتر هایی که توسط ویندوز به main ارسال میشه و بصورت آرایه ای از رشته ها است رو مدیریت کنه؟
معمولا چه نوع پارامتر هایی براش ارسال میشه؟

ویندوز فقط در مواردی خاص اقدام به ارسال آرگومنت به برنامه میکند که نمونش رو با مثال بررسی خواهیم کرد و اکثر این آرگومنتها توسط برنامه نویس برای دادن option های مختلف به کاربر و یا اجرای فرمان های گوناگون توسط کار بر در نظر گرفته می شود. با اجرای برنامه ویندوز پرامترهای ورودی را به صورت یک رشته یا آرایه به روال main ارسال میکند و این برنامه نویس است که تصمیم میگیرد که کدام فرمان درست وارد شده و با کدام چه کاری باید بکند.
معمولا در برنامه های کنسول در روال main یک آرگومنت به نام args در نظر گرفته می شود که مقدار فرمانهای ورودی را نگه می دارد. همچنین در کلاس System.Environment مقداری به نام CommandLine وجود دارد که مقدار فرمانهای ورودی را در اختیار برنامه نویس قرار می دهد.


و اگر امکان داره یه خورده بیشتر توضیح بدید ممنون میشم.

برای اینکه نحوه کار رو هرچه بیشتر لمس کنید مراحل زیر را دنبال کنید:

1- یک پروژه کنسول جدید ایجاد کنید و کد مربوط به تابع main را به صورت زیر تغییر دهید:

//in the name of god

static void Main(string[] args)
{
Console.WriteLine("arguments:");
foreach (string argument in args)
{
Console.WriteLine(argument);
}
Console.Write("press any key to continiue.");
Console.ReadKey();
}


همونطور که میبینید ما در این مثال فقط پارامترهای ورودی را در پنجره کنسول نمایش دادیم که طبیعتا در موارد عملی شما احتمالا محاسباتی با این مقادیر انجام میدهید یا بر اساس آنها برنامه رفتار گوناگونی خواهد داشت.
2- برنامه را در مسیر دلخواه ذخیره کرده و یک بار برنامه را build کنید.
3- به مسیر ذخیره برنامه<پوشه debug رفته و فایل اجرایی را به Test1.exe تغییر نام دهید و آن را به پوشه "x:\windows\system32\" (که x درایو ویندوز شماست) انتقال دهید. (این مرحله صرفا برای راحتی کار است)
4- فرمان زیر را در run یا خط فرمان بنویسید و کلید enter را بزنید:


test1 -param1 -param2 -param3


میبینید که فرمانهای ورودی به ترتیب در پنجره کنسول نمایش داده می شود. کلیدی را بزنید تا از برنامه خارج شوید.
5- حالا برای اینکه نمونه ای از پارامترهایی که توسط ویندوز ارسال می شود را ببینید در یک پوشه دلخواه در windows explorer یا همان my computer روی فضای خالی راست کلیک کنید و از منوی new گزینه Text document را انتخاب کرده نام آن را (برای مثال) به test.tst تغییر دهید.
6- روی فایلی که ایجاد کردید کلیدهای alt+enter را بزنید تا properties فایل مربوطه باز شود.
7- در قسمت open with کلید change را بزنید و با گزینه Brows یا "look for another app in this pc" (بسته به نسخه ویندوز) فایل برنامه (c:\windows\system32\test1.exe) را به عنوان برنامه پیشفرض برای این گونه فایل قرار داده ok کنید.
8- درمرحله آخر کافیست فایل test.tst را اجرا کنید تا برنامه اجرا شود و در خط دوم پارامتری که ویندوز به برنامه ما ارسال کرده (آدرس فایل test.tst( را ببینید.

وقتی شما از طریق windows explorer مثلا یک فایل صوتی را باز میکنید ویندوز نام آن را به عنوان پارامتر به application مربوطه ارسال میکند و application فایل را اجرا می کند.

MiniMicro
یک شنبه 16 تیر 1392, 17:10 عصر
دوست عزیز ممنون از این راهنمایی کامل و جامعت
به قول گفتنی 2 هزاریم افتاد
همین طور سوال پیش میاد
و اما سوال های دیگری هم که داشتم مربوط به تغییر نوع پارامتر های ارسالی به برنامه که توسط کامپایلر آرایه ای از رشته ها است منتفی میشه برای مثال اگر اون رو تغییر بدیم به int چون مسیر قابل تبدیل کردن به int نیست پس برنامه با مشکل مواجه میشه
و...


بسیار ممنون ...

مهرداد صفا
یک شنبه 16 تیر 1392, 20:07 عصر
دوست عزیز ممنون از این راهنمایی کامل و جامعت
به قول گفتنی 2 هزاریم افتاد
همین طور سوال پیش میاد
و اما سوال های دیگری هم که داشتم مربوط به تغییر نوع پارامتر های ارسالی به برنامه که توسط کامپایلر آرایه ای از رشته ها است منتفی میشه برای مثال اگر اون رو تغییر بدیم به int چون مسیر قابل تبدیل کردن به int نیست پس برنامه با مشکل مواجه میشه
و...


بسیار ممنون ...

خواهش میکنم.
اگر منظور تغییر نوع آرگومنتها با تغییر در نوع ورودی main باشد:

void Main(int[] args)

این کار به این صورت امکان پذیر نیست. چون اگر از حساسیت کامپایر روی این مساله هم بگذریم، ویندوز پارامترها رو به صورت string ارسال میکند و در مورد.string و آرایه ها هم در ویندوز آدرس رشته یا آرایه در stack قرار میگیرد
یعنی ویندوز ورودی ها را به صورت یک رشته در قسمتی از حافظه نگه میدارد و سپس آدرس آن را (که در مورد win32 یک int32 است) را به برنامه اجرایی ارسال میکند و این آدرس توسط کامپایلر یک اشاره گر به یک رشته یا آرایه در نظر گرفته می شود.
ولی اگر با type casting قصد دارید رشته ها را در برنامه به عدد convert کنید به راحتی این کار امکان پذیر است.
اگر قصد دارید که یک option در برنامه در نظر بگیرید که مقدار آن از ورودی، توسط کاربر وارد شود می توانید مانند کد زیر عمل کنید:

static void Main(string[] args)
{
string LengthOption = "";
foreach (string arg in args)
{
if (arg.StartsWith("/L:"))
LengthOption=arg;
}
if (LengthOption != "")
Console.Beep(3000, int.Parse(LengthOption.Split(':').Last()));
else
Console.WriteLine("usage:\n /L sets lengths of sound.\n example: /L:2000");


}

برنامه بالا طول صدا را با فرمت /L:n میگیرد و یک صدا به مدت n هزارم ثانیه پخش میکند و کاری هم با مثلا آدرس فایل کا ممکن است از طریق ویندوز ارسال شود ندارد.