الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

التصرف في الرسائل القصيرة

مغلق
بدأه بن العيد في 7 سبتمبر 2007 · 4 رد · 3,988 مشاهدة · في برمجة الأجهزة الكفية والمحمولة بالدوت نيت
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

كثيرا ما تفتح مواضيع متعلقة بالرسائل القصيرة. لذلك سأحاول تخصيص هذا الموضوع لتقديم أكبر حد ممكن من المعلومات المتعلقة بإرسال, قراءة والتصنت لإستقبال الرسائل القصيرة.

إرسال الرسائل القصيرة

post-91400-1189198578_thumb.jpg

SmsOpen ,SmsClose وSmsSendMessage وهي متوفرة في المكتبة sms.dll التي تحتوي العديد من الدوال الأخرى للتصرف في الرسائل القصيرة.

سأبدأ أولا بإستعراض الدوال الأصلية

 
  [DllImport("sms.dll")]
  private static extern IntPtr SmsOpen(String ptsMessageProtocol, IntPtr dwMessageModes, ref IntPtr psmshHandle, IntPtr phMessageAvailableEvent);

   [DllImport("sms.dll")]
   private static extern IntPtr SmsSendMessage(IntPtr smshHandle, IntPtr psmsaSMSCAddress, IntPtr psmsaDestinationAddress, IntPtr pstValidityPeriod, byte[] pbData, IntPtr dwDataSize, byte[] pbProviderSpecificData, IntPtr dwProviderSpecificDataSize, SMS_DATA_ENCODING smsdeDataEncoding, IntPtr dwOptions,  IntPtr psmsmidMessageID);

	 [DllImport("sms.dll")]
	  private static extern IntPtr SmsClose(IntPtr smshHandle);

هذه الدالة الرئيسية لإرسال الرسالة القصيرة وقد قمت بتقسيمها إلى ستة أجزاء:

 unsafe public static void SendMessage(string sPhoneNumber, string sMessage) {
													 IntPtr hSms = IntPtr.Zero;

													 try {
														 //======== 1. Open SMS component
										IntPtr res = SmsOpen(SMS_MSGTYPE_TEXT, (IntPtr)SMS_MODE_SEND, ref hSms, IntPtr.Zero);
														 if (res != IntPtr.Zero)
															 throw new Exception("Could not open SMS.");		
														 //======== 2. Retreive destination phone Nbr
														 Byte[] bDest = new Byte[516];
														 fixed (byte* pAddr = bDest) {
															 byte *pCurrent = pAddr;			  
															 Marshal.WriteInt32((IntPtr)pCurrent, (int)AddressType.Unknown);
															 pCurrent +=4;

															 foreach (byte b in Encoding.Unicode.GetBytes(sPhoneNumber)) {
																 Marshal.WriteByte((IntPtr)pCurrent, b);
																 pCurrent++;
															 }		

														  //===== 3. Encode Message to be sent 
															 Byte[] ProvData = new Byte[12];
															 byte[] bMessage = Encoding.Unicode.GetBytes(sMessage);
															 int nMsgSize = bMessage.Length;
														  //===== 4. Send SMS
	  res = SmsSendMessage(hSms, IntPtr.Zero, (IntPtr)pAddr, IntPtr.Zero, bMessage, (IntPtr)nMsgSize,  ProvData, (IntPtr)ProvData.Length, SMS_DATA_ENCODING.SMSDE_OPTIMAL, (IntPtr)SMS_OPTION_DELIVERY_NONE, IntPtr.Zero);
														  //===== 5. Manage exception 
															 if (res != IntPtr.Zero)
																 throw new Exception("SMS send failed.");		
														 }
													 }
														 //====== 6. Close SMS Component
													 finally {
														 if (hSms != IntPtr.Zero)
															 SmsClose(hSms);
													 }
												 }

1. كخطوة أولى لإرسال الرسائل القصيرة ينبغي فتح الجزء المكلف بذلك في حاسوب الكف/الهاتف الذكي :component . يمكن أن تفشل هذه المرحلة عند عدم توفر البطاقة في الهاتف أو أن المزود للخدمة لا يوفر صلاحية إرسال الرسائل القصيرة

2. في الجزء الثاني يتم قراءة رقم هاتف المرسل إليه وتشفيره : Encoding وفي ذلك تم إستعمال تعليمة خاصة قد تولد مشاكل عند الترجمة

fixed (byte* pAddr = bDest)

لذلك ينبغي تفعيل الإختيارAllow unsafe code في خصائص المشروع كما هو مصور في الصورة التالية:

post-91400-1189200692_thumb.jpg

3. في هذا الجزء من الدالة الرئيسية تتم قراءة نص الرسالة التي نود إرسالها ويتم تحويلها الى بايت

وأخيرا إرسال الرسالة القصيرة وتتبع نجاح العملية دون حدوث إستثناآت. ويبقى لنا غلق الجزء المهتم بهذه الخدمة والذي فتحناه في بداية الدالة

نلاحظ في الصورة الأولى وفي الكود (سي شارب) أني إستعملت رقم الهاتف +14250010001 هذا الرقم يستعمل في المحاكي. أي أرسلت الرسالة من و الى المحاكي.

Send_SMS_CS.rar

Send_SMS_VB.rar

أو من هذا الرابط

قراءة الرسائل القصيرة

في نفس المكتبة sms.dllتوجد دالة لقراءة الرسائل القصيرة وهي smsReadMessage. هذه الدالة مستعملة بشكل نادر في المشاريع المطورة بالدوت نت وذلك يعود الى صعوبة إستعمالها. وهي مستعملة أكثر في البرمجة باللغة سي (MFC)


private static extern IntPtr SmsReadMessage(IntPtr smshHandle,
long psmsaSMSCAddress,
string psmsaSourceAddress,
long pstReceiveTime,
byte[] pbBuffer,
long dwBufferSize,
long pbProviderSpecificBuffer,
long dwProviderSpecificDataBuffer,
long pdwBytesRead);
[DllImport("sms.dll")]
private static extern IntPtr SmsGetMessageSize(ref IntPtr hSms, ref uint dwMessageSize);
[DllImport("sms.dll")]
private static extern int SmsGetMessageStatus(IntPtr smshHandle, int smsmidMessageID, byte[] psmssiStatusInformation, int dwTimeout);
[DllImport("sms.dll")]
private static extern int SmsGetPhoneNumber(byte[] psmsaAddress);
[DllImport("sms.dll")]
private static extern int SmsGetSMSC(byte[] psmsaSMSCAddress);
[DllImport("sms.dll")]
private static extern int SmsGetTime(byte[] ptsCurrentTime, ref int pdwErrorMargin);
[DllImport("sms.dll")]

SMSIntercepter.zip

الحل الثاني لقراءة الرسال القصيرة يكون بإستعمال السي

post-91400-1189208272_thumb.gif

		 ...<pre class="code" id="ctl00_LibFrame_ctl04" space="preserve"> while (g_fContinue) {
					 rc = WaitForMultipleObjects (2, hWait, FALSE, INFINITE);
					 if (!g_fContinue || (rc != WAIT_OBJECT_0))
						 break;
					 // Point to the next free entry in the array
					 pNextMsg = &g_pMsgDB->pMsgs[g_pMsgDB->nMsgCnt];

					 // Get the message size
					 hr = SmsGetMessageSize (smshHandle, &dwSize);
					 if (hr != ERROR_SUCCESS) continue;

					 // Check for message larger than std buffer
					 if (dwSize > sizeof (pNextMsg->wcMessage)) {
						 if (dwSize > MAXMESSAGELEN) 
							 continue;
						 pIn = bBuffer;
						 dwInSize = MAXMESSAGELEN;
					 } else {
						 pIn = (PBYTE)pNextMsg->wcMessage;
						 dwInSize = sizeof (pNextMsg->wcMessage);
					 }
					 // Set up provider specific data
					 tpsd.dwMessageOptions = PS_MESSAGE_OPTION_NONE;
					 tpsd.psMessageClass = PS_MESSAGE_CLASS0;
					 tpsd.psReplaceOption = PSRO_NONE;
					 tpsd.dwHeaderDataSize = 0;
					 // Read the message
					 hr = SmsReadMessage (smshHandle, NULL, &pNextMsg->smsAddr, &st,
										  (PBYTE)pIn, dwInSize, (PBYTE)&tpsd, 
										  sizeof(TEXT_PROVIDER_SPECIFIC_DATA),
										  &dwRead);
					 if (hr == ERROR_SUCCESS) {
						 // Convert GMT message time to local time
						 FILETIME ft, ftLocal;
						 SystemTimeToFileTime (&st, &ft);
						 FileTimeToLocalFileTime (&ft, &ftLocal);
						 FileTimeToSystemTime (&ftLocal, &pNextMsg->stMsg);

						 // If using alt buffer, copy to std buff 
						 if ((DWORD)pIn == (DWORD)pNextMsg->wcMessage) {
							 pNextMsg->nSize = (int) dwRead;
						 } else {
							 memset (pNextMsg->wcMessage, 0, 
									 sizeof(pNextMsg->wcMessage));
							 memcpy (pNextMsg->wcMessage, pIn, 
									 sizeof(pNextMsg->wcMessage)-2);
							 pNextMsg->nSize = sizeof(pNextMsg->wcMessage);
						 }</pre> ....

ReadSms.rar

يمكن أيضا إعتماد هذا المثال

التصنت على الرسائل القصيرة

نعود الآن الى الدوت نت وتحديدا لأجيال ما بعد 2005 من حواسيب الكف والهواتف الذكية حيث تم تجاوز عدة نقائص في الإصدارات السابقة مثال وجود المجال Microsoft.WindowsMobile.PocketOutlook.MessageInterception الذي يوفر إمكانية التصنت على الرسائل القصيرة الواردة على حاسوب الكف/الهاتف الذكي بالكيفية التالية

MessageInterceptor sms ;

	 void Form1_Load( ... )
	 {
	   sms = new MessageInterceptor();
	   sms.MessageCondition = new MessageCondition(MessageProperty.Body, MessageComparisonType.StartsWith, "Foo" );
	   sms.InterceptionAction = InterceptionAction.NotifyAndDelete;
	   sms.MessageReceived += new MessageReceivedEventHandler( sms_MessageReceived );
	 }

و تعرفMessageReceived بالكيفية التالية:

void sms_MessageReceived(object sender, MessageReceivedEventArgs e)
	 {
	   SmsMessage message = (SmsMessage)(e.Message);
	   // ...
	 }

حصلت على كود التصنت على الرسائل القصيرة من هذا الرابط

المواضيع السابقة: الوجه الآخر لهواتف نوكيا , خفايا المكتبة coredll.dll, تنظيف حاسوب الكف لزيادة مساحة الذاكرة

في هذا الكود أهم الدوال المتعلقة بقراءة الرسائل القصيرة, هناك خلل ما في تعريف الدالة SmsReadMessageلذلك من يريد تجربة الكود عليه بمراجعته أولا.

تم تعديل هذه المشاركة بواسطة Ben_Laiid في 8 سبتمبر 2007 في 16:54

#2

أخي الكريم

أشكرك جزيل الشكر

لكن لي سؤال ماذا عن الجوالات الذكية N70 , .............

كذلك قمت بتحميل المصدر

لكني فوجئت بأنه بلغة غير الانجليزية

هل توجد نسخة انجليزية

#3

يا سلام عليك أخي الكريم .. يا هيك المشرفين يا أما بلا !

دروس و كتب مفيدة----------------------كتيب الإجرائيات المخزنةتعرف على اللغة Transact SQL <<-->> كتيب عن تنصيب قواعد البيانات Sql Server باللغة العربية كتيب عن إنشاء قواعد البيانات في SQL Server باللغة العربية <<-->> درس مع الأمثلة عن المؤشرات و التعامل معها في الـ T-SQLالعبارات الشرطية و الحلقات في T-SQL <<-->> شرح لبعض الـ Extended Stored Procedure استخدام مكتبات الـ Dot Net الخاصة بك في الـ Sql Server 2005 <<-->> التعامل مع المصفوفات من خلال الـ T-SQLتعابير الجداول الشائعة في SQL Server 2005 <<-->>الاتصال بالأداة SQL Server Management Studioحلول سريعة و لمحات برمجية --------------------------------التصدير إلى إكسل : طريقة أولى : طريقة بسطر واحد من الكود <<-->> طريقة ثانية : طريقة تحتاج إنشاء إجرائية مخزنةً تجهيز بيانات جدول بالصيغة XML تمهيداً لحفظها كملف <<-->> تصدير البيانات إلى ملفات نصية برمجياً إغلاق جميع الإتصالات المفتوحة بقاعدة بيانات محددة .. تمهيداً لاسترجاعها أو حذفها <<-->> الاستعلام بناء على وقت مخزن بالصيغة العربية ضمن حقل نصي ..حذف السجلات المتكررة و إبقاء عدد محدد منها في جدول.. <<-->> أسرع طريقة لحذف سجلات جدول كيف احصل على اسم جهازي والباسوورد باستخدام T-SQL <<-->> حشر أنواع الصور المختلفة في حقل من نوع Image باستخدام إجرائية مخزنة .كيف تعرف أنواع الصور المخزنة في حقل من نوع Image .. <<-->> إجرائيات مخزنة ببارامترات ديناميكية مفيدة جداً للاستعلامات استخدام رقم الحقل بدلاً من الإسم في عبارات الإستعلام <<-->> من هو أضخم الجداول في قاعدة بياناتي ؟معرفة زمن تنفيذ الإجرائيات ( لتختار الطريقة الأسرع بين إجرائياتك المخزنة ) <<-->> التعامل مع الـ Rules برمجياً الحصول على آخر صف في الجدول <<-->> قراءة ملفات XML باستخدام T-SQL برمجياً (مثال مرفق)سحب بيانات ملف إكسل إلى الـ SQL Server <<-->> تشفير النسخة الاحتياطية بكلمة مرور <<-->> التخلص من البيانات المكررة <<-->> حل مشكلة التاريخ الهجريDifferential Backup بالتعريف---------- لا إله إلا الله .. محمد رسول الله

أخوكم في الله..  Imad Ozone

#4

السلام عليكم

اقتباس
لكن لي سؤال ماذا عن الجوالات الذكية N70 , ............

الهواتف من نوع نوكيا تعتمد نظام تشغيل و لغة برمجة خاصة بها وهي السيمبيان.

اقتباس
كذلك قمت بتحميل المصدر

لكني فوجئت بأنه بلغة غير الانجليزية

لقد قمت بتعديل الموضوع وأضفت الكود مباشرة

اقتباس
يا سلام عليك أخي الكريم .. يا هيك المشرفين يا أما بلا !

شكرا أخي imadouzoun :)

#5

باي لغة هذا الكود

هذا الموضوع مغلق.

مواضيع مشابهة