# Native Code > برنامه نویسی در Delphi > مباحث عمومی دلفی و پاسکال > سوال: روشن شدن کامپیوتر از حالت standby با تنظیم زمان

## daneshmand1354

با سلام کدی را میخواستم که سیستم در ساعت خاصی از حالت standby خارج بشه و روشن بشه - به عبارت دیگر وقتی سیستم را استند بای می کنیم در ساعت خاصی روشن بشود-لطفا کد دلفی 7
با تشکر

----------


## vcldeveloper

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

----------


## zidane

من قبلا این برنامه رو برای خودم نوشتم که توی ویندوز اکس پی درست کار می کنه ولی فکر نمی کنم توی ویندوز سون جواب بده

----------


## AliReza Vafakhah

در پی صحبت های آقای کشاورز سوالی برام پیش امد که نرم افزار Auto PowerOn & Shutdown  از چه تکنیکی استفاده میکنه که حتی سیستم اگر درحالت Hibernate هم باشه به راحتی سر وقت (زمان تنظیم شده توسط کاربر) روشن میکنه ، حالا با چه تکنیکی من خبر ندارم.

----------


## سعید صابری

البته شاید حرف من منطقی نباشه

ولی شاید بشه تنظیمات wakeup در بایوس تغییر داد از طریق برنامه

----------


## vcldeveloper

> ولی شاید بشه تنظیمات wakeup در بایوس تغییر داد از طریق برنامه


میشه؛ برنامه های مختلفی هستند که می تونند تنظیمات خاصی رو در بایوس تغییر بدند؛ مثل برنامه های اورکلاک سی پی یو.

----------


## daneshmand1354

> من قبلا این برنامه رو برای خودم نوشتم که توی ویندوز اکس پی درست کار می کنه ولی فکر نمی کنم توی ویندوز سون جواب بده


با تشکر از شما دوست گرامی جناب زیدان مشکل حل شد.
من با این برنامه صبحها از خواب بیدار میشم و ان شاء الله این تکه برنامه شما دارای اجر معنوی نیز خواهد بود
در ضمن اگر لطف کنید میخواستم این برنامه بعد از روشن کردن کامپیوتر یک فایل صوتی را نیز اجرا کند
ولی برنامه شما سطح بالا بود و من بی سواد 
و نفهمیدم کجا باید این دستور را اضافه کنم
ضمنا سیستم پسورد داره و وقتی سیستم روشن می شه به صفحه ورود رمز ویندوز وارد می شه و در نتیجه نمی شه از statup ویندوز برای اجرای فایل صوتی استفاده کرد

----------


## moein+

> من قبلا این برنامه رو برای خودم نوشتم که توی ویندوز اکس پی درست کار می کنه ولی فکر نمی کنم توی ویندوز سون جواب بده





> با تشکر از شما دوست گرامی جناب زیدان مشکل حل شد.


یعنی این برنامه الان کار کرده؟ این برنامه رو یکم توضیح بدید جناب زیدان!!!




> میشه؛ برنامه های مختلفی هستند که می تونند تنظیمات خاصی رو در بایوس تغییر بدند؛ مثل برنامه های اورکلاک سی پی یو.


یعنی برای تغییرات یا دستیابی به یه سری از پارامترهای خیلی سطح پائین سیستم باید یه API وجود داشته باشه؟ 

خب توی اکثر BIOS ها بخشی به نام Power-On By Alarm یا RTC وجود داره که یه زمان رو برای روشن شدن خودکار میگیره حالا اگر روشی وجود داشته باشه که هنگامی که OS که Win باشه در حال اجراست از طریق یه سری SysCall بشه این مشخصات رو تغییر داد ...

----------


## Felony

> یعنی این برنامه الان کار کرده؟ این برنامه رو یکم توضیح بدید جناب زیدان!!!


خیر ؛ این برنامه کار میکنه ولی نه کاری که هدف این تاپیک بوده و *غیر ممکن هم هست !*
ایشون برداشتن یک Message Handler برای پیغام WM_PowerBroadcast نوشتن و به این وسیله تشخیص دادن که یک Power Event رخ داده و سیستم قصد داره Hibernate, Standby یا ... بشه ؛ بلافاصله که همچین پیغامی به برنامه رسید یک WaitableTimer ساختن و گفتن مدت زمانی که کاربر خواسته صبر کن ( مدت زمان وارد شده توسط کاربر - زمان فعلی سیستم ) و به جای اینکه اجازه بدن سیستم به حالت خواب بره از این کار جلوگیری کردن و عوضش به مانیتور اجازه روشن شدن تا زمان وارد شده رو ندادن :

SetThreadExecutionState(ES_DISPLAY_REQUIRED);

 :لبخند: 




> یعنی برای تغییرات یا دستیابی به یه سری از پارامترهای خیلی سطح پائین سیستم باید یه API وجود داشته باشه؟ 
> 
> خب توی اکثر BIOS ها بخشی به نام Power-On By Alarm یا RTC وجود داره که یه زمان رو برای روشن شدن خودکار میگیره حالا اگر روشی وجود داشته باشه که هنگامی که OS که Win باشه در حال اجراست از طریق یه سری SysCall بشه این مشخصات رو تغییر داد ...


API برای این کار در User Mode نیست ؛ اون برنامه های یکسری کد Kernel Mode اجرا میکنن .

----------


## moein+

> API برای این کار در User Mode نیست ؛ اون برنامه های یکسری کد Kernel Mode اجرا میکنن .


بسیار عالی و ممنون، خب اگر هدف ما پاسخگویی به سوال طرح شده در این تاپیک و یا یه موضوع کلی تر مثل نحوه عملکرد نرم افزار معرفی شده توسط آقای وفاخواه (Auto PowerOn & Shutdown) باشه چی؟
در این حالت شما معتقدید که این نرم افزار طبق گفته خودتون یکسری کد رو در حالت KernelMode داره اجرا میکنه ؟ (توجه داشته باشید نرم افزار فوق کارکرد صحیحی داره و در ضمن نگارش پرتابل شدش هم هست ...).
خب اگر جواب این سوال مثبته، حالا KernelMode!! چطور و چجوری؟ هر قدر هم که پیچیده باشه قابل طرح که هست؟

----------


## بهروز عباسی

> خب اگر جواب این سوال مثبته، حالا KernelMode!! چطور و چجوری؟ هر قدر هم که پیچیده باشه قابل طرح که هست؟


سلام دوست عزیز با دلفی نمیشه کرنل مد برنامه نوشت باید با c بنویسی و در کل کاریست مشکل

----------


## بهروز عباسی

این لینک ها در باره درایور نویسی و برنامه نویسی کرنل مد کمکت میکنه 
https://barnamenevis.org/showthread.p...8C%D8%B3%DB%8C

https://barnamenevis.org/showthread.p...8C%D8%B3%DB%8C

https://barnamenevis.org/showthread.p...8C%D8%B3%DB%8C

https://barnamenevis.org/showthread.p...A7%D8%B2%DB%8C

http://www.shabgard.org/forums/showthread.php?p=144248

http://www.osronline.com/

http://www.driverentry.com/resources/helloworld.htm

http://arcsinos.blogfa.com/post-181.aspx

----------


## moein+

ممنون از توجه شما جناب sam7sam7، ولی فکر نمی کنید راه حل های ساده تری هم باید وجود داشته باشد؟
در برخورد با چنین موضوعی ابتدا رفرنس معتبری که ویرایش اطلاعات CMOS رو در حیطه دستورات اجرا شونده در حالت Kernel قرار دهد چیست؟ (الان تو اصل قضیه رفتن سراغ KernelMode تشکیک کردم! :))
در ثانی برای کاربران برنامه نویس و توسعه دهنده با سطح بالاترین زبان های برنامه نویسی هم امروزه اینچنین موانعی با راه حل های سریع تری مانند استفاده از یکسری ابزارهای میانی برداشته شده و البته موضوع این تاپیک هم موضوع خیلی تخصصی مانند توسعه یک راه انداز سخت افزار نیست که منحصر به آن سخت افزار شود، اگر خواندن و نوشتن اطلاعات CMOS مد نظر باشد باید به صورت عملکردی کلی دارای راه حل هایی عامیانه تری باشد به لینک زیر نگاهی بیاندازید!؟
http://www.ocworkbench.com/2002/ecs/k7s5aguide/CHFSB%20FAQ1.htm

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

----------


## daneshmand1354

بر خلاف تصور اولیه من برنامه آقای زیدان گاهی جواب میده و گاهی جواب نمی ده
که نشان از اشکال اساسی این برنامه است
در ثانی دوستان اگر بتوانند در delphi XE هم ، جواب این سوال را بدهند ممنون می شوم
وگرنه مجبور می شوم در سایر تالارها سوال را مطرح کنم

----------


## moein+

> بر خلاف تصور اولیه من برنامه آقای زیدان گاهی جواب میده و گاهی جواب نمی ده
> که نشان از اشکال اساسی این برنامه است
> در ثانی دوستان اگر بتوانند در delphi XE هم ، جواب این سوال را بدهند ممنون می شوم
> وگرنه مجبور می شوم در سایر تالارها سوال را مطرح کنم


البته همونطور که جناب تاجیک توضیح دادن اون برنامه از لحاظ منطقی مشکل داره و روش درستی در اون پیاده نشده، اما در مورد نگارش دلفی فکر نمی کنم موضوع مهمی باشه، احتمالاً نگارش ویندوز منظور مهمتره...
روند منطقی کار هم تا جایی که من پیدا کردم به این شرح هست، در هر یک از وضعیت های Suspend ،Hibernate و Shutdown این امکان فراهم نیست که قطعه ای از کدی که ما نوشته ایم اجرا شود، در هر یک ازین زمان ها تنها نرم افزار فعال و موثر نرم افزار BIOS سیستم است و یک منبع وقفه (حتماً دیدید برخی سیستم ها با حرکت موس یا فشردن کلیدی از کیبرد روشن می شوند...) که در این جا همان مولد زمان سیستم یا RTC هست، تغریباً همه نرم افزارهای بایوس امروزه این قابلیت را دارند که زمانی را در بخش تنظیمات خود به عنوان Power-On by Alarm(Award) یا Resume On RTC Alarm(American Mega Trend) برای روشن کردن سیستم در زمانی از پیش تعیین شده تنظیم کنند...

پس تنها راهی که به نظر می رسد وجود دارد این هست که ما از طریق اجرای قطعه کدی در حالت عادی در ویندوز و در سیستمی که در حال کار هست تغییراتی در این تنظیمات انجام دهیم، اما آنچه باید تغییر کند تنظیماتی است که BIOS در محل نگهداری تنظیمات خود یعنی CMOS ذخیره می کند، پس بیت و بایتی در فضای ذخیره سازی CMOS باید تغییر پیدا کند، اما چه بیت و بایت هایی و چگونه؟

----------


## بهروز عباسی

فکر کنم با اسمبلی inline بشه 
مثلاً این کد اون جور که از نامش برمیاد تنظیمات CMOS رو پاک میکنه(الان دلفی دم دستم نیست که تست کنم)

procedure ClearCMOS;
asm
       MOV AX,0h        { 0 hex start of CMOS memory address }
@L1:   OUT 70h,AX       { Goto address of CMOS memory specified by the contents of Accumulator }
       MOV BX,AX        { Save contents of Accumulator (OUT instruction can only use Accumulator) }
       MOV AX,0h        { Put 0 hex data into CMOS memory }
       OUT 71h,AX       { Put 0 hex data into CMOS memory }
       MOV AX,BX        { Restore contents of Accumulator }
       INC AX           { Add 1 to contents of the Accumulator }
       CMP AX,03Fh      { Remmember 3F hex equals 63 Dec Have we
//put 0 hex in CMOS memory addreses from 0 Dec to 63 DEC ? }
       JNZ @L1          { Has the L1 loop run 64 times? }
end;

----------


## بهروز عباسی

> پس تنها راهی که به نظر می رسد وجود دارد این هست که ما از طریق اجرای قطعه  کدی در حالت عادی در ویندوز و در سیستمی که در حال کار هست تغییراتی در  این تنظیمات انجام دهیم، اما آنچه باید تغییر کند تنظیماتی است که BIOS در  محل نگهداری تنظیمات خود یعنی CMOS ذخیره می کند، پس بیت و بایتی در فضای  ذخیره سازی CMOS باید تغییر پیدا کند، اما چه بیت و بایت هایی و چگونه؟


این لینک ها رو ببین برای خوندن و نوشتن روی bios کمکت میکنن(بیشتر با زبان C مثال زدن )

http://www.programmersheaven.com/2/Art_C_1

این یه ماژول با دلفی 

http://www.koders.com/delphi/fid17EB...25C.aspx?s=ftp

اینم یه لینک دیگه 
http://www.dennisbabkin.com/php/faq.php?what=wosb

----------


## moein+

> اینم یه لینک دیگه 
> http://www.dennisbabkin.com/php/faq.php?what=wosb


یک گام به عقب ...
خب همین لینک و پیگیری اون و مطالبی که در رابطه با شی Waitabletimer وجود داره نشون میده این تایمر قابلیت Wake-Up سیستم رو از تمامی حالت های Sleep، Hybrid Sleep  و Hibernate دارا هست... !

واین یعنی اگر برنامه ای که نمونه ای از این تایمر رو ساخته و درست مقدادهی و فعال کرده، باز باشه و سیستم به یکی از حالت های مذکور بره، این تایمر قابلیت Wake-Up کامل سیستم رو خواهد داشت.

من هر چی گشتم بفهمم از لحاظ پیاده سازی درونی چطور این کار رو انجام میده، نتیجه ای حاصل نشد ولی خب امتحان کردم در هر سه حالت فوق کاملاً کار میکنه حتی در حالت Hibernate که سیستم اطلاعات رم رو، رو هارد قرار میده و کاملاً خاموش میشه!  فقط وقتی سیستم Shutdown میشه از اونجایی که برنامه و بالطبع نمونه اشیاء اون تخریب میشن دیگه کار نمیکنه (حتی اینم تست کردم!)
البته همه اینها دلیل نمیشه اون برنامه ای که در ابتدا مطرح شده بود و مبتنی بر همین تکنیک بود درست کارکنه! چون کار نکرد ولی من هنوز وقت نکردم دیباگش کنم حتماً یه ایرادی داره.
 همون لیک فوق (آخرین لینک جناب sam7sam7 ) که در حقیقت FAQ نرم افزاری اوپن سورس هست در زبان #C از همین تکنیک استفاده شده و نمونه کدهاش کلی توضیح داده شده (ولی من سورس کاملش رو برای دانلود پیدا نکردم!؟)

----------


## Felony

من کلی MSDN رو گشتم ( همون روز که اون سورس قرار داده شد هم این کار رو کردم ) ولی هیچ Document ی مبنی بر اینکه میشه یک Poweron Event توسط این تابع ایجاد کرد ندیدم ، امروز تو گوگل جست و جو کردم و باز هم راهنمایی یافت نشد و همشون نمونه کد های ناقص یا توضیحات دست و پا شکسته بودند ، دارم بازم میگردم ...

----------


## mrbm_2007

سلام
یک نمونه کد 
با #C هست ولی چون از API های ویندوز استفاده کرده پس توی دلفی هم میشه یه جورایی استفادش کرد

----------


## lord_viper

این هم یه کد که من پیدا کردم البته به C++‎ هست فکر کنم بشه راحت به دلفی تبدیلش کرد


#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>

HANDLE hEvent = NULL ;
VOID CALLBACK TimerAPCProc(
	  LPVOID lpArgToCompletionRoutine,
    DWORD dwTimerLowValue,
    DWORD dwTimerHighValue
)
{
   printf("In TimerAPCProc\n");
   SetThreadExecutionState(ES_CONTINUOUS|ES_DISPLAY_R  EQUIRED|ES_SYSTEM_REQUIRED);
   if(IsSystemResumeAutomatic ())
   {
	  printf("IsSystemResumeAutomatic :: True\n") ;
   }
   else {
	  printf("IsSystemResumeAutomatic :: False\n") ;
   }
   SetEvent(hEvent);
}
int main()
{
  HANDLE hTimer = NULL;
  LARGE_INTEGER liDueTime;
  liDueTime.QuadPart = 20*-10000000LL; // 20 seconds

   hEvent = CreateEvent(NULL,FALSE,FALSE,TEXT("TimerEvent"));
  // Create an unnamed waitable timer.
  hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
  if (NULL == hTimer)
  {
    printf("CreateWaitableTimer failed (%d)\n", GetLastError());
    return 1;
  }
  printf("Waiting for 20 seconds...\n");
  // Set a timer to wait for 20 seconds.
  if (!SetWaitableTimer(hTimer, &liDueTime, 0, TimerAPCProc , NULL, TRUE))
  {
    printf("SetWaitableTimer failed (%d)\n", GetLastError());
    return 2;
  }
   if(ERROR_NOT_SUPPORTED == GetLastError ())
   {
	  printf("System restore is not supported \n") ;
   }
  // Wait for the timer.
  SleepEx(INFINITE, TRUE);
 
  
  printf("Timer was signaled.\n");
   if (WaitForSingleObject(hEvent, INFINITE) != WAIT_OBJECT_0)
    printf("TimerAPCProc failed (%d)\n", GetLastError());
  else printf("TimerAPCProc was signaled.\n");
  getch();
  return 0;
}

----------


## zidane

> خیر ؛ این برنامه کار میکنه ولی نه کاری که هدف این تاپیک بوده و *غیر ممکن هم هست !*
> ایشون برداشتن یک Message Handler برای پیغام WM_PowerBroadcast نوشتن و به این وسیله تشخیص دادن که یک Power Event رخ داده و سیستم قصد داره Hibernate, Standby یا ... بشه ؛ بلافاصله که همچین پیغامی به برنامه رسید یک WaitableTimer ساختن و گفتن مدت زمانی که کاربر خواسته صبر کن ( مدت زمان وارد شده توسط کاربر - زمان فعلی سیستم ) و به جای اینکه اجازه بدن سیستم به حالت خواب بره از این کار جلوگیری کردن و عوضش به مانیتور اجازه روشن شدن تا زمان وارد شده رو ندادن :
> 
> SetThreadExecutionState(ES_DISPLAY_REQUIRED);


واقعا خنده داره! از شما انتظار نداشتم اينقدر سطحي كد رو بررسي كنيد. اولا كه كل برنامه رو من ننوشتم و طبيعتا از كدهاي آماده زيادي استفاده كردم و اونها رو كنار هم قرار دادم. Message Handler صرفا به اين دليل قرار داده شده كه اگه كاربر به وسيله برنامه سيستم رو Hibernate نكرد باز هم برنامه تشخيص بده و در كار خودش رو انجام بده. اگه شما با برنامه كار كرده باشيد ميفهميد كه اصلا ربطي به خاموش كردن مانيتور نداره و كامپيوتر كاملا Hibernate يا Stand by ميشه و سپس روشن ميشه. اون تيكه كدي رو هم كه شما فرموديد اجازه روشن شدن به مانيتور رو نمي ده كاملا برعكس فرمايش جنابعالي كار مي كنه و وقتي كه سيستم روشن ميشه مانيتور رو هم باهاش روشن مي كنه و اگه اون كد نباشه سيستم روشن ميشه ولي مانيتور خاموش باقي مي مونه.
براي روشن كردن هم از تايمر داخلي برنامه استفاده نميشه و يك تايمر سيستمي هست كه مربوط به خود ويندوزه و براي اين كار ميشه ازش استفاده كرد.
البته احتمال وجود اشكال در برنامه هست اما كليت كار همينه كه در برنامه پياده سازي شده

----------


## Mask

دوستان برنامه ضمیمه رو تست کنید. ببینید برای شما کار میده.البته رو xp

----------


## zidane

روي xp جواب داد

----------


## DAMAVAND

کدي که دوستمون zidane نوشتن واقعا کار ميکنه! من چک کردم و کل سيستم به حالت standby رفت! نه فقط مانيتور! از ايشون خيلي تشکر ميکنم.

----------


## zidane

سورس برنامه ای که Gold برای تست گذاشته بود.
البته زبانش انگلیسی نیست

----------

