PDA

View Full Version : سوال: دریافت کد از کاربر و اجرای آن در runtime



ZerOne
سه شنبه 19 مهر 1390, 11:05 صبح
من نیاز دارم که یک قطعه کد رو در زمان اجرای برنامه کامپایل و اجرا کنم.
مثلا کاربر کدی رو به زبان سی شارپ در تکست باکس بنویسه و بعد با زدن یک دکمه اون کد اجرا بشه و نتیجه اش نمایش داده بشه.
من کشتم و فهمیدم با رفلکشن در سی شارپ می شه این کار رو کرد.
ولی این کدی که تو تکست باکسه دیگه با برنامه من ارتباط نداره.
من می خوام این کد با برنامه اصلی من ارتباط داشته باشه مثلا از یک متغییر که داخل برنامه اصلی است بطونه استفاده کنه.
آیا اصلا چنین امکانی وجود داره؟!

ZerOne
سه شنبه 19 مهر 1390, 19:22 عصر
دوستان کسی نیست منو راهنمایی کنه؟
کسی از رفلکشن استفاده کرده؟
کسی منبعی برای آموزش سراغ نداره؟

exlord
سه شنبه 19 مهر 1390, 19:29 عصر
من نیاز دارم که یک قطعه کد رو در زمان اجرای برنامه کامپایل و اجرا کنم.
مثلا کاربر کدی رو به زبان سی شارپ در تکست باکس بنویسه و بعد با زدن یک دکمه اون کد اجرا بشه و نتیجه اش نمایش داده بشه.
من کشتم و فهمیدم با رفلکشن در سی شارپ می شه این کار رو کرد.
ولی این کدی که تو تکست باکسه دیگه با برنامه من ارتباط نداره.
من می خوام این کد با برنامه اصلی من ارتباط داشته باشه مثلا از یک متغییر که داخل برنامه اصلی است بطونه استفاده کنه.
آیا اصلا چنین امکانی وجود داره؟!

باید این کد رو توی یه فایل ذخیره کنی و با کامپایلر C# کامپایل کنی و متغییر رو هم میتونی به صورت arqument پاس بدی به این برنامه موقع اجرا شدن ...
بگرد هست تو همین فروم و ربطی هم به reflection نداره ...

علیرضا حسن زاده
سه شنبه 19 مهر 1390, 21:48 عصر
تو خو کد می تونی کد رو کامپایل و اجرا کنی تو
تو این آدرس ها هم مثال داره البته توخود سایت هم هست لینکش یادم نیست:
http://www.codeproject.com/KB/cs/codecompilation.aspx
http://www.codeproject.com/KB/dotnet/DynamicCompileAndRun.aspx

ZerOne
چهارشنبه 20 مهر 1390, 21:24 عصر
باید این کد رو توی یه فایل ذخیره کنی و با کامپایلر C#‎ کامپایل کنی و متغییر رو هم میتونی به صورت arqument پاس بدی به این برنامه موقع اجرا شدن ...
بگرد هست تو همین فروم و ربطی هم به reflection نداره ...

با این روش میشه ولی برنامه اصلی و کد کاربر زیاد با هم ارتباط ندارند.
من می خواهم که به چند متغییر با هم دسترسی داشته باشد. یک ارتباط دو طرفه و اجرای همزمان

علیرضا حسن زاده
پنج شنبه 21 مهر 1390, 09:41 صبح
فکر کنم کد جدید رو کامپایل کنی و رفرنسی هم به یه اسمبلی دیگه که کلاس مورد نظر برای پارمترها توش Static باشه و هردوبرنامه هم تو یه Namespace باشن بشه اطلاعات رو بین هردو بشه انتقال داد(یه زمانی میخواستم همچین کار بکنم که نشد یه چند تا تست کردم دیگه پیگیر نشدم)
ولی بهترین را ممکنه استفاده از Pipe برای ارتباط دوبرنامه باشه که اگه اشتباه نکنم آقای محسن شاهمحمدی به مقادله در هین مورد تو سایت قرار دان می تونید از اون استفاده کنید

ZerOne
پنج شنبه 21 مهر 1390, 18:44 عصر
فکر کنم کد جدید رو کامپایل کنی و رفرنسی هم به یه اسمبلی دیگه که کلاس مورد نظر برای پارمترها توش Static باشه و هردوبرنامه هم تو یه Namespace باشن بشه اطلاعات رو بین هردو بشه انتقال داد(یه زمانی میخواستم همچین کار بکنم که نشد یه چند تا تست کردم دیگه پیگیر نشدم)
ولی بهترین را ممکنه استفاده از Pipe برای ارتباط دوبرنامه باشه که اگه اشتباه نکنم آقای محسن شاهمحمدی به مقادله در هین مورد تو سایت قرار دان می تونید از اون استفاده کنید

منم هم تست کردم نشد.
این مقاله ای گفتید رو من نتونستم پیدا کنم.شما لینکش رو دارید.

علیرضا حسن زاده
پنج شنبه 21 مهر 1390, 19:56 عصر
اگه نام کاربر و پستهاش رو جستجو می کردین حتما به نتیجه می رسیدین
به هر حال اینم لینک تاپیک:
http://barnamenevis.org/showthread.php?306543

ZerOne
جمعه 22 مهر 1390, 13:19 عصر
با روش بالا میشه اطلاعات رو جابجا کرد. البته اون چیزی که می خواستم نبود.
اما یه سوال مهمتر:
امکان داره دو تا برنامه توابع همدیگر رو صدا بزنند؟

علیرضا حسن زاده
شنبه 30 مهر 1390, 08:43 صبح
امکان داره دو تا برنامه توابع همدیگر رو صدا بزنند؟
اگه از DLLهای ویندوز استفاده کرده باشی تقریبا همچین کاری رو انجام میدن
ولی تو دانت نت فکر کنم برای این کار بهتره از سرویس ها استفاده کنی(البته برای برنامه های غیر دات نت هم استفاده میشه )

C#.net
جمعه 11 فروردین 1391, 09:46 صبح
از این مثال استفاده کنید
از کامپایلر #C و اشیایی مثل CSharpCodeProvider استفاده شده

Miladkt.S.A.o
دوشنبه 04 اردیبهشت 1391, 23:45 عصر
سلام دوست عزیز
برای این کار کلاس مخصوصی به نام CodeDom
وجود دارد به مثال زیر توجه کن

در دات نت فريم ورك امكان كامپايل پوياي يك قطعه كد دريافت شده از يك رشته، توسط فضاي نام CodeDom مهيا است كه قدرت قابل توجهي را در اختيار برنامه نويس قرار مي‌دهد.

مثال يك:
رشته زير را كامپايل كرده و تبديل به يك فايل exe كنيد:

string source =
@"
namespace Foo
{
public class Bar
{
static void Main(string[] args)
{
Bar.SayHello();
}

public static void SayHello()
{
System.Console.WriteLine(""Hello World"");
}
}
}
";
روش انجام كار به همراه توضيحات مربوطه به صورت كامنت:

using System;
using System.Collections.Generic;
//دو فضاي نامي كه براي اين منظور اضافه شده‌اند
using Microsoft.CSharp;
using System.CodeDom.Compiler;

namespace compilerTest
{
class Program
{
static void compileIt1()
{
//سورس كد ما جهت كامپايل
string source =
@"
namespace Foo
{
public class Bar
{
static void Main(string[] args)
{
Bar.SayHello();
}

public static void SayHello()
{
System.Console.WriteLine(""Hello World"");
}
}
}
";

//تعيين نگارش كامپايلر مورد استفاده
Dictionary<string, string> providerOptions = new Dictionary<string, string>
{
{"CompilerVersion", "v3.5"}
};
//تعيين اينكه كد ما سي شارپ است
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);

//تعيين اينكه خروجي يك فايل اجرايي است بعلاوه مشخص سازي محل ذخيره سازي فايل نهايي
CompilerParameters compilerParams = new CompilerParameters
{
OutputAssembly = "D:\\Foo.EXE",
GenerateExecutable = true
};

//عمليات كامپايل در اينجا صورت مي‌گيرد
CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);

//اگر خطايي وجود داشته باشد نمايش داده خواهد شد
Console.WriteLine("Number of Errors: {0}", results.Errors.Count);
foreach (CompilerError err in results.Errors)
{
Console.WriteLine("ERROR {0}", err.ErrorText);
}
}

static void Main(string[] args)
{
compileIt1();

Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
}
مثال 2:
كد مورد نظر را به صورت يك فايل dll كامپايل كنيد.
براي اين منظور تمامي مراحل مانند قبل است فقط GenerateExecutable ذكر شده به false تنظيم شده و نام خروجي نيز به foo.dll بايد تنظيم شود.


مثال 3:
كد مورد نظر را در حافظه كامپايل كرده (خروجي dll يا exe نمي‌خواهيم)، سپس متد SayHello آن را به صورت پويا فراخواني نموده و خروجي را نمايش دهيد.
در اين حالت روش كار همانند مثال 1 است با اين تفاوت كه GenerateInMemory = true و GenerateExecutable = false تنظيم مي‌شوند. همچنين جهت دسترسي به متد كلاس ذكر شده،‌ از قابليت‌هاي ريفلكشن موجود در دات نت فريم ورك استفاده خواهد شد.

using System;
using System.Collections.Generic;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;

namespace compilerTest
{
class Program
{
static void compileIt2()
{
//سورس كد ما جهت كامپايل
string source =
@"
namespace Foo
{
public class Bar
{
static void Main(string[] args)
{
Bar.SayHello();
}

public static void SayHello()
{
System.Console.WriteLine(""Hello World"");
}
}
}
";

//تعيين نگارش كامپايلر مورد استفاده
Dictionary<string, string> providerOptions = new Dictionary<string, string>
{
{"CompilerVersion", "v3.5"}
};
//تعيين اينكه كد ما سي شارپ است
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);

//نحوه تعيين مشخص سازي كامپايل در حافظه
CompilerParameters compilerParams = new CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = false
};

//عمليات كامپايل در اينجا صورت مي‌گيرد
CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);

// اگر خطايي در كامپايل وجود نداشت متد دلخواه را فراخواني مي‌كنيم
if (results.Errors.Count == 0)
{
//استفاده از ريفلكشن براي دسترسي به متد و فراخواني آن
Type type = results.CompiledAssembly.GetType("Foo.Bar");
MethodInfo method = type.GetMethod("SayHello");
method.Invoke(null, null);
}
}


static void Main(string[] args)
{
compileIt2();

Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
}

منبع این مطالب سایت http://www.dotnettips.info/2009/09/blog-post_16.html
موفق باشی:قهقهه: