[سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - الشاكي لله - 27-11-13
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
والصلاة والسلام على اشرف الخلق محمد وعلى اله الطيبين الطاهرين
--
اهلا وسهلا بكم اخواني في المقالة الرابعة من [سلسلة التحكم]
صفر :- اجزاء المقالة
اولا :- كتابة Remote object
ثانيا :- كتابة Web Service
ثالثا :- كتابة برنامج Server
رابعا :- كتابة برنامج Client
خامسا :- فيديو نتيجة الدرس (من تصويري)
سادسا :- المراجع & الخاتمة
اولا :- Remote object
الRemote object هو مصطلح يعلمه كل من تابع المقالة الثانية من هذه السلسلة
هذا الRemote object يحتوي على دوال تتحكم في الحاسوب فور استدعائها
ولكن من الذي يستدعي هذه الدالة ؟؟
البرنامج Client هو من يعطي اشارة للServer ليقوم باستدعاء الدالة من الRemote object
فيتم اسدعاء الدالة وتنفيذها على الServer ، كل هذا تم بأمر من برنامج الClient.
في البداية علينا إنشاء Remote object وهو عبارة عن Class library
--
خطوات انشاء Remote object :-
1-
سنسمي الRemote object باسم Control وسنقوم بانشاء مشروع جديد من نوع Class Library
2-
دائما اول شيئ تفكر فيه هو "الاوامر" ، فتسأل نفسك : ماهي الاوامر التي اريد من الServer ان ينفذها ؟؟
وتكتب كل الاوامر داخل enum
PHP كود :
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Windows.Forms;
namespace Control { public class Controls { public enum Commands { TurnOffPC, ViewMessage, PlayBeebs, SetClipboard, GetClipboard, GetScreenShot, GetPCName } } }
الاوامر التي اريد من الجهاز الاخر (Server) ان ينفذها هي :
- اطفاء الحاسوب ، عرض رسالة ، تشغيل صوت ، اضافة قيمة للحافظة ، جلب قيمة الحافظة ، جلب صورة سطح المكتب الحالية - جلب اسم جهاز السيرفر
هذه الاوامر التي خطرت في بالي فقمت بكتابتها في enum.
3-
الان علينا كتابة دالة لكل امر كتبته فوق :-
PHP كود :
public void TurnOffPC() { System.Diagnostics.Process.Start("shutdown", "-s -t 1"); }
public void ViewMessage(string message) { MessageBox.Show(message, "Message From Client", MessageBoxButtons.OK, MessageBoxIcon.Information); }
public void PlayBeebs() { System.Media.SystemSounds.Beep.Play(); }
public void SetCliboard(string str) { Clipboard.SetText(str); }
public string GetCliboard() { try { return Clipboard.GetText(); } catch { return ""; } }
public byte[] GetScreenShot() { try { var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap. var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner. gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen. using (var ms = new System.IO.MemoryStream()) { bmpScreenshot.Save(ms, ImageFormat.Png); return ms.ToArray(); } } catch { return null; } }
public string GetPCName() { try { return System.Environment.MachineName; } catch { return ""; } }
--
وهكذا قمنا بكتابة الدوال التي ستقوم بتنفيذ طموحاتنا على جهاز الServer
والكود النهائي :-
PHP كود :
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Windows.Forms;
namespace Control { public class Controls { public enum Commands { TurnOffPC, ViewMessage, PlayBeebs, SetClipboard, GetClipboard, GetScreenShot, GetPCName }
public void TurnOffPC() { System.Diagnostics.Process.Start("shutdown", "-s -t 1"); }
public void ViewMessage(string message) { MessageBox.Show(message, "Message From Client", MessageBoxButtons.OK, MessageBoxIcon.Information); }
public void PlayBeebs() { System.Media.SystemSounds.Beep.Play(); }
public void SetCliboard(string str) { Clipboard.SetText(str); }
public string GetCliboard() { try { return Clipboard.GetText(); } catch { return ""; } }
public byte[] GetScreenShot() { try { var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap. var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner. gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen. using (var ms = new System.IO.MemoryStream()) { bmpScreenshot.Save(ms, ImageFormat.Png); return ms.ToArray(); } } catch { return null; } }
public string GetPCName() { try { return System.Environment.MachineName; } catch { return ""; } } } }
ثانيا :- كتابة Web Service
الان يجب علينا التفكير مليا ... ماهي الطريقة التي سنستعملها للتحكم بالجهاز الاخر ؟؟
هناك طريقة ذكية وسنستعملها في هذه المقالة وهي "الرسائل" .
مبدأها يشبه مبدأ الChatting تماااااما ، حيث انك ترسل من برنامجك Client الى البرنامج الاخر (Server) الرقم 3
فيقوم الServer باستدعاء الدالة TurnOffComputer مثلا ... نفس الشيئ لو ارسلت الرقم 7 ، سيقوم السيرفر باستدعاء GetScreenShot.
اذن النظام الذي سنستخدمه هو الرسائل . فالان علينا التفكير في طريقة لنقل الرسائل من عندنا الى الطرف الاخر !
الجواب هو باستعمال خدمة الويب كأحد طرق نقل الرسائل ...
فالطريقة بالتفصيل ستكون بهذه الكيفية :-
1- اولا يقوم البرنامج الClient بارسال الرقم 1 مع اسم السيرفر الهدف الى خدمة الويب
2- تقوم خدمة الويب بحفظ الرقم + اسم الserver في مكان مخصص في الذاكرة
3- في برنامج الServer يوجد timer يعمل كل 3 ثواني مثلا .. وظيفته هو فحص هذا المكان في الذاكرة للبحث عن الجديد
4- فاذا عثر على الرقم 1 في المكان المخصص ... يقوم بترجمة الرقم ويفهمه على انه استدعاء لدالة معينة
طبعا نظام الارقام صار قديم في البرمجة .. الان يتم استخدام enum ، لذلك قمنا في بداية المقالة بانشاء enum لتسهيل الموضوع
--
نقوم اولا بإنشاء WebService ونسميها WebKernel مثلا او اي اسم يحلو لك
إقتباس :خطوات إنشاء خدمة الويب :-
1- إنشاء مشروع جديد من نوع ASP.NET Empty Web Application
2- قم بإضافة WebService من خلال Project > Add new item > Web Service
خطوات إنشاء خدمة الويب (بالصور) :-
1
2
ثم نقوم بادراج الRemote object في هذا المشروع عبر :-
بعدها نقوم بكتابة دالة يطلبها الClient لكي تخزن رقم في الذاكرة
PHP كود :
[WebMethod] public void SendCommandTo(string SenderName, string ReceiverName, Controls.Commands cmd, string addtionalData) { Application.Set(ReceiverName + "|CMD", ((int)cmd).ToString()); Application.Set(ReceiverName + "|ADD", addtionalData); Application.Set(ReceiverName + "|Sender", SenderName); }
Application.Set هي دالة تقوم بحفظ بيانات لفترة قدرها نصف ساعة تقريبا ثم تحذف .
هي تستقبل بارمترين .. الاول هو key ، والاخر هو data
اي انها شبيهة جدا بHashtable او Dictionary
طبعا اعلم ان الكود يسوده الغموض وهذا طبيعي لأن البرنامج يعتمد على نمط لايعلم عنه سوا كاتب الكود .
الدالة المقابلة والتي تقوم باسترجاع البيانات من الذاكرة هي
PHP كود :
[WebMethod] public string[] ReceiveCommand(string name) { try { string[] obj = new string[3]; obj[0] = (string)Application.Get(name + "|CMD"); obj[1] = (string)Application.Get(name + "|ADD"); obj[2] = (string)Application.Get(name + "|Sender"); return obj; } catch { return null; } }
Application.Get تستقبل بارمتار واحد وهو key .. وسترجع لك الdata المحفوظة على هذا الkey
كما قلت سابقا مبدأها يشبه مبدا HashTable فالي فاهمنه مابواجه مشكلة.
بقية الكود هي دوال مساعدة :-
PHP كود :
using Control; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services;
namespace WebKernel { /// <summary> /// Summary description for MyService /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class MyService : System.Web.Services.WebService {
[WebMethod] public void SendCommandTo(string SenderName, string ReceiverName, Controls.Commands cmd, string addtionalData) { Application.Set(ReceiverName + "|CMD", ((int)cmd).ToString()); Application.Set(ReceiverName + "|ADD", addtionalData); Application.Set(ReceiverName + "|Sender", SenderName); }
[WebMethod] public object SendCommandAndWaitResult(string SenderName, string ReceiverName, Controls.Commands cmd) { Application.Set(ReceiverName + "|CMD", ((int)cmd).ToString()); Application.Set(ReceiverName + "|ADD", null); Application.Set(ReceiverName + "|Sender", SenderName); //wait for result while (Application.Get(SenderName) == null) { }
object result = Application.Get(SenderName); Application.Remove(SenderName);
return result; }
[WebMethod] public void ReturnResultToClient(string name, object result) { Application.Set(name, result); }
[WebMethod] public string[] ReceiveCommand(string name) { try { string[] obj = new string[3]; obj[0] = (string)Application.Get(name + "|CMD"); obj[1] = (string)Application.Get(name + "|ADD"); obj[2] = (string)Application.Get(name + "|Sender"); return obj; } catch { return null; } }
[WebMethod] public void RemoveRegisterName(string name) { try { Application.Remove(name + "|CMD"); Application.Remove(name + "|ADD"); Application.Remove(name + "|Sender"); } catch { } }
[WebMethod] public bool CheckNameExist(string name) { if (Application[name + "|Alive"] != null) { return true; } else { Application.Set(name + "|Alive", -1); return false; } }
} }
ستفهم جميع هذه الدوال في النهاية اذا ركزت في الجزئين التاليين .
ولكن عليك ان تقوم برفع الخدمة الى استضافة كي نستطيع التحكم عن بعد
ثانيا :- كتابة Server
دائما اغلب مبرمجي تطبيقات (Client/server) يقومون بكتابة الserver اولا
فنحن بدورنا سنقوم بفعل ذلك ، لذلك قم بإنشاء مشروع جديد في نفس السلوشن
ومن نوع Windows App واسمه Server :
اولا علينا اضافة المراجع الضرورية ك Remote object الي سويناها في الجزء الاول
وخدمة الويب المرفوعة على استضافة .
بعدها نعرف متغير عام على المشروع يمثل الclient تبع الخدمة
ومتغير اخر عام نحفظ فيه اسمنا
PHP كود :
Service.MyServiceSoapClient _serviceClient = new Service.MyServiceSoapClient(); private string _MyName = string.Empty;
قد تقول معليش انا فهمت ليش سويت متغير يعبر عن الخدمة وذلك لكي تستطيع استعمال دوال خدمة الويب
ولكن لم افهم ليش سويت متغير _MyName ؟؟؟
طبيعي في اي برنامج server/client ان يكون هناك عنوان فريد يدل على الاخر
فكيف يستطيع الclient ان يتصل بالسيرفر بدون عنوانه ؟
العنوان في العادة يكون عبارة عن IP Address ولكن باستعمال خدمة الويب يمكنك الاستغناء عن الايبي
واضافة اي اسم كي يستطيع الclient الوصول له ...
فنحن سنكتب اسمنا في الtextbox وثم ناخذ قيمته ونضعه في المتغير العام MyName .
والان كود الButtonOK هو :-
PHP كود :
private void OKbutton_Click(object sender, EventArgs e) { if (_serviceClient.CheckNameExist(textBox1.Text.Trim())) { MessageBox.Show("Choose another name", "Error : name exist", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } _MyName = textBox1.Text.Trim(); textBox1.Enabled = false; OKbutton.Enabled = false; StatusLable.Text = "Waiting for commands ..."; ServerTimer.Start(); }
--
شرح الكود :-
في السطر الاول : نقوم بفحص الاسم المدخل ، هل يستخدمه شخص اخر ام لا ؟ فكما لايمكن ان يتشابه IP address على وجه الارض
كذلك لايمكننا ان ندع الاسماء تتشابه كي نستلم الرسائل من الجهة الصحيحة .
بقية الاسطر : مفهومة وواضحة .
السطر الاخير : تشغيل تايمر لفحص الاوامر الجديدة . فهذا تايمر يعمل كل 3 ثواني ويقوم بالاستعلام عن اخر الاوامر
وكوده هو :-
PHP كود :
private async void ServerTimer_Tick(object sender, EventArgs e) { //الاستعلام عن اخر امر Task<ReceiveCommandResponse> cmdTask = _serviceClient.ReceiveCommandAsync(_MyName); ReceiveCommandResponse cmdResb = await cmdTask; Service.ArrayOfString arr = cmdResb.Body.ReceiveCommandResult; if (arr[0] == null) { return; } Control.Controls controlObj = new Control.Controls(); //حذف اخر من ذاكرة السيرفر await _serviceClient.RemoveRegisterNameAsync(_MyName);
//استخلاص الامر والعنوان من الاستعلام Commands CMD = (Commands)int.Parse(arr[0]); string addtionalInfo = (string)arr[1]; string senderName = (string)arr[2];
//اذا كان الامر المرسل يساوي كذا قم باستدعاء الدالة المناسبة switch (CMD) { case Commands.TurnOffPC: controlObj.TurnOffPC(); break; case Commands.ViewMessage: controlObj.ViewMessage(addtionalInfo); break; case Commands.PlayBeebs: controlObj.PlayBeebs(); break; case Commands.SetClipboard: controlObj.SetCliboard(addtionalInfo); break; case Commands.GetClipboard: string data0 = controlObj.GetCliboard(); await _serviceClient.ReturnResultToClientAsync(senderName, data0); break; case Commands.GetScreenShot: byte[] data1 = controlObj.GetScreenShot(); await _serviceClient.ReturnResultToClientAsync(senderName, data1); break; case Commands.GetPCName: string data2 = controlObj.GetPCName(); await _serviceClient.ReturnResultToClientAsync(senderName, data2); break; } }
الكود مشروح بالتعليقات الخضراء
ولكن اهم شيئ فيه هو المتغير CMD وهو يعبر عن الامر المرسل من الClient
فإذا كان الامر الذي ارسله Client يساوي Commands.TurnOffPC قم باستدعاء دالة اغلاق الحاسوب
ونفس الشيئ للبقية .
--
الكود كامل :-
PHP كود :
using Server.Service; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;
namespace Server { public partial class ServerForm : Form { Service.MyServiceSoapClient _serviceClient = new Service.MyServiceSoapClient(); private string _MyName = string.Empty;
public ServerForm() { InitializeComponent(); }
private void OKbutton_Click(object sender, EventArgs e) { if (_serviceClient.CheckNameExist(textBox1.Text.Trim())) { MessageBox.Show("Choose another name", "Error : name exist", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } _MyName = textBox1.Text.Trim(); textBox1.Enabled = false; OKbutton.Enabled = false; StatusLable.Text = "Waiting for commands ..."; ServerTimer.Start(); }
private async void ServerTimer_Tick(object sender, EventArgs e) { //الاستعلام عن اخر امر Task<ReceiveCommandResponse> cmdTask = _serviceClient.ReceiveCommandAsync(_MyName); ReceiveCommandResponse cmdResb = await cmdTask; Service.ArrayOfString arr = cmdResb.Body.ReceiveCommandResult; if (arr[0] == null) { return; } Control.Controls controlObj = new Control.Controls(); //حذف اخر من ذاكرة السيرفر await _serviceClient.RemoveRegisterNameAsync(_MyName);
//استخلاص الامر والعنوان من الاستعلام Commands CMD = (Commands)int.Parse(arr[0]); string addtionalInfo = (string)arr[1]; string senderName = (string)arr[2];
//اذا كان الامر المرسل يساوي كذا قم باستدعاء الدالة المناسبة switch (CMD) { case Commands.TurnOffPC: controlObj.TurnOffPC(); break; case Commands.ViewMessage: controlObj.ViewMessage(addtionalInfo); break; case Commands.PlayBeebs: controlObj.PlayBeebs(); break; case Commands.SetClipboard: controlObj.SetCliboard(addtionalInfo); break; case Commands.GetClipboard: string data0 = controlObj.GetCliboard(); await _serviceClient.ReturnResultToClientAsync(senderName, data0); break; case Commands.GetScreenShot: byte[] data1 = controlObj.GetScreenShot(); await _serviceClient.ReturnResultToClientAsync(senderName, data1); break; case Commands.GetPCName: string data2 = controlObj.GetPCName(); await _serviceClient.ReturnResultToClientAsync(senderName, data2); break; } }
} }
الان نذهب لتصميم الClient فيقوم بارسال امر الى الخدمة الويب ، فتقوم خدمة الويب بحفظها في ذاكرة الHost لمدة قدرها تقريبا نصف ساعة
طبعا كما ذكرنا في الفقرة السابقة ان الserver سيقوم كل 3 ثواني بفحص ذاكرة الHost للحصول على جديد الاوامر .
رابعا :- كتابة Client
كما قلنا سابقا سنقوم بعمل برنامج Client يقوم بارسال امر الى الخدمة ويقوم الServer بالاستعلام من الخدمة .
سنقوم بإنشاء برنامج Client في نفس السلوشن ايضا ، وهو من نوع Windows App وباسم Client :
كلعادة نقوم باضافة الموارد اللازمة (خدمة الويب + الRemote object)
والان اصبح السلوشن بهذا الشكل :
الان نبدأ البرمجة ونقول بتعريف المتغيرات العامة :-
PHP كود :
Service.MyServiceSoapClient _serviceClient = new Service.MyServiceSoapClient(); private string _ServerName = string.Empty; private string _MyName = string.Empty;
ونبرمج زر OK بنفس طريقة الServer :-
PHP كود :
private void OKbutton_Click(object sender, EventArgs e) { if (_serviceClient.CheckNameExist(textBox1.Text.Trim())) { MessageBox.Show("Choose another name (My Name)", "Error : name exist", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } groupBox1.Enabled = false; groupBox2.Enabled = true; _MyName = textBox1.Text.Trim(); _ServerName = textBox2.Text.Trim(); }
والان نقوم بكتابة كود الازرار ال6 :-
PHP كود :
private void SendMessageBtn_Click(object sender, EventArgs e) { string str = Interaction.InputBox("Enter your message to server"); if (str != string.Empty) { //ارسال امر _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.ViewMessage, str); } }
private void SendBeebsBtn_Click(object sender, EventArgs e) { _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.PlayBeebs, null); }
private void SendClipboardBtn_Click(object sender, EventArgs e) { string str = Interaction.InputBox("Enter your text to save it in server clipboard"); if (str != string.Empty) { _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.SetClipboard, str); } }
private void GetDataClipboardBtn_Click(object sender, EventArgs e) { //ارسال امر وانتظار النتيجةSendCommandAndWaitResult string savedClipBoard = (string)_serviceClient.SendCommandAndWaitResult(_MyName,_ServerName, Service.Commands.GetClipboard);
MessageBox.Show("The content of server clipboard is : " + savedClipBoard, "Server Clipboard", MessageBoxButtons.OK, MessageBoxIcon.Information); }
private void ScreenshotBtn_Click(object sender, EventArgs e) { //ارسال امر جلب الصورة وانتظار الصورة byte[] serverShot = (byte[])_serviceClient.SendCommandAndWaitResult(_MyName, _ServerName, Service.Commands.GetScreenShot);
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(serverShot)) { Image shot = Image.FromStream(ms); ScreenShotForm shotForm = new ScreenShotForm(); shotForm.pictureBox1.BackgroundImage = shot; shotForm.Show(); ms.Close(); } }
private void MachinenameBtn_Click(object sender, EventArgs e) { //ارسال امر جلب اسم جهاز السيرفر وانظار النتيجة string serverMachineName = (string)_serviceClient.SendCommandAndWaitResult(_MyName, _ServerName, Service.Commands.GetPCName);
MessageBox.Show("The server machine name is : " + serverMachineName, "Server Machine Name", MessageBoxButtons.OK, MessageBoxIcon.Information); }
private void ShutdownBtn_Click(object sender, EventArgs e) { _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.TurnOffPC,null); }
استخدمت في الكود الدالة SendCommandTo هي لكي ترسل امر الى الخدمة
والدالة SendCommandAndWaitResult لارسال امر وانتظار النتيجة التي سيرجعها الServer
فمثلا هذا الزر يتطلب ارسال امر وجلب نتيجة تنفيذه :
فهذا الزر يتطلب استعمال دالة SendCommandAndWaitResult لانتظار النتيجة
بعد وصول النتيجة سيتم عرضها على فورم اخر .
ولكن هناك شيئ مهم جدا يخص Get screen shot ، فكما نعلم من اسم الزر انه امر لجلب صورة سطح المكتب للسيرفر
وهذا يتطلب نقل الصورة من الserver الى client ، ولكن انتبه فلا يجوز نقل صورة حجمها اكبر من 60 كيلو بايت !!!
60 كيلو بايت !!! . هي مساحة صغيرة جدا واغلب الصور تكون اكبر من هذا الحجم فما الحل ؟؟
الحل بسيط اكثر مماتتخيل . فقط قم بالدخول الى App.config والخاص بالمشروع Client الذي نعمل عليه حاليا
وقم بالتالي :-
كما ترا قمت باضافة maxReceivedMessageSize لزيادة حجم اقصى حد لاستقبال الرسائل
ووضعت قيمته 2000000 مما يساوي 2 ميغا بايت
ومستحيل صورة سطح المكتب التي سيتم التقاطها بتنسيق jpg ان يتجاوز حجمها ال700 كيلو ولكن للاحتطيات فقط وضعت 2 مب.
الكود كامل :-
PHP كود :
using Microsoft.VisualBasic; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
namespace Web_Remote { public partial class ClientForm : Form { Service.MyServiceSoapClient _serviceClient = new Service.MyServiceSoapClient(); private string _ServerName = string.Empty; private string _MyName = string.Empty;
public ClientForm() { InitializeComponent(); }
private void OKbutton_Click(object sender, EventArgs e) { if (_serviceClient.CheckNameExist(textBox1.Text.Trim())) { MessageBox.Show("Choose another name (My Name)", "Error : name exist", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } groupBox1.Enabled = false; groupBox2.Enabled = true; _MyName = textBox1.Text.Trim(); _ServerName = textBox2.Text.Trim(); }
private void SendMessageBtn_Click(object sender, EventArgs e) { string str = Interaction.InputBox("Enter your message to server"); if (str != string.Empty) { //ارسال امر _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.ViewMessage, str); } }
private void SendBeebsBtn_Click(object sender, EventArgs e) { _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.PlayBeebs, null); }
private void SendClipboardBtn_Click(object sender, EventArgs e) { string str = Interaction.InputBox("Enter your text to save it in server clipboard"); if (str != string.Empty) { _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.SetClipboard, str); } }
private void GetDataClipboardBtn_Click(object sender, EventArgs e) { //ارسال امر وانتظار النتيجةSendCommandAndWaitResult string savedClipBoard = (string)_serviceClient.SendCommandAndWaitResult(_MyName,_ServerName, Service.Commands.GetClipboard);
MessageBox.Show("The content of server clipboard is : " + savedClipBoard, "Server Clipboard", MessageBoxButtons.OK, MessageBoxIcon.Information); }
private void ScreenshotBtn_Click(object sender, EventArgs e) { //ارسال امر جلب الصورة وانتظار الصورة byte[] serverShot = (byte[])_serviceClient.SendCommandAndWaitResult(_MyName, _ServerName, Service.Commands.GetScreenShot);
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(serverShot)) { Image shot = Image.FromStream(ms); ScreenShotForm shotForm = new ScreenShotForm(); shotForm.pictureBox1.BackgroundImage = shot; shotForm.Show(); ms.Close(); } }
private void MachinenameBtn_Click(object sender, EventArgs e) { //ارسال امر جلب اسم جهاز السيرفر وانظار النتيجة string serverMachineName = (string)_serviceClient.SendCommandAndWaitResult(_MyName, _ServerName, Service.Commands.GetPCName);
MessageBox.Show("The server machine name is : " + serverMachineName, "Server Machine Name", MessageBoxButtons.OK, MessageBoxIcon.Information); }
private void ShutdownBtn_Click(object sender, EventArgs e) { _serviceClient.SendCommandTo(_MyName, _ServerName, Service.Commands.TurnOffPC,null); } } }
خامسا :- فيديو نتيجة الدرس (من تصويري)
او من على اليوتيوب مباشرة
كود :
https://www.youtube.com/watch?v=DClwZ_m9dAs
سابعا :- المراجع & الخاتمة
المراجع المعتمد عليها في هذه المقالة :-
[سلسلة التحكم] {3} - خدمة الويب (Web Service)
--
أتمنى أن تستفيدو من هذه المقالة
اعلم ان بعضكم قد يتسآل ويقول "مادام مبدأك نقل رسائل فقط ليش استعملت WebService ولم تقم بإرسال الرسائل مباشرة للServer" ؟
في الواقع الاتصال المباشر بين طرفين يسمى Peer2Peer وهو اتصال سهل يمكنك عمله بسهولة ولكن ...
لو كان الطرفان بعيدان وعلى شبكة مختلفة ، أعلم ان Peer2Peer ستواجه المصاعب والمآسي ولن يتم الاتصال
وكل هذا بسبب الجدران النارية والNAT ، ولكن في الاجزاء القادمة سنقوم بكشف الستار عن اسرار الاتصال المباشر
وسنقوم بعمل برنامج مثل TeamViewer يقوم بالتحكم الكامل عن بعد بواسطة Peer2Peer ولن نقوم بالاستعان بطرف ثالث (Third party).
نلقاكم بخير
إنتهى
[/size]
RE: [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - VanToM - 27-12-13
بارك الله فيك
وجعله في ميزان حسناتك
وبإنتظار جديدك دائماً
والله أنت فخر للمسلمين !
RE: [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - as206em - 15-03-14
السلام عليكم ورحمة الله وبركاته شكرا لك أخي الكريم على هذا الموضوع القييم
لدي سؤال لو سمحت لي
قمت بعمل web service ورفعته على هوستينج Somee وهو يعمل بنجاح
قمت بتطوير المشروع وقمت بإضافة Database اليه من نوع Sql Serever باستخدام تقنية Linq 2 Sql
بعد التطوير , المشروع يعمل بنجاح على حاسوبي الشخصي "Local Machine"
قمت برفع البرنامج مرة أخرى إلى ال Hosting
ولكن عندما أقوم باستدعاء التابع الذي يقوم بالقراءة من ال Database يظهر لي الخطأ التالي
error: 26 - Error Locating Server/Instance Specified
هنا الكودات التي يتألف منها مشروعي
Web.Config
PHP كود :
<?xml version="1.0"?>
<!-- For more information on how to configure your ASP.NET application, please visit http://go.microsoft.com/fwlink/?LinkId=169433 -->
<configuration> <connectionStrings> <add name="Database1ConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" /> </connectionStrings> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web>
</configuration>
Web Service1
PHP كود :
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Services;
namespace test2 { /// <summary> /// Summary description for WebService1 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. // [System.Web.Script.Services.ScriptService] public class WebService1 : System.Web.Services.WebService {
[WebMethod] public string DataBaseTest() { try { DataClasses1DataContext db = new DataClasses1DataContext(); return db.Table1s.Select(c => c).First().name; } catch (Exception x) { return x.Message; } } } }
Client Windows Application
PHP كود :
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
private void Form1_Load(object sender, EventArgs e) { ServiceReference1.WebService1SoapClient c = new ServiceReference1.WebService1SoapClient(); MessageBox.Show(c.DataBaseTest()); } } }
أرجة منك أخي الكريم تنبيهي إلى الخطأ فيما سبق
وشكرا لك
RE: [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - الشاكي لله - 15-03-14
الخطأ هنا
إقتباس :Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True;User Instance=True"
حسب مافهمت انك رفعت القاعدة على الاستضافة، فيجب عليك ان تستبدل نص الاتصال بنص القاعدة المرفوعة
تحصل عليه من صفحة ال Ms-Sql :manage database
كما في الصورة :
RE: [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - as206em - 16-03-14
شكرا لك أخي الكريم
نعم كانت مشكلتي في ال connection string
سوف أقوم بتجربة ماتفضلت به
وأذكر النتيجة هنا إن شاء الله
RE: [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - as206em - 17-03-14
شكرا لك أخي الكريم
حلت المشكلة عندما استبدلت نص الاتصال
RE: [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - mohammed abdalsamed - 30-12-19
السلام عليكم اخي
ما شاء الله موضوع جميييل وجزاك الله كل خير
انا محمد عبدالصمد
طالب في قسم هندسة المعدات السنة الاخيرة
واريد مساعتك لو امكن
مشروعي عن تحريك كرسي الاسنان عن طريق الصوت باستخدام الاردوينو
بس ما لقيت شخص يساعد في PHP كود
مثل ما انت شارح
وهاذا ايميلي
navigator.on.line001@gmail.com
وشكرا
RE: [سلسلة التحكم] {4} - التحكم عن بعد بواسطة خدمة الويب - devante.celvin - 12-07-21
ما شاء الله موضوع جميييل وجزاك الله كل خير
Speed Test
|