PDA

View Full Version : بدست آوردن مورد منحصر به فرد از پنجره فعال در ويندوز



hero4000
سه شنبه 15 اردیبهشت 1394, 17:35 عصر
سلام دوستان
من براي گرفتن نام پنجره فعال در ويندوز از تابع
GetWindowText
استفاده مي كردم منتها مشكلي كه دارم اينه كه بعضي از پنجره ها اسم ندارند يا بعضيها اسم تكراري دارند
ميخواستم ببينم غير از اسم چه چيز منحصر به فردي از پنجره ها ميتونم بدست بيارم كه هميشه ثابت باشند و بتونم تشخيص بدم چه پنجره اي در ويندوز الان فعال است
ممنون از همه

hero4000
چهارشنبه 16 اردیبهشت 1394, 17:28 عصر
دوستان واساتيد محترم بنده همچنان منتظر پاسخ هستم

خواهشا تو اين سايت حداقل يكي از مشكلاتم حل بشه

javad dehnavi
پنج شنبه 17 اردیبهشت 1394, 22:47 عصر
سلام و احترام!



For Each p As Process In Process.GetProcesses
string = p.ProcessName ' نام برنامه
string = p.MainWindowTitles ' تایتل پنجره اصلی برنامه
date = p.StartTime ' زمان شروع
p.Kill() ' بستن برنامه
string = p.CloseMainWindow() ' بستن پنجره اصلی برنامه
p.WaitForExit() ' انتظار برای بسته شدن نرم افزار
integer = p.VirtualMemorySize ' میزان استفاده رم

Next



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

hero4000
دوشنبه 21 اردیبهشت 1394, 10:08 صبح
سلام دوست عزيز
ممنون از پاسختون متاسفانه من چند روزي اينترنت نداشتم سر بزنم
من ميخوام با توجه به فرمي كه در ويندوز بازه يك قسمت از برنامم رو فعال كنم منتها مشكلي كه دارم اينه كه اون فرمها را من صدا نمي زنم كه شماره و مشخصات پروسس رو داشته باشم
و دوم اين كه پنجره هاي باز شده اكثرا از يك برنامه هستند و فرمهاش اسم ندارند كه يتونم با عنوان فرم تشخيص بدم چه پنجره اي باز هستش
بازم ممنون

javad dehnavi
چهارشنبه 23 اردیبهشت 1394, 15:55 عصر
اگه دوست دارید برنامه ای که میخواید فرم های مختلفش رو تشخیص بدید بگید تا اگه تونستم کمکتون کنم

hero4000
پنج شنبه 24 اردیبهشت 1394, 13:20 عصر
دوست عزيز برنامه من يك برنامه كمكي جهت برنامه هاي ديگه هست و با توجه به برنامه فعال و فرم فعال در برنامه فعلي قسمت خاصي از درخت برنامه من آماده عمليات ميشه كه من ميخوام كاربر خودش هر شاخه از درخت برنامه من رو به يك فرم خاص از برنامه هاي خودش نسبت بده و به محض فعالسازي برنامه من خود شاخه مورد نظر از درخت با توجه به تنظيم قبلي كاربر آماده عمليات بشه .
من تا حالا از عنوان فرم برنامه هاي ديگه براي نشانه گذاري كاربر استفاده مي كردم ولي متوجه شدم كه بعضي از برنامه ها از فرمهاي بدون عنوان براي عملياتشون استفاده مي كنند . واسه همين حالا دنبال مورد شاخص ديگه اي در فرمها مي گردم تا بتونم نشانه گذاري رو بر حسب همون انجام بدم.

hero4000
سه شنبه 05 خرداد 1394, 07:15 صبح
خيلي جالبه من چندين ساله توي اين سايت عضوم ولي شايد توي اين همه پستي كه فرستادم يك يا دوبار جواب گرفته باشم مابقي سوالهام مثل اين بي جواب مونده

مديران محترم هم كه ظاهرا تعطيل كردند:افسرده::افسرده:

javad dehnavi
جمعه 29 خرداد 1394, 13:25 عصر
132391


If Process.GetProcessesByName("notepad").Count = 0 Then
Label1.ForeColor = Color.Red
Else
Label1.ForeColor = Color.Green
End If

hero4000
دوشنبه 01 تیر 1394, 15:01 عصر
سلام دوست عزيز
بازم صد رحمت به شما
مديران كه مثل اينكه همه استعفا دادند و سايت متروكه شده
اون كدي كه دادين خيلي خوبه ولي به درد من نميخوره
نگاه كنيد به توضيحاتم
من ميخوام الان يك پنجره اي رو كه بازه رو (كه مربوط به برنامه خودم نيست)با يك شاخصه توي بانكم مشخص كنم و بعدا اگه اين پنجره باز شد با توجه به اون شاخصه چك كنم و اگه منطبق بود عنليات خاصي رو انجام بدم.
مشكلم اينجاست كه قبلا از عنوان پنجره استفاده ميكردم و اين كار رو ميكردم ولي حالا به پنجره هاي بدون عنوان برخوردم و موندم براي تشخيص اونها چكار ميتونم بكنم.

Saman_12
چهارشنبه 03 تیر 1394, 16:59 عصر
پنجره ها یه سری ویژگی هایی دارن که باید باهشون آشنا باشید مثلا همین کپشن ,نام کلاس و ... (این دوتا بیشترین استفاده رو دارند).
برای دقیق تر بودن میشه از چک کردن نام پروسه و محل ذخیره فایل اجرایی هم استفاده کرد(GetWindowTheardID فکرکنم این بود یا یه چیز مشابه ش).
حالا که کپشن خالیه خوب کپشن رو خالی میزاریم (یا NULL میفرستیم) جاش از کلاس و استیال(این یکی زیاد قابل اعتماد نیست) میشه استفاده کرد نمیدونم تابعی برای تشخیص آیکون پنجره هست یا نه (که احتمالا هست) که باهاش آیکون رو طتبیق بدی جاش میتونی راحت مکان پنجره رو بدست بیاری و از محل آیکون یا هر ویژگی منحصر به فرد بصری دیگه عکس بیگیری و با یه درصدی مطابقت بدی.

یه سرچ تو گوگل کنی همه توابعی که لازمت میشه رو میتونی پیدا کنی.

hero4000
شنبه 06 تیر 1394, 15:43 عصر
سلام دوست عزيز
من هم دنبال مورد منحصر به فردي هستم كه هميشه تكراري باشه
جستجو هم خيلي زياد كردم چيزي بدست نياوردم
متاسفانه نام كلاس رو هم قبلا تست كردم .نميدونم من بلد نبودم يا مشكل از نام كلاسه ؟ چون هر دفعه برنامه رو اجرا ميكرد نام كلاس تغيير ميكرد . همچنين چند تا پنجره مختلف توي يك برنامه داراي نام كلاس يكسان بودند . اگه بخوام كپشن رو هم خالي بزارم خوب پنجره ها با هم قاطي ميشن چون ممكنه چند تا پنجره با كپشن خالي باشه.
لطفا اگه زحمتي نيست يك نمونه برنامه اي يا راهنمايي بهتري محبت كنين ممنون ميشم
البته پيشينه شما رو من سال 89 دارم اون زمان توي خيلي از تاپيكها به دوستان كمك ميكردين.

Saman_12
چهارشنبه 10 تیر 1394, 01:37 صبح
این نمونه هر جوری دوست دارید عوضش کنید : (برای ارسال متن به api از stringbuilder استفاده کنید من با استفاده از string به مشکل برخوردم)
-به جای دات نت همین رو با C++‎ یا delphi بنویسید خیلی راحت ترید (مخصوصا نوع داده برای ارتباط با api)-

Saman_12
چهارشنبه 10 تیر 1394, 01:54 صبح
اولین child رو به عنوان مشخصه منحصرد به فرد گرفتم شما میتونی دنبال یه child خاص باشی که تو بقیه نیست

hero4000
چهارشنبه 10 تیر 1394, 08:24 صبح
با سلام و تشكر فراوان از شما
من برنامتون رو دانلود كردم و تست كردم
مشكل من هم دقيقا همين موضوعه كه اگه دقت كنين اون پنجره هايي كه باز ميشه هر دفعه شماره هاي جديد دارند و من ميخوام مثلا يه جا ذخيره كنم كه اگه برنامه نوتپد فعال بود فلان قسمت برنامم فعال يشه كه البته اين فعال سازي همه دست خود كاربره و كاربر خودش تعيين ميكنه در صورت فعال بودن فلان فرم چه قسمتي فعال بشه.
مشكل منم تو همين بخشه يعني اون فرما كه باز ميشه هر دفعه يه شماره به خودش ميگيره و مثل عنوان فرم نيست كه هميشه ثابت باشه(هرچند تكراري باشه) حالا من ميخوام يه چيز ديگه اي مثلا نام فرم به جاي عنوان فرم رو ذخيره كنم كه هميشه يك مقدار باشه و هر موقع كاربر براي فرم قسمتي از برنامه رو تنظيم كرد هميشه همون قسمت فعال شه
حالا ميدونم هر فرم غير از عنوان يك اسم هم داره ولي نميدونم چطوري اسم فرم رو ميشه بدست آورد يا يه چيز مخصوص ديگه از فرم رو
بازم خيلي خيلي از شما كه به من كمك ميكنين ممنونم

Saman_12
چهارشنبه 10 تیر 1394, 09:58 صبح
اگه منظورتون از اون شماره ها هندل هست که بله هر دفعه تغییر میکنه و شما اول با همون مشخصه ای که عرض کردم باید هندل فرم رو پیدا کنید اگر موفق شدید (فکرکنم یا پاسخ غیر منفی بود یا صفر) یعنی فرم بازه اگر نه هم که بسته است.
درمورد نام فرم هم مطمئن نیستم اما به نظر میاد فقط توی محیط ویژوال وحود داره (موقع کد نویسی) نه وقتی برنامه کامپایل شه!
بنده که گفتم اول تمام پنجره هایی که کلاس موردنظر شما رو دارند با هر کپشنی (nothing) پیدا کنید بعد هندل اولین کنترل (یا یک کنترل خاص) زیر مجموعه رو پیدا کنید و کلاس و کپشن رو دوباره تطبیق بدید.

نمونه ای که گذاشتم دقیقا همین کار رو میکنه.

اگر خواستید از یک کنترل خاص استفاده کنید (نه اولی) میتونید با findwindowex یا enumchild اینکار رو انجام بدید.

hero4000
پنج شنبه 11 تیر 1394, 14:55 عصر
دوست عزيز من اصلا نميدونم پنجره هدف اصلا چه نوع كنترلي توش هست كه بخوام چك كنم
مثلا يكي از كابرام نياز داشت موقعي كه نوت پد بازه قسمت خاصي از برنامه اجرا شه
شايد يكي ديگه بخواد موقعي كه فايرفاكس بازه يه قسمت از برنامه اجرا شه
شايدم يكي بخوا موقعي كه قسمت تنظيمات توي آي دي ام بازه يه بخش اجرا بشه
همه اين انتخابها دست كاربر ميخوام باشه

Saman_12
پنج شنبه 11 تیر 1394, 22:23 عصر
فکرکردم واسه یه برنامه خاص هست!
از بالا به پایین برای هر پنجره شما میتونید اینها رو چک کنید :

1.Process -> Name/*(file)Location
2.Window -> ClassName/*Title/*Child-Count
3.اگر Child-Count > 0 بود : *First-Child

در انتها هم به کاربر این حق انتخاب رو بدید که بتونه یک کنترل از روی پنجره مورد نظر که میدونه caption ش و وضعیت قرار گیریش تغییر نمیکنه انتخاب کنه - شما هم کلاس و نام و نحوه قرار گیری (منظورم اینه که خود کنترل شاید child یکی از child های پنجره باش به صورت تو در تو شما باید parent رو level به level بدست بیارید تا برسید به پنجره اصلی) رو ذخیره کنید.

این هم یک لیست از API های هر مرحله :
1 :
GetModuleBaseName OpenProcess GetProcessImageFileName GetModuleFileNameEx و البته کلاس Process دات نت.
3, 2 :
GetClassName GetWindowText GetWindowTextLength FindWindow FindWindowEx EnumWindows EnumChildWindows GetParent

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

فعلا همین ها به نظرم میرسه موفق باشید!

hero4000
یک شنبه 14 تیر 1394, 08:07 صبح
جناب سامان
من خيلي متوجه اون دستوراتي كه نوشتيد نشدم
نگاه كنيد برنامه من نميدونه چه پروسسي را ميخواد بررسي كنه فقط پنجره فعال رومن ميگيرم
نگاه كنيد: من يك راهنماي كامل براي همه برنامه ها نوشتم كه سوپروايزر مجموعه ميتونه راهنمايي واسه همه قسمتهايي كه كاربرا كار ميكنند بنويسه (چون تعداد نيروها زياده و قسمتهاي كاري زياده و نيروها مرتبا جابجا ميشند نميتونه به تك تك كاربرا توضيح بده چجوري با اين قسمت كار كنند)
خوب حالا من چه كار كردم يك برنامه راهنما نوشتم كه مدير راهنماييهاي لازم براي هر فرم رو توي برنامه درج كرده و كاربر هر موقع توي هر قسمت از كامپيوتر بود و نياز به راهنمايي بود كافيه كليد Ctrl+F1 رو فشار بده تا صفحه راهنماي همون قسمت باز بشه
دقت كنيد كه برنامه هايي كه قراره كاربرا باهاش كار كنند مال چند برنامه نويس متفاوته و بعضيهاش فرمهاي اكسل هستش كه من قبلا به عنوان برنامه ها نگاه ميكردم و صفحه راهنماي همون بخش رو توي برنامم باز ميكردم ولي حالا به موردي خوردم كه بعضي از فرمها عنوان ندارند و من نميدونم چجوري راهنماي اون فرم رو تشخيص بدم . و روي صفحه براي كاربر بيارم
اگه توضيحاتم كامل نيست برماييد بازم توضيح بيشتري بدم
ممنون

Saman_12
چهارشنبه 17 تیر 1394, 00:35 صبح
این مثالی از روال دفعه اول هست که سوپروایزر میخواد پنجره رو انتخواب کنه تا توضیحاتی براش بنویسه :

1 : خوب اول Handle پنجره اصلی مورد نظر رو بدست میارید که به نظر میاد با GetActiveWindow این کار رو میکنید (یا شاید هم از WindowFromPoint) زیاد مهم نیست از چه روشی فرض میکنیم شما هندل رو دارید.
حالا با GetWindowThreadProcessId و وهندل پنجره ای که بدست آوردیم pid مربوط به پروسس رو بدست میاریم (خروجیش ترد id ه یکی از پارامتراش پروسس id ه نباید این دوتا رو اشتباه گرفت) بعد هم با OpenProcess یه هندل از پروسس بدست میاریم و با اون هندل به وسیله GetProcessImageFileName اسم فایل اجرایی یا پروسس (درست یادم نیست کدوم) رو بدست میاریم و ذخیره میکنیم.
-با هندل پروسس میشه آدرسس فایل اجرایی رو هم بدست آورد-

3و2 : با همون هندل پنجره که دفعه اول گرفتیم با
GetClassName GetWindowText نام کلاس و احتمالا کپشن اگر ثابت باشه (* برای همینه که مشخص نیست ثابته یا نه) رو بدست اورده بعد ذخیره میکنیم.
برای child-count هم فعلا راهی جز شمردن تعداد دفعات اجرای callback ی که به
EnumChildWindows میدید نمیدونم. (درضمن شاید تعداد child ها ثابت نباشه).
از GetWindow یا FindWindowEx هم برای پیدا کردن اولین child استفاده کنید و کلاس و کپشن اون رو هم ذخیره کنید.

برای فهمیدن اینکه اون پنجره رو پیدا کنید هم کافیه همین روال رو روی پنجره اکتیو یا پنجره ای که در مختصات خاصی هست (windowfrompoint) انجام بدید و چیز هایی که ذخیره کردید رو با انوهایی که برای پنجره فعال بدست میارید مقایسه کنید.
-البته از enumwindows و ... هم میشه استفاده کرد که به نظر میاد تو مورد شما زیاد به کار نیاد-

درمورد API ها و نحوه استفاده هم MSDN به طور کامل توضیح داده فقط کافیه صدا کردن اون api در vb رو از نت پیدا کنید (www.pinvoke.net
)
اگر هم مشکلی بود مطرح کنید.
مورد دیگه ای یادم اومد همینجا اظافه میکنم.

hero4000
شنبه 20 تیر 1394, 09:27 صبح
با تشكر فراوان از شما من با توجه به توضيحاتتون جلو رفتم ولي ديگه وسطاي برنامه سردرگم شدم.
نام و آدرس فايل اجرايي رو بدست آوردم ولي مشكل اينه كه من يك برنامه اتوماسيون توي سيستمهام دارم كه حدود 30 فرم مختلف داره و شايد 10 تا از اونها بدون عنوان هستند
با تابع
GetClassName هم هر دفعه يك كدي بهم ميده و نام اصلا نميده.
جسارتا ميشه يك تكه كوچولو برنامه برام بنويسين شايد من توي تعاريف متغيرهام يا استفاده از توابع مشكلي دارم.
بي زحمت وقتي نوشتين برنامه هدف را ببندين و باز كنين ببينين مقداري كه ميده مثل دفعه قبل هستش
شرمنده ميدونم توقعم زياديه
بازم ممنون

Saman_12
شنبه 20 تیر 1394, 21:23 عصر
کد مربوط به همین قسمت رو هرچقدر نوشتید بذارید همین رو اگر بشه درست میکنیم.

hero4000
دوشنبه 22 تیر 1394, 07:12 صبح
دوست عزيز من همون روز كه مطالب شما رو ديدم يك پروژه باز كردم دستورات رو توش نوشتم و چون هر كاري كردم به نتيجه نرسيدم ديگه پروژه رو ذخيره نكردم
اگه شما فقط قسمت گرفتن همون مورد منحصر به فرد رو بنويسين ممنون ميشم ذخيره سازي و مقايسه رو نميخوام اونها رو خورم مينويسم
بازم ممنون

Saman_12
دوشنبه 22 تیر 1394, 15:14 عصر
حتما مقداری که توابع api برمیگردونند رو چک کنید که مشکلی پیش نیاد , و بهتره برای پنجره هایی مثل اکسل (همه پنجره ها) بالاترین parent رو بدست بیارید (فکر کنم آخری برای همه میشه دکستاپ که شما یه لول قبلش رو لازم دارید یا میشه اینطور طراحی کرد که بالترین پنجره حتما باید مربوط به پروسس اولین پنجره باشه (pid)) :

Saman_12
سه شنبه 23 تیر 1394, 17:56 عصر
برای اکسل فعلا خط 16 (Me.Handle = handle) از cls_winfinder رو به Me.Handle = GetAncestor(handle, 2) تغییر بدید.
و به mdl_api API زیر رو اظافه کنید :
Public Declare Function GetAncestor Lib "user32.DLL" ( _
ByVal hwnd As Integer, _
ByVal gaFlags As Integer) As Integer
اگر میخواید کار دقیق تر باشه باید parent رو level به level ذخیره کنید.

hero4000
چهارشنبه 24 تیر 1394, 18:32 عصر
دوست عزيز من برنامه رو باز كردم منتها فرم وركي كه دارم و برنامه اصليم رو نوشتم 2 هستش ولي تا فرم ورك 4 هم كه داشتم تست كردم برنامه خط زير رو خطا ميده و اصلا ران نميشه
ميشه اين خط رو بر مبناي فرم ورك 2 بنويسين تا من هم تو برنامم بتونم استفاده كنم



For Each pr As PropertyInfo In wf.GetType.GetProperties()


Console.WriteLine(pr.Name & vbTab & "->" & vbTab & pr.GetValue(wf))
Next

در ضمن با فرم ورك 4.5 هم بنامه رو اجرا كردم هيچ عملي انجام نميداد
ممنون

Saman_12
چهارشنبه 24 تیر 1394, 23:10 عصر
دوست عزيز من برنامه رو باز كردم منتها فرم وركي كه دارم و برنامه اصليم رو نوشتم 2 هستش ولي تا فرم ورك 4 هم كه داشتم تست كردم برنامه خط زير رو خطا ميده و اصلا ران نميشه
نه اون هیچی نیست کلا حذفش کنید حوصله نداشتم نام تک تک پروپرتی ها رو بنویسم اینجوری نوشتم این حلقه رو کلا پاک کنید کاری جز نمایش مقدار پروپرتی های کلاس cls_winfinder انجام نمیده.(همون اطلاعتی که بدست میاره)


در ضمن با فرم ورك 4.5 هم بنامه رو اجرا كردم هيچ عملي انجام نميداد

شما روی set window point راست کلیک رو نگه دارید و روی هر پنجره ای که خواستید رها کنید بعد get information فعال میشه که با .net 4.5 اطلاعات رو تو output نمایش میده
پروپرتی های کلاس رو چک کنید. یه نگاه هم به کد ها بندازید

hero4000
دوشنبه 29 تیر 1394, 12:42 عصر
سلام دوست عزيز
خيلي ممنون از محبتتون
اين اطلاعاتي كه زحمت كشيدين خيلي خوبه و البته من قبلا بصورت پراكنده به اونها رسيده بودم ولي بازم تست كردم توي حدود 8 تا از فرمها بجز Pid , Handle مابقي اطلاعات فرم تكراريند(البته اون دو تا هم كه در هر بار اجرا تغيير ميكنند)
اگه ميشد اسم اصلي فرم (نه عنوان فرم) رو بدست آورد واقعا منحصر به فرد بود و خيلي عالي ميشد
بازم از زحمتي كه بهتون دادم عذر ميخوام ممنون

Saman_12
دوشنبه 29 تیر 1394, 13:32 عصر
تنها چیزی که به نظرم میرسه همون تصویر از قسمت خاصی از فرم که تغییر نکنه با یک درصد مطابقت معقول هست و همینطور یک child خاص که تا parent ش به صورت level به level کپشن و کلاس رو بدست بیارید و چک کنید تو فرم اکتیو این توالی رسیدن به اون کنترل وجود داره یا نه.(یعنی تعداد child ها و کلاس و کپشن اولین child برای همه شون یکسان هست؟خب تفاوت اون فرم ها تو چی هست چه فرقی دارند رو همون فرق تمرکز کنید شاید برای بقیه برنامه ها هم بدرد خورد.)
درمورد نام فرم فکر نمیکنم این نام واقعی باشه یا حداقل به سادگی قابل دسترس اگر برنامه دات نت باشه با system.reflection شاید بشه نام فرم رو بدست آورد ...
به هرحال اگه چیزی درمورد این موضوع پیدا کردم حتما تو همین تایپیک قرار میدم به نظر موضوع جالبی هست.