Jump to content

Another intelligent hibernationscript


majstang

Recommended Posts

Made this Autohotkey script cuz I dont use a dedicated recording server with recording service installed. I instead often use this main HTPC to watch TV with one or two clients and have it as recording server with two tuners simultainously. If having a dedicated recording server only for recording there is no problem letting recording service built-in standby/hibernation/shutdown tasks do its job after each recording is done. For those users this script might not be that intresting. However if having a similar setup as me i suggest you check this out. The original power tasks within recording service are alright, but if saving a search preset with for example hibernate as a post recording action all your future recordings (for the specific show) will inherit this action and you can be sure you will miss the timed messagebox that offers you to abort hibernation when recording is done and when you get back to the TV your HTPC has blackouted in hibernation. My hibernation script for use in Recording Service offers some more variables which you can set as you want and it makes your HTPC behave more intelligent. This script does NOT use DVBViewer COM interface at all. In other words no need to have a DVBViewer client running in order to make this script work. The script instead uses and retrieves data from the API in Recording Service.

 

The script works with variables such as:

- Days of the week

- Current (local) time

- Recording Service status

- Time to next recording

 

Autohotkey for newbies

Some instructions for folks not having used scripts of any kind before. Autohotkey is a scriptlanguage with no native support in Windows. You therefor have to install it.

1) Download autohotkey and install it on your PC http://www.autohotkey.com/download/

2) Copy the code in the script below and paste it into a notepad sheet and save it as whateveryoulike.ahk

3) Fill in your own username and password for Recording Service in the URLs in the hibernationsscript and save.

4) Rightclick on the whateveryoulike.ahk and select "Complie Script" in the menu. This complies the script to an executable file (exe), which is needed when setting up this script in recording service configuration.

 

When the script is compiled as an exe, then you have to create a task in RecService and tie the exe to this task. When scheduling a recording this task can be brought up through the "Task" field in the "SearchEPG" or "New Recording Timer". This task/script will then be executed after the recording is done. The script can also be used as default task after recording Webinterface->Configuration->Recorder->Choose the script/task as default task after recording. You can also do the same thing if you are using Autosearchtimers and choose this script/task from the SearchEPG and then save it as a Search Preset. All future to come recordingtimers for that particular Search Preset will then inherit the script/task when the autosearchtimer gets executed.

 

In my case the script works like this:

- Between weekdays Monday to Friday and the time 15:00:00-01:00:00 no hibernation will be allowed.

- Same weekdays but between the time 01:00:00-15:00:00 hibernation will be allowed, but only if time to next recording is more than 30 minutes.

- Between weekends Saturday and Sunday no hibernation is allowed between time 09:00:00-02:00:00

- Same days but hibernation is allowed between 02:00:00-09:00:00, but only if time to next recording is more than 30 minutes.

 

My initial goal was to also use a RecService status variable. Sometimes or quite often earlier i found myself in the situation (i have multiple tuners) im recording two shows simultainously and when one recording finishes RecService will hibernate if im not nearby and are abled to abort the hibernation through RecService messagebox. My thought was to have the script check recordcount in status api (RecService status) and if RecService is not doing any recordings allow hibernation else deny. But developers of RecordingService have for unknown reasons chosen to have "all" timers if executed to affect/alter the recordcount value (RecService status). Our script is a process timer and it causes the recordcount value to change as if a recording is going on, so the script will not hibernate ever.

 

EDIT: After further testing regarding the issue I had with using Recording Service status as a variable in the hibernation script I have to say that using that variable works very well. All that was needed was a little understanding how things work in recording service. When first tested the script it was quite confusing because when executing my hibernationscript/task through "Timer TAB" and then "Task link" this didnt alter/change the recordcount value. Recordcount value = RecService status and this value could vary between 0=no recording is going on, 1=one recording in process, 2=two recordings in process. BUT when executing the same task as an process timer in shape of an After recording task it did change the recordcount value to 1, meaning recording is going on.

In other words timers does affect/alter RecService status and tasks does not. Since our task/script is added to an existing recording timer it changes from being a task to a process timer (despite the name for it "After recording task"). This threw me completly.

 

If the hibernationscript checks the RecService status and receives recordcount=1, this simply means NO RECORDING IS GOING ON. The 1 simply comes from the "After recording task" my recording timer has already finished when the After recording task executes and wont have any effect on the recordcount.

 

This knowledge comes in handy if having two or more tuners. We do not want the HTPC to be hibernated if two shows are being recorded simultainously and one recording finishes which executes our script. If we have no way of query if a recording is going on or not the HTPC will be hibernated during the timespan when hibernation is allowed. So, if RecService status query comes back LessOrEqual to 1, hibernation will commence. If RecService status query comes back as GreaterOrEqual to 2, we know there is one or more recordings going on and hibernation will be denied.

 

Last scenario to cover was if somebody watches TV when hibernation is allowed according to my script. Using scripts executed from within Recording Service wont allow messageboxes. No userinteraction is allowed at all. It would be quite annoying if watching TV after lets say 02:00:00 on a weekend and have no way of aborting a hibernation at all, because there is no messageboxes showing up allowing me to do so.

I made a workaround for this. I created a script which is intercepting the hibernation call (coming from the After recording task

im having with an OnMessage command)) and quickly close this function down. In this way taking control of the hibernation process and it gives me the opportunity to have some userinteraction using a script runned outside of RecService.

 

A messagebox pops up when hibernation is intercepted and gives you the following options:

Press "Yes" button and Hibernation initiates

Press "No" button script breaks and does nothing

If no presses are registred hibernation will initiate after 20 seconds

 

This script should be autostarted when windows starts and it will be active in background (no trayicon) waiting for the hibernation call to come and intercept it and fire up the messagebox. Only drawback with this script is if using a client when hibernation call comes it closes the graph, due to some bug in DVBViewer. No other player behaves like this though. If pressing on No button simply change channel and the graph comes back up. Hopefully developers could adress this bug and sort it out.

 

 

Now to the scripts.

All code behind a ";" is inactivated and will not be executed.

 

This is the hibernation script:

 

#NoTrayIcon
FormatTime, TimeVar,, HH:mm:ss ;Current local time.
FormatTime, DateVar,, WDay ; 1=Sunday, 2=Monday etc.

OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/timerlist.html[?utf8=]")
StringReplace, OutputVar, OutputVar, <Timer, % Chr(4) . "<Timer", All
StringReplace, OutputVar, OutputVar, </Timer>, % "</Timer>" . Chr(4), All
MyList := A_Now A_Tab "<now>"
While pos := RegexMatch( OutputVar,"<Timer[^>]*Date=""(?<_D>\d+)\D(?<_M>\d+)\D(?<_Y>\d+)""[^>]*Start="""
. "(?<_H>\d+)\D(?<_N>\d+)\D(?<_S>\d+)""[^\x04]*<ID>(?<_ID>\d*)", Tmr, A_Index = 1 ? 1 : pos + StrLen(Tmr) )
  MyList .= "`n" . Tmr_Y . Tmr_M . Tmr_D . Tmr_H . Tmr_N . Tmr_S . A_Tab . Tmr_ID
Sort, MyList, N

set=0
Loop, Parse,MyList, `n
{
if set=1
{
datetime:=A_LoopField
break
}
IfInString, a_loopfield,<now>
set=1
}
StringSplit, datetime,datetime,%A_Tab%
EnvSub, datetime1,A_Now,min
RS_TimeToNextRecordingVar:=datetime1 ;time in minutes to next recording


OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html")
FoundPos := RegExMatch(OutputVar, "(?<=recordcount>)(.)", SubPat)
RS_StatusVar:=SubPat ;status of the recording service

UrlDownloadToVar(URL, Proxy="", ProxyBypass="")
{
AutoTrim, Off
hModule := DllCall("LoadLibrary", "str", "wininet.dll")

If (Proxy != "")
AccessType=3
Else
AccessType=1
;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

io_hInternet := DllCall("wininet\InternetOpenA"
, "str", "" ;lpszAgent
, "uint", AccessType
, "str", Proxy
, "str", ProxyBypass
, "uint", 0) ;dwFlags

iou := DllCall("wininet\InternetOpenUrlA"
, "uint", io_hInternet
, "str", url
, "str", "" ;lpszHeaders
, "uint", 0 ;dwHeadersLength
, "uint", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
, "uint", 0) ;dwContext

If (ErrorLevel != 0 or iou = 0) {
DllCall("FreeLibrary", "uint", hModule)
return 0
}

VarSetCapacity(buffer, 512, 0)
VarSetCapacity(NumberOfBytesRead, 4, 0)
Loop
{
 irf := DllCall("wininet\InternetReadFile", "uint", iou, "uint", &buffer, "uint", 512, "uint", &NumberOfBytesRead)
 NOBR = 0
 Loop 4  ; Build the integer by adding up its bytes. - ExtractInteger
   NOBR += *(&NumberOfBytesRead + A_Index-1) << 8*(A_Index-1)
 IfEqual, NOBR, 0, break
 ;BytesReadTotal += NOBR
 DllCall("lstrcpy", "str", buffer, "uint", &buffer)
 res = %res%%buffer%
}
StringTrimRight, res, res, 2

DllCall("wininet\InternetCloseHandle",  "uint", iou)
DllCall("wininet\InternetCloseHandle",  "uint", io_hInternet)
DllCall("FreeLibrary", "uint", hModule)
AutoTrim, on
return, res
}

If DateVar between 2 and 6 ;Specifies and conditions the week days. If between Monday=2 and Friday=6 the script will continue. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 01:00:00 and 15:00:00 ;Specifies which time to allow hibernation. Set to the value you prefer! Always use LowerBound and UpperBound format, like my example.
   If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
     If RS_TimeToNextRecordingVar >= 30 ;If minutes to next recording is more than 30 HTPC will hibernate. Set to the value you prefer!
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;Hibernates HTPC if all above conditions are met. If you prefer Standby change first parameter. Hibernate = 1 Standby = 0
     Else
        Return ;One or more conditions above is NOT met...hibernation will be cancelled.
}

If DateVar not between 2 and 6 ;Specifies and conditions the week days. If between Monday=2 and Friday=6 the script will continue. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 02:00:00 and 09:00:00 ;Specifies which time to allow hibernation. Set to the value you prefer! Always use LowerBound and UpperBound format, like my example.
   If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
      If RS_TimeToNextRecordingVar >= 30 ;If minutes to next recording is more than 30 HTPC will hibernate. Set to the value you prefer!
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;Hibernates HTPC if all above conditions are met. If you prefer Standby change first parameter. Hibernate = 1 Standby = 0
     Else
        Return ;One or more conditions above is NOT met...hibernation will be cancelled.
}

 

 

Intercept Hibernation Script Update:

- Reworked the messagebox and added a visual countdowntimer, now you can see the countdown from 20 to 0 seconds in wintitle.

- Messagebox is now always-on-top.

- Developers fixed the issue with graph going down when this script intercepts the hibernation (from Beta.165). Sadly this change did make it impossible to hibernate HTPC as long as DVBViewer beta .165 is running. If using this script I therefor recommend beta.160 or earlier.

 

New Intercept Hibernationscript:

 

#NoTrayIcon
#Persistent
OnMessage(0x0218, "OnPBMsg")
hibernate = 0
Return


OnPBMsg(wParam, lParam, msg, hwnd) {
  global hibernate
  If (wParam = 0 or wParam=4)
  {   ;PBT_APMQUERYSUSPEND
     If (lParam & 1)   ;Check action flag
     {
        if (hibernate = 0)
        {
           SetTimer, InterceptPBMSG, -1
           Return 1112363332
        }
        else
           Return 4
     }
  }
  ;Must return True after message is processed
  Return True
}

InterceptPBMSG:
Secs := 20
SetTimer, CountDown, 1000
MsgBox, 262148, System Hibernation in 20 seconds, Your HTPC is about to be Hibernated.`nAllow it?, %Secs%
SetTimer, CountDown, Off

IfMsgBox, Yes
{
  hibernate = 1
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;If you prefer Standby change first parameter. Hibernate = 1 Standby = 0 
  hibernate = 0
  Return
}
IfMsgBox, Timeout
{
  hibernate = 1
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;If you prefer Standby change first parameter. Hibernate = 1 Standby = 0 
  hibernate = 0
  Return
}
IfMsgBox No
{
  hibernate = 0
  return
}

Return

CountDown:
Secs -= 1
WinSetTitle, System Hibernation in,, System Hibernation in %Secs% seconds
Return

 

These scripts are tested and works on Windows XP. I use hibernation, but if preferring standby it can be changed quite easily. Let me know if someone have any questions. Enjoy...I certainly do, cuz it works great even though i wasnt abled to complete all my plans! It is failsafe provided you have only one tuner...set it and forget it :)

 

Regards

Majstang

Edited by majstang
Link to comment

Nice work. But I encountered problems when using the function setsuspendstate. The recording service was not able to create a timer for recordings. That's why I used tthe standby function from AutoIt.

Link to comment

Nice work. But I encountered problems when using the function setsuspendstate. The recording service was not able to create a timer for recordings. That's why I used tthe standby function from AutoIt.

Could you be more specific? It is hard to troubleshoot with so little information.

Link to comment

Could you be more specific? It is hard to troubleshoot with so little information.

 

I think you misunderstood. I don't use your script. So you don't have to search any error in it. I wrote my own standy script using AutoIt. When using the setsuspendstate function the recordingservice was not able to create his wakeup timers for recordings before going standby.

 

So don't worry. If your script is running well enjoy it

Link to comment

I think you misunderstood. I don't use your script. So you don't have to search any error in it. I wrote my own standy script using AutoIt. When using the setsuspendstate function the recordingservice was not able to create his wakeup timers for recordings before going standby.

 

So don't worry. If your script is running well enjoy it

Oh, now I understand! Good :)

However, im quite intresting to know the cause for things going wrong...any theories? Sounds really strange a setsuspendstate function could be abled to spoil wakeup timers for recordings since your standbyscript is supposed to be runned as an After recording task and shouldnt be runned when "autosearchtimers" and other recording scheduling creates new recordingtimers (wakeuptimers). You must have executed your script in a different way from mine, yes?

Also if using the setsuspendstate function what ever you do do not pass it with third parameter as 1, then you will disable all wake events.

Edited by majstang
Link to comment
  • 4 weeks later...

Thanks Majstang! That is a very useful script and I will put it in use when I get some time. You saved me the work of doing this as I have not had time to finish my similar script over the summer. Thanks once more :)

 

patti

Link to comment

Thanks patti! Im glad you like it. If i remember it right i think you are using Win7. I do not know how this script works on that OS yet. Havent taken the step to convert yet. The "Intercept Hibernation script" will not work for sure since Win7 uses other kinds of powermessages compared to WinXP. The "Intelligent Hibernation script" relies on the "Intercept Hibernation script" to prevent hibernation (or at least give you a choice what to do) on times when hibernation is allowed. If you only allow hibernation during nights so no biggie you dont need the intercept hibernation script. Let me know how it works for you.

 

Regards

Majstang

Link to comment

Oh yes, there is this Win XP vs. Win7 issue to think about. I didn't notice it at first. Well, I'll do some testing and see what I get out of it. I'll get back to you when I get it done, most likely in September, not earlier.

 

BTW, I saw an annoying little fly on my screen and tried to kill it... :D Then I noticed it was your avatar :D

 

patti

Link to comment

Haha...hilarious little bugger that one :rotfl:

Well, it is time for me to set up my Win7 system anyway. I have dragging that one out a long time now...long enough actually, cuz it is so much work trying to get it to work as good as my WinXP system does with all the scripts and other stuff. When I do, getting these two scripts working on Win7 is highly prioritized. I will post my results shortly.

 

Regards

Majstang

Link to comment

@patti!

 

If you wanna try my script just use the Intelligent Hibernationscript as it is and skip the Intercept Hibernation script. All tests of the Intelligent Hibernationscript on Win7 worked perfect. Only drawback you cant cancel the hibernation (with a shutdown messagebox) when it is sent as you can do on Windows XP. That is a gift from mister Gates himself and his gang of malignant hackers ;)

Link to comment
  • 2 weeks later...

Hi Folks!

 

Made some updates on both the Intelligent Hibernation Script and the Intercept Hibernation script.

 

Hibernationscript:

- It is now possible to use Recording Service own native PowerTasks and cancel messagebox. Read the script for instructions on how to enable the RS PowerTask. If using this option the Intercept Hibernation/shutdown script for WindowsXP will not be needed, cuz Recording Service blocks and delays the hibernation/shutdown for you (same principle as the Intercept Hibernation/Shutdown Script). Recording Service own cancel messagebox will only be displayed on WinXP systems. If using Windows 7 use Intercept Shutdown script for Windows 7. That will grant you a chance to cancel hibernate/standby/shutdown...otherwise HTPC just hibernates/shuts down after recording is finished without any warning and you wont be abled to stop it, during times you specify when hibernation/standby/shutdown is allowed.

 

post-56433-059497800 1282383319_thumb.jpg

 

- Also added Standby and Shutdown option if preferred instead of hibernation for use with the Intercept Hibernation/Shutdown script.

 

#NoTrayIcon
FormatTime, TimeVar,, HH:mm:ss ;Current local time.
FormatTime, DateVar,, WDay ; 1=Sunday, 2=Monday etc.

OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/timerlist.html[?utf8=]") ;Fill in your own username and password
StringReplace, OutputVar, OutputVar, <Timer, % Chr(4) . "<Timer", All
StringReplace, OutputVar, OutputVar, </Timer>, % "</Timer>" . Chr(4), All
MyList := A_Now A_Tab "<now>"
While pos := RegexMatch( OutputVar,"<Timer[^>]*Date=""(?<_D>\d+)\D(?<_M>\d+)\D(?<_Y>\d+)""[^>]*Start="""
. "(?<_H>\d+)\D(?<_N>\d+)\D(?<_S>\d+)""[^\x04]*<ID>(?<_ID>\d*)", Tmr, A_Index = 1 ? 1 : pos + StrLen(Tmr) )
  MyList .= "`n" . Tmr_Y . Tmr_M . Tmr_D . Tmr_H . Tmr_N . Tmr_S . A_Tab . Tmr_ID
Sort, MyList, N

set=0
Loop, Parse,MyList, `n
{
if set=1
{
datetime:=A_LoopField
break
}
IfInString, a_loopfield,<now>
set=1
}
StringSplit, datetime,datetime,%A_Tab%
EnvSub, datetime1,A_Now,min
RS_TimeToNextRecordingVar:=datetime1 ;time in minutes to next recording


OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html") ;Fill in your own username and password
FoundPos := RegExMatch(OutputVar, "(?<=recordcount>)(.)", SubPat)
RS_StatusVar:=SubPat ;status of the recording service

UrlDownloadToVar(URL, Proxy="", ProxyBypass="")
{
AutoTrim, Off
hModule := DllCall("LoadLibrary", "str", "wininet.dll")

If (Proxy != "")
AccessType=3
Else
AccessType=1
;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

io_hInternet := DllCall("wininet\InternetOpenA"
, "str", "" ;lpszAgent
, "uint", AccessType
, "str", Proxy
, "str", ProxyBypass
, "uint", 0) ;dwFlags

iou := DllCall("wininet\InternetOpenUrlA"
, "uint", io_hInternet
, "str", url
, "str", "" ;lpszHeaders
, "uint", 0 ;dwHeadersLength
, "uint", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
, "uint", 0) ;dwContext

If (ErrorLevel != 0 or iou = 0) {
DllCall("FreeLibrary", "uint", hModule)
return 0
}

VarSetCapacity(buffer, 512, 0)
VarSetCapacity(NumberOfBytesRead, 4, 0)
Loop
{
 irf := DllCall("wininet\InternetReadFile", "uint", iou, "uint", &buffer, "uint", 512, "uint", &NumberOfBytesRead)
 NOBR = 0
 Loop 4  ; Build the integer by adding up its bytes. - ExtractInteger
   NOBR += *(&NumberOfBytesRead + A_Index-1) << 8*(A_Index-1)
 IfEqual, NOBR, 0, break
 ;BytesReadTotal += NOBR
 DllCall("lstrcpy", "str", buffer, "uint", &buffer)
 res = %res%%buffer%
}
StringTrimRight, res, res, 2

DllCall("wininet\InternetCloseHandle",  "uint", iou)
DllCall("wininet\InternetCloseHandle",  "uint", io_hInternet)
DllCall("FreeLibrary", "uint", hModule)
AutoTrim, on
return, res
}

If DateVar between 2 and 6 ;Specifies hibernation rules between Monday=2 and Friday=6. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 00:00:00 and 15:00:00 ;Specifies which time to allow hibernation. Set to the value you prefer! Always use LowerBound and UpperBound format, like my example.
   If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
     If RS_TimeToNextRecordingVar >= 30 ;If minutes to next recording is more than 30, HTPC will hibernate. Set to the value you prefer!
        /*
        If you prefer some other default System Closedown method than Hibernate, activate the one you prefer by removing semicolon for choosen PowerTask below and remember to
        inactivate the DllCall for Hibernation by inserting a semicolon in front of that codeline. 
        WindowsXP users only!!! If using the "Intercept Hibernation/shutdown script" you will have the opportunity to cancel System Closedown through a messagbox and
        simultainously be presented with several options (Hibernate, Standby, Shutdown, Restart or Cancel ) what to do next.   
        */
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;Hibernates HTPC if all above conditions are met. 
        ;DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0) ;Standby mode for your HTPC if all above conditions are met. 
        ;Shutdown, 1 ;This option will shutdown your HTPC.

        /*
        Codelines below can be used to activate Rec.Service native PowerTASKs. WinXP users will get the RS messagebox which allows you to abort shutdown within 10 seconds.   
        If using this option the "Intercept Hibernation/shutdown script" will not be needed (WinXP only). Activate by removing semicolon for Task of choice below and remember to 
        inactivate the DllCall above by inserting a semicolon in front of that codeline. Don't forget to fill in your username and password in the URL otherwise it won't work.
        */
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Hibernate&aktion=tasks") ;If choosen activates Rec.Service own Hibernation task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Standby&aktion=tasks") ;If choosen activates Rec.Service own Standby task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Shutdown&aktion=tasks") ;If choosen activates Rec.Service own Shutdown task.
     Else
        Return ;One or more conditions above is NOT met...hibernation will be cancelled.
}

If DateVar not between 2 and 6 ;Specifies hibernation rules between Saturday=7 and Sunday=1. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 02:00:00 and 09:00:00 
    If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
      If RS_TimeToNextRecordingVar >= 30
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;Hibernates HTPC if all above conditions are met. 
        ;DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0) ;Standby mode for your HTPC if all above conditions are met. 
        ;Shutdown, 1 ;This option will shutdown your HTPC.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Hibernate&aktion=tasks") ;If choosen activates Rec.Service own Hibernation task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Standby&aktion=tasks") ;If choosen activates Rec.Service own Standby task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Shutdown&aktion=tasks") ;If choosen activates Rec.Service own Shutdown task.
     Else
        Return
}

 

 

Update Intercept Hibernation/Shutdown script for Windows XP:

- This script now intercepts hibernation/standby/shutdown/restart.

- Removed the countdown timer in wintitle

- Added vast styling possibilities for the msgbox. You can now combine html and javascript with Autohotkey inside the messagbox and pretty much get it to look and do what ever you like.

- Added a javascript countdown timer

- Added handwritten fonts

- More closedown options

 

A little example on what you are abled to do:

post-56433-049931400 1282384338_thumb.jpg

 

The countdowntimer function in this script needs a little explanation. When msgbox timeouts (countdown timer reaches 0 seconds) this script is configured to:

- If a hibernation/standby is intercepted the default closedownmethod is Hibernate. You can alter this by changing BDefault (ButtonDefault) to what closedown method you like to use. After 20 seconds of countdown this default closedown method will be executed per automatic.

- If a shutdown/restart is intercepted the default closedownmethod is Shutdown when msgbox timeouts.

 

#NoTrayIcon
#Persistent
SetTimer, InterceptShutdown, Off
SetTimer, InterceptPBMSG, Off
DllCall("kernel32.dll\SetProcessShutdownParameters", UInt, 0x4FF, UInt, 0)
OnMessage(0x11, "WM_QUERYENDSESSION")
OnMessage(0x0218, "OnPBMsg")
hibernate = 0
Return

WM_QUERYENDSESSION(wParam, lParam)
 {
   static sdtry = 0
   ENDSESSION_Logoff = 0x80000000
   If (lParam & ENDSESSION_Logoff) ; User is logging off.
     EventType = Logoff
   Else     ; System is either shutting down or restarting. and
     EventType = Shutdown
   If (EventType = "Shutdown" and sdtry = 0)
   {
     SetTimer, InterceptShutdown, On
     Return false ; Tell the OS to Abort the Shutdown/Logoff.
   }
   Else If (EventType = "Shutdown" and sdtry = 1)
     Return true
 }

OnPBMsg(wParam, lParam, msg, hwnd) {
  global hibernate
  If (wParam = 0 or wParam=4)
  {   ;PBT_APMQUERYSUSPEND
     If (lParam & 1)   ;Check action flag
     {
        if (hibernate = 0)
        {
           SetTimer, InterceptPBMSG, On
           Return 1112363332
        }
        else
           Return 4
     }
  }
  ;Must return True after message is processed
  Return True
}

InterceptShutdown:
SetTimer, InterceptShutdown, Off
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%  

FileDelete, demo.htm
FileAppend,
(
<html>
<body style="overflow:hidden">
<body bgcolor="#0033FF" leftmargin="1" topmargin="1">
<div align="Center"><p>
<font color="#FFFB02" face="SpillMilk" size="6"><br><b>
Your HTPC is about to be Closed Down.
<br>
You now have a chance to choose closedown method
<br>
or wait until default method gets choosen for you</b>
</p>
<font face="SpillMilk" size="7"><b>
<script type="text/javascript">
var countDownInterval=20; 
var countDownTime=countDownInterval+1; 
function countDown(){ 
countDownTime--; 
if (countDownTime <=0){ 
countDownTime=countDownInterval; 
clearTimeout(counter); 
//window.location=""; 
return 
} 
if (document.getElementById) //else if NS6+ 
document.getElementById("countDownText").innerHTML=countDownTime+" ";
else if (document.layers){ //CHANGE TEXT BELOW TO YOUR OWN 
document.c_reload.document.c_reload2.document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
document.c_reload.document.c_reload2.document.close() 
} 
counter=setTimeout("countDown()", 1000); 
} 

function startit(){ 
if (document.getElementById) //CHANGE TEXT BELOW TO YOUR OWN 
document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
countDown() 
} 

if (document.getElementById) 
startit() 
else 
window.onload=startit 
clearTimeout ( countDownTime );
</script>
</font></b>
</div>
</body>
</html>
)
, demo.htm


URL=file:///%A_ScriptDir%\demo.htm
Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=580, HtmH=250, BDefault=3, DlgBgColor=0xEE0000, DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"
;Change BDefault (ButtonDefault) to what closedown method you like to use. After 20 seconds of countdown this default closedown method will be executed per automatic. 
;Button 1=Hibernate 
;2=Standby
;3=Shutdown (Deafult today) 
;4=Restart
;5=Cancel

Sel := HtmDlg( URL, "", Options )

if (Sel = 1)
 {
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
  Return
 }
else if (Sel = 2)
 {
  DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
  Return
 }
else if (Sel = 3)
 {
  Shutdown, 1
  ExitApp
  Return
 }
else if (Sel = 4)
 {
  Shutdown, 2
  ExitApp
  Return
 }
else if (Sel = 5)
 {
  hibernate = 0
  Return
 }

Return                                                 ; // end of auto-execute section //

InterceptPBMSG:
SetTimer, InterceptPBMSG, Off
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%  

FileDelete, demo.htm
FileAppend,
(
<html>
<body style="overflow:hidden">
<body bgcolor="#0033FF" leftmargin="1" topmargin="1">
<div align="Center"><p>
<font color="#FFFB02" face="SpillMilk" size="6"><br><b>
Your HTPC is about to be Closed Down.
<br>
You now have a chance to choose closedown method
<br>
or wait until default method gets choosen for you</b>
</p>
<font face="SpillMilk" size="7"><b>
<script type="text/javascript">
var countDownInterval=20; 
var countDownTime=countDownInterval+1; 
function countDown(){ 
countDownTime--; 
if (countDownTime <=0){ 
countDownTime=countDownInterval; 
clearTimeout(counter); 
//window.location=""; 
return 
} 
if (document.getElementById) //else if NS6+ 
document.getElementById("countDownText").innerHTML=countDownTime+" ";
else if (document.layers){ //CHANGE TEXT BELOW TO YOUR OWN 
document.c_reload.document.c_reload2.document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
document.c_reload.document.c_reload2.document.close() 
} 
counter=setTimeout("countDown()", 1000); 
} 

function startit(){ 
if (document.getElementById) //CHANGE TEXT BELOW TO YOUR OWN 
document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
countDown() 
} 

if (document.getElementById) 
startit() 
else 
window.onload=startit 
clearTimeout ( countDownTime );
</script>
</font></b>
</div>
</body>
</html>
)
, demo.htm


URL=file:///%A_ScriptDir%\demo.htm
Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=580, HtmH=250, BDefault=1, DlgBgColor=0xEE0000, DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"
;Change BDefault (ButtonDefault) to what closedown method you like to use. After 20 seconds of countdown this default closedown method will be executed per automatic. 
;Button 1=Hibernate (Deafult today) 
;2=Standby
;3=Shutdown 
;4=Restart
;5=Cancel

Sel := HtmDlg( URL, "", Options )

if (Sel = 1)
 {
  hibernate = 1
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
  hibernate = 0
  return
 }
else if (Sel = 2)
 {
  hibernate = 1
  DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
  hibernate = 0
  return
 }
else if (Sel = 3)
 {
  Shutdown, 1
  ExitApp
  return
 }
else if (Sel = 4)
 {
  Shutdown, 2
  ExitApp
  return
 }  
else if (Sel = 5)
 {
  hibernate = 0
  return
 }

Return                                                 ; // end of auto-execute section //

;#Include HtmDlg.ahk ; You may copy/Paste HtmDlg() Instead
HtmDlg( _URL="", _Owner=0, _Options="", _ODL="," ) {     ; HTML DialogBox v0.57 -- by SKAN
; Topic: www.autohotkey.com/forum/viewtopic.php?t=60215    CD:09-Jul-2010 | LM:05-Aug-2010
; Credit: WebControl Demo by Sean - www.autohotkey.com/forum/viewtopic.php?p=103987#103987

Static _hInst,_hDLG,_DlgP,_B$,_B$L,_pIWEB,_pV,_DlgT,CliC, HtmF=0,_Brush=0,   BDef=1,BEsc=0

If ( A_EventInfo = 0xCBF ) {                                   ; nested Callback Function
  hWnd := _URL,  uMsg := _Owner,  wP := _Options,  lP := _ODL

  If ( uMsg=0x112 && wP=0xF060 )                               ; WM_SYSCOMMAND & SC_ClOSE
    Return DllCall( "DestroyWindow", UInt,_hDLG ) | ( BDEf:=BEsc )

  If ( uMsg=0x111 && (wP>>16)=0 )                              ; WM_COMMAND & BN_CLICKED
    Return DllCall( "DestroyWindow", UInt,_hDLG ) | ( BDef := (wP=2) ? BEsc : wP-100  )

  If ( uMsg=0x007 && HtmF=0 )                                  ; WM_SETFOCUS
    Return DllCall( "SetFocus", UInt,DllCall( "GetDlgItem", UInt,_hDLG, UInt,100+BDEF ) )

  If ( uMsg=0x201 && CliC )                                    ; WM_LBUTTONDOWN
    Return DllCall( "DestroyWindow", UInt,_hDLG ) |  ( BDEf := 1 )

  If ( uMsg=0x136 && _Brush<>0 )                               ; WM_CTLCOLORDLG
    Return _Brush

  if ( uMsg=0x002 && hWnd=_hDLG )                              ; WM_DESTROY
    Return _Brush := DllCall( "DeleteObject", UInt,_Brush, UInt ) >> 32

Return False
}

If ! ( _hInst ) {
_hInst := DllCall( "GetModuleHandle", Str,A_IsCompiled ? A_ScriptFullpath : A_AhkPath )

_DT := "61160CD3AFCDD0118A3EGC04FC9E26EZQ1GFFFFUCHC88GAZO9G9G1I4DG53G2H53G68G65G6CG6CG2H"
. "44G6CG67ZL5V64K41G74G6CG41G78G57G69G6EK7BG38G38G35G36G46G39G36G31G2DG33G34G3H41G2DG31"
. "G31G44G3H2DG41G39G36G42G2DG3H3H43G3H34G46G44G37G3H35G41G32G7DZS14V65KFFFF8ZP14V66KFFF"
. "F8ZP14V67KFFFF8ZP14V68KFFFF8ZP14V69KFFFF8ZP14V6AKFFFF8ZP14V6BKFFFF8ZP14V6CKFFFF8ZP14V"
. "6DKFFFF8P"

Loop 20   ;  Decompressing Nulls : www.autohotkey.com/forum/viewtopic.php?p=198560#198560
 StringReplace,_DT,_DT,% Chr(70+21-A_Index),% SubStr("000000000000000000000",A_Index),All

Loop % _B$L := VarSetCapacity( _B$, ( _DTLEN := StrLen(_DT) // 2 ), 0 )
 NumPut( "0x" . SubStr(_DT, 2*A_Index-1,2),_B$,A_Index-1,"Char" )  ; Creating Structure
_pIWEB := &_B$, _pV := &_B$+16, _DlgT := &_B$+32   ; Relevant pointers to Structure

DllCall( "GetModuleHandle", Str,"atl.dll" ) ? 0 : DllCall( "LoadLibrary", Str,"atl.dll" )
DllCall( "atl\AtlAxWinInit" ),          _DlgP := RegisterCallback( A_ThisFunc,0,4,0xCBF )
}

VarSetCapacity( _W$,_B$L,0 ), DllCall( "RtlMoveMemory", UInt,&_W$, UInt,&_B$, UInt,_B$L )
_pIWEB := &_W$, _pV := &_W$+16, _DlgT := &_W$+32         ; Relevant pointers to Structure

Butt:="OK", BWid:=75, BHei:=23, BSpH:=5, BSpV:=8, BAli:=1, Slee:=-1, HtmC:=0, CliC:=0
HtmD:=0, DlgT:=0, DlgN:=0, DlgX:="", DlgY:="", HtmW:=240, HtmH:=140, Left:=0, TopM:=0
Loop, Parse, _Options, =%_ODL%, %A_Space%        ; Override Variables with user 'Options'
  A_Index & 1  ? (  __  := (SubStr(A_LoopField,1,1)="_") ? "_" : SubStr(A_LoopField,1,4))
               : ( %__% := A_LoopField )

Cap  := DllCall( "GetSystemMetrics", UInt,4  ) ; SM_CYCAPTION    = Window Caption
Frm  := DllCall( "GetSystemMetrics", UInt,7  ) ; SM_CXFIXEDFRAME = Window Frame

NumPut( HtmC<>0 ? 0x200 : 0x0, _W$, 32+68 ), DlgD := DlgD ? 0x8000000 : 0x0
FonS ? NumPut( FonS < 8 ? 8 : ( FonS > 14 ? 14 : FonS ), _W$, 64, "UShort" ) : 0

If (  ( DlgS := SubStr( DlgS,1,1 ) ) <> ""  )
 _ := ( DlgS = "F" ) ? NumPut( 0x800000C0 | DlgD, _W$, 44 ) | ( Cap := 0 )
   :  ( DlgS = "N" ) ? NumPut( 0x80000040 | DlgD, _W$, 44 ) | ( Frm := Cap := 0 )
   :  ( DlgS = "B" ) ? NumPut( 0x80800040 | DlgD, _W$, 44 ) | ( Cap := 0 ) | ( Frm := 1 )
   :                   NumPut( 0x80C800C0 | DlgD, _W$, 44 )

IfNotEqual,DlgB,, SetEnv,_Brush,% DllCall( "CreateSolidBrush", UInt,DlgB )

_hDLG  := DllCall( "CreateDialogIndirectParam", UInt,_hInst, UInt,_DlgT, UInt
,_Owner := ( _Owner <> "" ) ? _Owner : DllCall( "GetShellWindow" ), UInt,_DlgP, UInt,0 )

VarSetCapacity( _WU, StrLen(_URL) * ( A_IsUnicode ? 1 : 2 ) + 2, 0 )
A_IsUnicode ? _WU := _URL : DllCall( "MultiByteToWideChar", UInt,0, UInt,0, UInt,&_URL
                                    , Int,-1, UInt,&_WU, Int,StrLen(_URL)+1 )

_hHTM := DllCall( "GetDlgItem", UInt,_hDLG, UInt,100 )
DllCall( "atl\AtlAxGetControl", UInt,_hHTM, UIntP,_ppunk )
DllCall( NumGet( NumGet( _ppunk+0 )+4*0 ), UInt,_ppunk, UInt,_pIWEB, UIntP,_ppwb )
DllCall( NumGet( NumGet( _ppunk+0 )+4*2 ), UInt,_ppunk ),_pwb := NumGet( _ppwb+0 )
DllCall( NumGet(_pwb+4*11),UInt,_ppwb, UInt,&_WU, UInt,_pV,UInt,_pV,UInt,_pV,UInt,_pV )
DllCall( NumGet(_pwb+4*2), UInt,_ppwb )

DllCall( "SetWindowPos", UInt,_hHTM,Int,0,Int,Left,Int,TopM,Int,HtmW,Int,HtmH,UInt,0x14 )
IfNotEqual,HtmD,0, Control,Disable,,,ahk_id %_hHTM%

DlgW := Frm + Left + HtmW + Frm + Left,       ClAW := DlgW - Frm - Frm ; ClientArea Width
DlgH := Frm + Cap + TopM + HtmH + BSpV + BHei + BSpV + Frm
DlgX := ( DlgX <> "" ) ? DlgX : ( A_ScreenWidth - DlgW ) // 2
DlgY := ( DlgY <> "" ) ? DlgY : ( A_ScreenHeight - DlgH ) // 2

StringReplace, Butt,Butt, /,/, UseErrorLevel
bCount := ErrorLevel+1
BY := TopM + HtmH + BSpV
BX := ( Bali=1 ? ( ( ClAW - (BSpH*(bCount-1)) - (BWid*bCount) ) / 2 )
   :  ( Bali=0 ? ( ( BSpH * 2 ) + ( HtmD ? 0 : Left ) )
   :  ( ClAW - (BSpH*(bCount+1)) - (BWid*bCount) - ( HtmD ? 0 : Left ) ) ) )

Loop, Parse, Butt, /   ;  SetWindowPos flags = SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOZORDER
  DllCall( "SetWindowPos", UInt,BH:=DllCall( "GetDlgItem", UInt,_hDLG, UInt,100+A_Index )
                       , UInt,0, Int,BX, Int,BY, Int,BWid, Int,BHei, UInt,0x40|0x10|0x4 )
, DllCall( "SetWindowText", UInt,BH, Str,A_LoopField ),   BX := BX + BSpH + BWid
, _ := ( BNoT<>"" ) ? DllCall( "uxtheme\SetWindowTheme", UInt,BH, UInt,0, UIntP,0 ) : 0
, _ := ( BSFl<>"" ) ? DllCall( "SetWindowLong", UInt,BH, Int,-16, UInt,0x50018000 ) : 0

BDef := ( BDef < 1 || BDef > bCount ) ? 1 : BDef ; Force Default Button
DllCall( "SendMessage", UInt,_hDLG, UInt,0x401, UInt,100+BDef, UInt,0 )    ;  DM_SETDEFID

DllCall( "SetWindowText", UInt,_hDLG, Str,Titl ? Titl : A_ScriptName ) ; Set Dialog Title
DllCall( "SetWindowPos", UInt,_hDLG, Int,DlgT ? -1 : 1, Int,DlgX, Int,DlgY, Int,DlgW, Int
                       , DlgH, UInt,0x10 )         ; DlgTopmost ? HWND_TOPMOST : HWND_TOP

While ( nReady <> 4 && DlgW<>"" )  ;  wait until webpage-load adapted from Seans's IE.ahk
  Sleep % 1 + ( DllCall( NumGet(NumGet(1*_ppwb)+224 ), UInt,_ppwb, UIntP,nReady ) >> 32 )
Sleep, %Slee%

DllCall( "ShowWindow", UInt,_hDLG, Int,DlgN ? 8 : 5 ) ; DlgNA ? SW_SHOWNA : SW_SHOW
IfNotEqual,HtmF,0, ControlFocus,, ahk_ID %_hDLG%
WinWaitClose, ahk_id %_hDLG%,, %Time%
TimedOut := Errorlevel  ? DllCall( "EndDialog", UInt,_hDLG, UInt,0 ) : 0
IfNotEqual,AltR,, IfGreater,BDef,0, StringSplit,B,Butt,/
DllCall( "SetLastError", UInt,TimedOut ? 1 : 0 )
Return AltR ? B%BDef% : BDef
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \
>-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  O P T I O N S  -  -<
\- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /

Usage: HtmDlg( URL, hwndOwner, Options, OptionsDelimiter )

Parameters :

URL              - A valid URL supported by Internet Explorer including Res:// and File://

hWndOwner        - Handle to the parent window. If invalid handle or 0 ( zero ) is passed,
                  the dialog will have a taskbar button. Passing "" as a parameter will
                  set 'Progman' the owner, thereby supressing the 'Taskbar Button'.

Options          - A series of 'variable overrides' delimited with character specified in
                  'Optionsdelimiter'. Please refer 'VARIABLE OVERRIDES' below.

OptionsDelimiter - The delimiter used in seperating 'variable overrides'


;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  * * *   V A R I A B L E   O V E R R I D E S   * * *
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Important Note: leading 4 characters of a variable will be sufficient.
               for eg.: Instead of 'AltReturn=1' you may use 'AltR=1'


DlgXpos         = X coordinate in pixels, relative to screen
                 Dialog is horizontally centered by default

DlgYpos         = Y coordinate in pixels, relative to screen
                 Dialog is vertically centered by default

DlgTopmost      = 1 will set the Dialog 'Always-on-Top'
                 0 is default

DlgDisable      = 1 will disable the Dialog window
                 No default value

                 Caution:
                 Since there is no way to interact, you may opt to TimeOut the Dialog

DlgStyle        = Frame or NoFrame or Border. Leading character is sufficient, like: F-N-B
                 Default is Caption

                 Note on Styles used:

                 Frame   = WS_POPUP | DS_MODALFRAME
                 NoFrame = WS_POPUP | DS_SETFONT
                 Border  = WS_POPUP | DS_SETFONT | WS_BORDER
                 Caption = WS_POPUP | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU

                 WS_DISABLED is additionally set when DlgDisable=1

DlgNoActivate   = 1 will Show the Dialog without activating it
                 0 is default

DlgBgColor      = ColorRef.  eg: 0x0000FF is Red / Invalid ColorRef will result in Black.

DlgWait         = 1 will delay Dialog from being shown - until HTM is fully loaded

Sleep           = MilliSeconds ( Will be used just before Dialog is shown )
                 Default value is -1, 'No sleep'

Title           = Captionbar Text
                 Default is A_ScriptName

AltReturn       = 1 will return Button-text
                 0 is default and Button-instance will be returned

TimeOut         = Seconds
                 No default value

                 Note: A_LastError will be true when a TimeOut occurs

ClickClose      = 1
                 Default value is 0

                 Note:
                 Mouse L-Click on window's unoccupied clientarea' will close the dialog

                 Tip: Use following to simulate a unobtrusive message ( like TrayTip )
                 DlgTopmost=1, HtmD=1, DlgNA=1, DlgStyle=Border, BHei=0, BSpV=0, Clic=1

LeftMargin      = Spacing in Pixels ( on the left/right sides of WebControl )
                 Default value is 0

TopMargin       = Spacing in Pixels ( above the WebControl )
                 Default value is 0

FonName           ( Not implemented yet )
                 Default is 'MS Shell Dlg' and equivalent

FonSize         = Pointsize ( text size of Button-labels - restricted to 8,10,12,14 )
                 Default value is 8

HtmClientEdge   = 1 to set WS_EX_CLIENTEDGE
                 Default value is 0

HtmDisable      = 1 to disable
                 Default value is 0

HtmWidth        = Width of WebControl in Pixels
                 Default value is 240

HtmHeight       = Height of WebControl in pixels
                 Default value is 140

HtmFocus        = 1 will activate the dialog and WebControl will have input focus
                 Default value is 0

                 Note: DlgNoActivate option will lose effect.
                       For best result, use this option along with DlgWait=1

Buttons         = Button labels seperated with "/"  eg: Buttons=Yes/No/Cancel
                 Default Button is "OK"

BDefault        = Instance of Default Button. eg: To make 3rd Button default, use BDef=3
                 Default forced value is 1

BEscape         = Instance of Button to return when dialog is closed or {Esc} is pressed
                 Default is 0

BWidth          = Button Width in Pixels
                 Default Value is 75

BHeight         = Button Height in Pixels
                 Default value is 23

BSpHorizontal   = Pixels ( affects the spacing on the sides of a button )

BSpVertical     = Pixels ( affects the spacing above/below a button )

BAlign          = 0 or 1 or 2  ( for Left, Center, Right alignment of buttons )
                 Default is 1

BNoTheme        = 1 will remove theme from buttons ( XP & greater )
                 No default value

BSFlat          = 1 will flatten the button by removing the 3D edge - requires BNoTheme=1
                 No default value

;< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >

*/

 

Enjoy!

 

Regards

Majstang

Edited by majstang
Link to comment
  • 3 weeks later...

Nice work and thanks a lot for the great script! It adds much needed functionality to after recording. Would it be possible to add an option to the shutdown script which would check if RS has any streaming clients connected and if so discard the standby/hibernation. The information is available in /api/status.html so it should be possible... I could try to do it myself but I have little knowledge about scripting. That would be great feature because then you would need not to worry about missing the shutdown warning if not watching tv intensively and there would be no annoying cancel dialogs if watching intensively :). Then your script could be called super intelligent :)

Link to comment

Thanks! It's always nice to get some feedback and to see people starting to use this script. Please feel free to ask me anything and let me know if I need to work on the "How to set up things in order to get the script working" or anything :)

 

@Tuomiopuuma, it never crossed my mind adding this variable, due to the way Im using my system. On my system a client is running all the time and I never close it down and prefer to have it running when server resumes from hibernation. No problem at all adding this request of yours. This is one of the major points with the script...everyone should be abled to use it regardless of userbehaviour and I have really tried to put an effort to accomplish that. So of course there should be a clientcount variable added and the script should then look like this. If anyone else do not wanna use this variable you can always inactivate the "If RS_ClientCountStatus" statement using the semicolon...well I think everyone that have followed this thread have got that by now ;)

 

Enjoy!

:bye:

 

Hibernationscript with Clientcount Variable

#NoTrayIcon
FormatTime, TimeVar,, HH:mm:ss ;Current local time.
FormatTime, DateVar,, WDay ; 1=Sunday, 2=Monday etc.

OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/timerlist.html[?utf8=]") ;Fill in your own username and password
StringReplace, OutputVar, OutputVar, <Timer, % Chr(4) . "<Timer", All
StringReplace, OutputVar, OutputVar, </Timer>, % "</Timer>" . Chr(4), All
MyList := A_Now A_Tab "<now>"
While pos := RegexMatch( OutputVar,"<Timer[^>]*Date=""(?<_D>\d+)\D(?<_M>\d+)\D(?<_Y>\d+)""[^>]*Start="""
. "(?<_H>\d+)\D(?<_N>\d+)\D(?<_S>\d+)""[^\x04]*<ID>(?<_ID>\d*)", Tmr, A_Index = 1 ? 1 : pos + StrLen(Tmr) )
  MyList .= "`n" . Tmr_Y . Tmr_M . Tmr_D . Tmr_H . Tmr_N . Tmr_S . A_Tab . Tmr_ID
Sort, MyList, N

set=0
Loop, Parse,MyList, `n
{
if set=1
{
datetime:=A_LoopField
break
}
IfInString, a_loopfield,<now>
set=1
}
StringSplit, datetime,datetime,%A_Tab%
EnvSub, datetime1,A_Now,min
RS_TimeToNextRecordingVar:=datetime1 ;time in minutes to next recording


OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html") ;Fill in your own username and password
FoundPos := RegExMatch(OutputVar, "(?<=recordcount>)(.)", SubPat)
RS_StatusVar:=SubPat ;status of the recording service

OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html") ;Fill in your own username and password and portnumber.
FoundPos := RegExMatch(OutputVar, "(?<=clientcount>)(.)", SubPat2)
RS_ClientCountStatus:=SubPat2 ;Number of clients connected to the recording service

UrlDownloadToVar(URL, Proxy="", ProxyBypass="")
{
AutoTrim, Off
hModule := DllCall("LoadLibrary", "str", "wininet.dll")

If (Proxy != "")
AccessType=3
Else
AccessType=1
;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

io_hInternet := DllCall("wininet\InternetOpenA"
, "str", "" ;lpszAgent
, "uint", AccessType
, "str", Proxy
, "str", ProxyBypass
, "uint", 0) ;dwFlags

iou := DllCall("wininet\InternetOpenUrlA"
, "uint", io_hInternet
, "str", url
, "str", "" ;lpszHeaders
, "uint", 0 ;dwHeadersLength
, "uint", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
, "uint", 0) ;dwContext

If (ErrorLevel != 0 or iou = 0) {
DllCall("FreeLibrary", "uint", hModule)
return 0
}

VarSetCapacity(buffer, 512, 0)
VarSetCapacity(NumberOfBytesRead, 4, 0)
Loop
{
 irf := DllCall("wininet\InternetReadFile", "uint", iou, "uint", &buffer, "uint", 512, "uint", &NumberOfBytesRead)
 NOBR = 0
 Loop 4  ; Build the integer by adding up its bytes. - ExtractInteger
   NOBR += *(&NumberOfBytesRead + A_Index-1) << 8*(A_Index-1)
 IfEqual, NOBR, 0, break
 ;BytesReadTotal += NOBR
 DllCall("lstrcpy", "str", buffer, "uint", &buffer)
 res = %res%%buffer%
}
StringTrimRight, res, res, 2

DllCall("wininet\InternetCloseHandle",  "uint", iou)
DllCall("wininet\InternetCloseHandle",  "uint", io_hInternet)
DllCall("FreeLibrary", "uint", hModule)
AutoTrim, on
return, res
}

If DateVar between 2 and 6 ;Specifies hibernation rules between Monday=2 and Friday=6. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 00:00:00 and 15:00:00 ;Specifies which time to allow hibernation. Set to the value you prefer! Always use LowerBound and UpperBound format, like my example.
   If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
    If RS_ClientCountStatus = 0 ;Hibernation will be allowed only if no clients are connected to RS. 
     If RS_TimeToNextRecordingVar >= 30 ;If minutes to next recording is more than 30, HTPC will hibernate. Set to the value you prefer!
        /*
        If you prefer some other default System Closedown method than Hibernate, activate the one you prefer by removing semicolon for choosen PowerTask below and remember to
        inactivate the DllCall for Hibernation by inserting a semicolon in front of that codeline. 
        WindowsXP users only!!! If using the "Intercept Hibernation/shutdown script" you will have the opportunity to cancel System Closedown through a messagbox and
        simultainously be presented with several options (Hibernate, Standby, Shutdown, Restart or Cancel ) what to do next.  
        */
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;Hibernates HTPC if all above conditions are met. 
        ;DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0) ;Standby mode for your HTPC if all above conditions are met. 
        ;Shutdown, 1 ;This option will shutdown your HTPC.

        /*
        Codelines below can be used to activate Rec.Service native PowerTASKs. WinXP users will get the RS messagebox which allows you to abort shutdown within 10 seconds.   
        If using this option the "Intercept Hibernation/shutdown script" will not be needed (WinXP only). Activate by removing semicolon for Task of choice below and remember to 
        inactivate the DllCall above by inserting a semicolon in front of that codeline. Don't forget to fill in your username and password in the URL otherwise it won't work.
        */
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Hibernate&aktion=tasks") ;If choosen activates Rec.Service own Hibernation task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Standby&aktion=tasks") ;If choosen activates Rec.Service own Standby task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Shutdown&aktion=tasks") ;If choosen activates Rec.Service own Shutdown task.
     Else
        Return ;One or more conditions above is NOT met...hibernation will be cancelled.
}

If DateVar not between 2 and 6 ;Specifies hibernation rules between Saturday=7 and Sunday=1. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 02:00:00 and 09:00:00 
    If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
     If RS_ClientCountStatus = 0 ;Hibernation will be allowed only if no clients are connected to RS. 
      If RS_TimeToNextRecordingVar >= 30
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;Hibernates HTPC if all above conditions are met. 
        ;DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0) ;Standby mode for your HTPC if all above conditions are met. 
        ;Shutdown, 1 ;This option will shutdown your HTPC.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Hibernate&aktion=tasks") ;If choosen activates Rec.Service own Hibernation task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Standby&aktion=tasks") ;If choosen activates Rec.Service own Standby task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Shutdown&aktion=tasks") ;If choosen activates Rec.Service own Shutdown task.
     Else
        Return
}

Edited by majstang
Link to comment

Thank you very very much :bounce:. The script works nicely, no more annoying shutdown dialogs to cancel when watching tv :). I came up with another idea to improve the script. In addition to DVBViewer, I also use XBMC as frontend to my HTPC. Would it be possible that the script could also check running processes and if it finds xbmc.exe running then discard the shutdown again with no notification? I only keep DVBViewer/xbmc running if using them actively (watching tv/videos, listening music) so then I wouldn't have to worry about the shutdown if for example I'm listening music with XBMC. This function would also be handy if you are frequently running some other applications, or for example games, which you don't want the shutdown message to interrupt.

Link to comment

Thank you very very much :bounce:. The script works nicely, no more annoying shutdown dialogs to cancel when watching tv :)

You're welcome :) Only thing when using clientcount variable is to remember to close the client when finished watching TV otherwise this variable will cancel all standby/hibernation. Im sure you are aware of this already...only pointing this out to make it clear for others.

 

I came up with another idea to improve the script. In addition to DVBViewer, I also use XBMC as frontend to my HTPC. Would it be possible that the script could also check running processes and if it finds xbmc.exe running then discard the shutdown again with no notification? I only keep DVBViewer/xbmc running if using them actively (watching tv/videos, listening music) so then I wouldn't have to worry about the shutdown if for example I'm listening music with XBMC. This function would also be handy if you are frequently running some other applications, or for example games, which you don't want the shutdown message to interrupt.

Yes, this is possible, but since XBMC is not a part of Recording Service and the DVBViewer system Im not especially keen on adding this to the base script. I also have no idea how widespread the use of XBMC is. I can at least give you the codelines and you can insert them in the script yourself.

 

Add these two lines right under "FormatTime, DateVar,, WDay ; 1=Sunday, 2=Monday etc." on an empty line...never on the same line as other code.

 

Process, Exist, xbmc.exe
XBMC_Status:=ErrorLevel

 

Now add this If statement right under "If RS_ClientCountStatus"

 

If XBMC_Status = 0

 

Let me know how it works for you!

:bye:

Link to comment

Again a big thanks to you for the code :). It works perfectly. Of course it's not a good idea to include these user related codelines to the actual script. But now everyone can put their own shutdown blocking applications to their script if needed. I'm definitely adding also for example all my party games (ultrastar, guitar heros... :)) to the script so they don't ever get disrupted by the shutdown message. I think now in my setup, the RS shutdown after recording never needs any user attention which is obviously the perfect situation. Once again thank you! I'll be in touch if I come up with any other ideas. I doubt it because the script is now perfect :).

Link to comment

I think now in my setup, the RS shutdown after recording never needs any user attention which is obviously the perfect situation. Once again thank you! I'll be in touch if I come up with any other ideas. I doubt it because the script is now perfect :).

Yes, this was my big goal with the script...no user attention at all...just set it and forget it. Thanks, it is really fun to get such positive feedback:)

:bye:

Link to comment
  • 1 month later...

Hi majstang,

 

man, I was waiting a long time for this kind of script. Great work!

Unfortunatly the hibernatescript does not work for me on Win7. I am not an expert in scripting, but I have limited the problem to this line:

 

 If RS_TimeToNextRecordingVar >= 30 

 

Of course I checked if any recording are scheduled in the next 30minutes. I even deleted all scheduled recordings, but the script exits the if loop at this line.

 

If I delete the line above, the script works very well in combination with the intercept script for Win7.

 

If I have correctly understood the script, you check this link http://127.0.0.1:8089/api/timerlist.html (in my case port 8089 no user/password) to build the Variable RS_TimeToNextRecordingVar.

 

In my Case without timers, the XML File looks like this:

 

  <?xml version="1.0" encoding="iso-8859-1" ?> 
 <Timers />

 

I do not know how to debug step by step with autohotkey so that one can see what is written in that Var (may be with a Message box).

 

Any help will be great.

Thanks!

Link to comment

Forgotten something:

 

Another issue with the Message Box of the intercept script: I usually use Windows Media Center to watch videos. Unfortunately when WMC is in fullscreen mode the message box pops up undiscovered in the background so that one can not intercept to cancel the hibernation process. I can not use the solution mentioned above in the thread for Tuomiopuuma, because I let WMC always running even when using DVBViewer. In that case WMC is minimized.

Is there a command line so that the messagebox gets to the front of the WMC?

 

Thanks again!

Link to comment

 

Of course I checked if any recording are scheduled in the next 30minutes. I even deleted all scheduled recordings, but the script exits the if loop at this line.

 

If I delete the line above, the script works very well in combination with the intercept script for Win7.

 

If I have correctly understood the script, you check this link http://127.0.0.1:8089/api/timerlist.html (in my case port 8089 no user/password) to build the Variable RS_TimeToNextRecordingVar.

 

In my Case without timers, the XML File looks like this:

 

  <?xml version="1.0" encoding="iso-8859-1" ?> 
 <Timers />

 

I do not know how to debug step by step with autohotkey so that one can see what is written in that Var (may be with a Message box).

Hi Tobias!

 

I always use these lines in my script for debugging purposes. Insert them just before the if statements on an empty line. These lines creates an ini-file with all results from the Recording Service API query. You might need to change the path where the ini-file should be created.

 

IniWrite, %DateVar%, E:\DVBViewer RecService Status.ini, Day_of_Week, Key
IniWrite, %TimeVar%, E:\DVBViewer RecService Status.ini, CurrentTime, Key
IniWrite, %RS_StatusVar%, E:\DVBViewer RecService Status.ini, RS_Status, Key
IniWrite, %RS_TimeToNextRecordingVar%, E:\DVBViewer RecService Status.ini, RS_TimeToNextRecording, Key
IniWrite, %RS_ClientCountStatus%, E:\DVBViewer RecService Status.ini, RS_ClientCountStatus, Key

 

This XML file you are referring to are you sure it is the C:\ProgramData\CMUV\DVBViewer\config\svctimers.xml? Cuz empty it should look like this:

<?xml version="1.0" encoding="utf-8"?>
 <Timers/>

 

"utf-8" means unicode. What version of DVBViewer and Recording Service are you using?

 

The query link for your RS_TimeToNextRecordingVar should therefor look like this:

OutputVar := UrlDownloadToVar("http://127.0.0.1:8089/api/timerlist.html[?utf8=]")

Link to comment

Forgotten something:

 

Another issue with the Message Box of the intercept script: I usually use Windows Media Center to watch videos. Unfortunately when WMC is in fullscreen mode the message box pops up undiscovered in the background so that one can not intercept to cancel the hibernation process. I can not use the solution mentioned above in the thread for Tuomiopuuma, because I let WMC always running even when using DVBViewer. In that case WMC is minimized.

Is there a command line so that the messagebox gets to the front of the WMC?

 

Thanks again!

This line in the Interceptscript for Windows 7 dictates how the messagebox should behave:

Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=580, HtmH=200, BDefault=1, DlgBgColor=0xEE0000, DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"

 

DlgTopmost=1 means the messagebox is set to be Always-On-Top.

 

I can see two possible causes for your issue:

1. WMC is also set as Always-On-Top and have superiority. In such a case I would play around with the WMC settings.

2. When you copy this script from this thread, make sure the whole Options line stays on one line with no rowbreaks. I did notice earlier when I did copy the script myself from this forum and pasted it into a notepad document the optionsline looked like this:

Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=580, HtmH=200, BDefault=1, DlgBgColor=0xEE0000, 

DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"

The criterias after the rowbreak will not work, but in such a case you will get a warning during startup of this exe (if you have it in autostart).

Edited by majstang
Link to comment

Hi majstang,

 

many thanks for the hints. I will try them later when I am home.

 

The Rec Service is, as I remember 1.6.something beta, don't know the exact Version, I ve installed it some time ago. I never update a running system :biggrin:

 

Will look at it later.

 

Thanks for your support!

Link to comment

Hello Majistang,

 

unfortunately the script did not work for me under windows 7, there were some problems:

 

1)The declared function UrlDownloadToVar() in the hibernation script did not work for me. After searching the forums of autohotkey I found that the function causes trouble on some machines, so I chaged it with these few lines, now it works great for me:

 

UrlDownloadToVar(sURL) 
{  
COM_Init() 
pwhr := COM_CreateObject("WinHttp.WinHttpRequest.5.1") 
COM_Invoke(pwhr, "Open", "GET", sURL) 
COM_Invoke(pwhr, "Send") 
sResponseText := COM_Invoke(pwhr, "ResponseText") 
COM_Release(pwhr) 
COM_Term() 
return, sResponseText 
}

 

When Compiling the script the COM.ahk Library must be in the same directory as the script. The Library can be downloaded here.

 

2)Now after I get the above function to work and receiving the needed variables ( RS_StatusVar, RS_TimeToNextRecordingVar and so on...) I was confronted with another problem. When I started the hibernation script manually by double clicking on it, the interception script worked great and the html interception message came up. BUT when the hibernation script was started from the DVBViewer recording service as a Task executed after a TV record, nothing happend! After some time of searching, I've found the problem: Since Vista, a windows service can not communicate with a desktop application. It seems like UrlDownloadToVar() function needed that and the hole application was terminated. Even allowing the record service to communicate to desktop application(checkbox in the services) did not solve the problem. So the question was now: how to pass the "go on" order to the interception script from a windows Service? SendMessage and PostMessage did not work cause they are, as it seems, desktop communication. On the Net I`ve found that this could be done in C with named pipes, but as an absolutely programming greenhorn this was too tricky for me.

 

Enough talking, now this is the solution for me:

 

After ending a TV record, the recording service starts a simple batch file creating an event in the windows Event Log. The batch file has only two lines:

eventcreate /T WARNING /ID 999 /L APPLICATION /D "DVBViewer Hibernate Trigger"
exit

 

This Event above is the trigger for a scheduled task, the hibernation script it self. In this way the communication from the service is separated from the desktop app.

The hibernation script checks the conditions (all if statements) and post a message to the Interception Script hidden window:

 

SetTitleMatchMode 2
DetectHiddenWindows On
SendMessage, 0x5555, 0, 0,,ruhe3.exe ; ruhe3.exe is in my case the interception script
DetectHiddenWindows Off; 

 

On the other side, the interception script is listenig to the message above and starts the hibernation menu as soon as it arrives:

 

OnMessage(0x5555, "RunBeforeShutdown")

 

In my case even the turn off button of my harmony remote control is now mapped through eventghost to your hibernation script and I can forget completly any worries about turning or not turnig off the htpc while recodring.

 

3)I ve solved the problem with the wmc in fullscreen and the not appearing hibernation menu in front of it, with eventgohst. When the Menu appears the wmc pauses any playing video, minimizes it self and the hibernation menu appears. If I cancel it, the wmc returns in full screen and the video continue to play. I know it is not the most "beautyful" way, but it works perfectly.

 

May be with more experience in autohotkey and C, I can one day create a hibernation message box with wmc appearing. All the needed Utilities (dlls) are already within windows 7 in the so called Windows Presentation Foundation hosted application (WPF) See here (especially the section "Integrating with the WMC Managed APIs"). In combination with the autohotkey CLR.ahk library (see here), one can integrate the needed c code directly in the autohotkey script getting then a real WMC intercept menu :)

 

Any way, many thanks again for the this script, it is the best way for me now to handle the hibernation problem of my htpc.

 

Tobias

Link to comment

Hi Tobias!

 

After some extensive testing your contibution exposes a huge misstake from my part. Arrogant enough I didnt test the shutdown communication between the Intelligent Hibernationscript inside the RS sending through shutdown commands for the Interceptscript for Windows 7 to intercept :blush: I took for granted it worked exactly like it does on WinXP. When testing I only executed the hibernationscript manually from the explorer and that works without any problem, which is obvious because in such a situation both scripts are located outside of any windows service application and the interception goes without a hitch.

 

However I do get quite another results with my tests compared to yours. Yes it seems MS removed something when it comes to communication between windows service applications and desktop applications on Vista and forward. But they have not removed getting commands through. This because of the simple fact I have it working (partly). I can initiate a shutdown from the hibernation script triggered from inside the recording service, BUT when doing so RS sends out a Force-Shutdown which is not interceptable instead of the ordinary shutdown command which my script would have intercepted just fine. The intresting part is why does this differ from the experience from WinXP? Doing some tests gives the difference between WinXP and Win7:

 

WinXP:

DVBV Client running, Using RS shutdown task --> Force-Shutdown, Interceptionscript wont work.

DVBV Client running, Using IntelligenHibernation shutdown task from inside RS --> Ordinary Shutdown. Interceptionscript works fine.

DVBV Client running, Initiate shutdown from Windows start menu --> Ordinary Shutdown, Interceptionscript works fine. DVBViewer Client also blocks shutdown if the interceptionscript isnt started.

 

Win7:

DVBV Client running, Using RS shutdown task --> Force-Shutdown, Interceptionscript wont work.

DVBV Client running, Using IntelligenHibernation task from inside RS --> Force-Shutdown, Interceptionscript wont work.

DVBV Client running, Initiate shutdown from Windows start menu --> Ordinary Shutdown, Interceptionscript works fine, DVBViewer Client also blocks shutdown if the interceptionscript isnt started.

 

I really can't explain this result. Shutdown command from IntelligentHibernation task seems to go through, but Windows 7 does not interpret it as an ordinary shutdown command and instead uses the default RS Force-Shutdown. On XP this very thing works great. Very Very strange!

 

I even tested your approach, trying to get a clue whats going on with the communication between windows service applications and desktop applications on WinXP compared to Win7. I did send the 0x5555 message from inside RS using the IntelligentHibernation task directly to a modifyed interception script, but that did not work either on WinXP or Win7. It only works if using the batchfile and windows scheduler part you came up with.

 

I don't know if it would help if RS developers change the Force-Shutdown method they have as default today. It's likely the developers did choose this approach when they were forced to deal with their own decisions from the past, namely to choose to have the DVBViewer application block shutdown per default (there are a bunch of threads on the forum where people are complaining about this choice). People using the Recording Service would have gotten furious if RS fails to shutdown the HTPC if DVBV client is running each and every time. The solution was Force-Shutdown. The Force-shutdown just shuts down all applications and bypasses the ordinary VM_ENDSESSIONQUERY and therefor my interceptscript gets no message and fails. Here is the thread i started to adress this: http://www.DVBViewer.tv/forum/topic/42794-new-rs-uses-forceful-shutdown/

 

Well, this whole thing serves as an another pro argument for removing the fact DVBViewer application replying false to VM_QUERYENDSESSION and subsequently also change force-shutdown approach from RS entirely. If removing the first there is no need of the second. In the meantime I'm afraid we do not have any other choice, but to use your solution to get the Intercept Shutdown script for Windows 7 to work as intended. I will post the needed scriptadaptations and further details how to set it up. I do not like the batchfile and windows scheduler part though and maybe I can find some solution i can integrate into the hibernationscript. I will investigate it. Thanks for your valuable input, Tobias! Nice work!

 

You also mensioned that the DownloadToVar functions didnt work on your machine. But you were abled to get the RS status variable accurate if Im not mistaken? That shows it did work, but your problem was probably XML format related. Did you find out why your RS 1.6.5.2 used iso-8859-1 encoding on your svctimers.xml? It really should have used utf-8 (unicode). It would have been intresting to know if the right XML encoding had solved your DownloadToVar issue.

 

Regards

Majstang

Link to comment

You also mensioned that the DownloadToVar functions didnt work on your machine. But you were abled to get the RS status variable accurate if Im not mistaken? That shows it did work, but your problem was probably XML format related. Did you find out why your RS 1.6.5.2 used iso-8859-1 encoding on your svctimers.xml? It really should have used utf-8 (unicode). It would have been intresting to know if the right XML encoding had solved your DownloadToVar issue.

 

Regards

Majstang

 

Hi Majstang,

 

yes I get now the right Variables with the modified DownloadtoVar function mentionend above. The iso 8859-1 issue was not the Problem. I got the utf8 Version with simply changing the initial URL (http://127.0.0.1:8089/api/status.html) with (http://127.0.0.1:8089/api/status.html[?utf8=]. Even with the utf8 xml file, the initial DownloadtoVar function did not work on my machine. The problem was in the function itself, it uses Winint to connect to the URL which seems not to be stable under win7 as I ve read in the autohotkey forum.

 

I agree with you that the solution with the batch file is not state of the art. I simply searched for a way to separate the communication between the windows service and the desktop application. So I used the eventlog/task schedule as a medium for passing the trigger command to the script.

 

For a better undestanding here is the action chain:

 

Recording finished-->RS only starts the batch File which creates an event in the windows event log, RS does not hibernate-->Scheduled Task with the hibernation script starts and sends a Message* to interception script-->interception script receives the message and starts the hibernation cowntdown.

 

 

*The 0x5555 is arbitrary choosen, it must simply be the same on the receiving part in the interception script and should be above 0x4000 so that it can't interfere with other standard windows messages (precaution only).

 

 

May be there is a more elegant way to solve the issue with only one exe file which will be executed by the RS and could communicate to the desktop app (interception script). When I get some time(and brain :)) I will try with named pipes.

 

Tobias

Link to comment
  • 3 weeks later...

Adapted Windows 7 Intelligent Hibernation and Interception package

 

Tobias.s brought to my attension the Intercept Shutdown script for Windows 7 wasnt working as intended and elegantly provided a working solution. Many thanks for that! The solution did include Setting up a Windows Scheduler Task and Windows Eventlog batchtrigger. After getting some help from HotKeyIt on the Autohotkey forum there is now a solution that makes these steps unnecessary. The Intelligent hibernationscript can once again be executed as the main after recording task according to the way used before. You can read more about the solution here:

http://www.DVBViewer.tv/forum/topic/43239-launch-applications-from-recording-service/page__view__findpost__p__318224

This is the presentation of the required script adaptations to get this solution to work and how to set it up. This setup does ONLY apply to Windows 7 systems. The original IntelligentHibernation script does still work as it should on Windows 7 on it's own without any Interceptions script. By using the native RS shutdown/hibernations task provided in the IntelligentHibernation script you will get a chance to cancel the hibernation/standby/shutdown when the script allows that (10 second countdown messagebox). The solution presented down below however is ONLY for those who wanna have a nicer looking cancel messagebox with more design possibilities and more poweroptions.

 

post-56433-0-58522300-1289309003_thumb.jpg

 

How to setup:

 

1. Copy the code right below and paste it into an emty notepad sheet. Change the path to what path you choose for the Receiverscript.exe on the last line in the script. Name the file to Receiverscript.ahk

Save and compile the .ahk file to an .exe. Make a shortcut and drag it to the autostart folder on the start-menu. Start it manually if you dont wanna restart Windows at this point. Have in mind this script MUST be started before running the Intelligent Hibernationscript from RS. The autostart takes care of that.

 

#NoTrayIcon
While !DllCall("WaitNamedPipe","Str","\\.\pipe\Receiverscript","UInt",0xffffffff)
Sleep, 500
Run % """" A_AhkPath """ \\.\pipe\Receiverscript"
Sleep, 500
Run, Receiverscript.exe, D:\ScriptsForWindows7 ;Change to your own path for this receiverscript

2. See the adapted IntelligentHibernation script below. Copy it and save it as IntelligentHibernation.ahk and then complie to an exe.

 

3. If you not already have created the IntelligentHibernation task:

Rightclick the RS systrayicon and choose Configuration. Go to Tasks and create a new task. Name it IntelligentHibernation and also type in the path for the IntelligentHibernation.exe file (e.g. C:\ IntelligentHibernation.exe) in the Filenamebox or click the 3 dot button to the right and navigate to the IntelligentHibernation.exe.

Close the Task Editor and the Configuration window.

 

4. Open up RS webinterface. Click on Configuration-->Recorder. Under "Default recording actions" and "Default task after recording:" select the process task you created " IntelligentHibernation". Remember if you have search presets created before this step they all have the default task after recording inherited, so the change you just did wont have any effect on recordingtimers created with these old search presets. Simply bring up your searchpresets in the SearchEPG and manually edit them one by one until all old presets have the " IntelligentHibernation" as the default task after recording.

 

5. See the adapted IntercepShutdown script below. Copy it and save it as InterceptShutdown.ahk and then compile it to an exe. Make a shortcut of this exe and then place it in the autostartfolder on Windows 7 startmeny. This script then gets started when Window 7 starts. Start it manually if you dont wanna restart Windows at this point. Now everything should work.

 

 

Adapted Intelligent Hibernationscript for Windows 7

 

 

#NoTrayIcon
FormatTime, TimeVar,, HH:mm:ss ;Current local time.
FormatTime, DateVar,, WDay ; 1=Sunday, 2=Monday etc.

OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/timerlist.html[?utf8=]") ;Fill in your own username, password and portnumber.
StringReplace, OutputVar, OutputVar, <Timer, % Chr(4) . "<Timer", All
StringReplace, OutputVar, OutputVar, </Timer>, % "</Timer>" . Chr(4), All
MyList := A_Now A_Tab "<now>"
While pos := RegexMatch( OutputVar,"<Timer[^>]*Date=""(?<_D>\d+)\D(?<_M>\d+)\D(?<_Y>\d+)""[^>]*Start="""
. "(?<_H>\d+)\D(?<_N>\d+)\D(?<_S>\d+)""[^\x04]*<ID>(?<_ID>\d*)", Tmr, A_Index = 1 ? 1 : pos + StrLen(Tmr) )
  MyList .= "`n" . Tmr_Y . Tmr_M . Tmr_D . Tmr_H . Tmr_N . Tmr_S . A_Tab . Tmr_ID
Sort, MyList, N

set=0
Loop, Parse,MyList, `n
{
if set=1
{
datetime:=A_LoopField
break
}
IfInString, a_loopfield,<now>
set=1
}
StringSplit, datetime,datetime,%A_Tab%
EnvSub, datetime1,A_Now,min
RS_TimeToNextRecordingVar:=datetime1 ;time in minutes to next recording


OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html") ;Fill in your own username, password and portnumber.
FoundPos := RegExMatch(OutputVar, "(?<=recordcount>)(.)", SubPat)
RS_StatusVar:=SubPat ;status of the recording service

OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html") ;Fill in your own username, password and portnumber.
FoundPos := RegExMatch(OutputVar, "(?<=clientcount>)(.)", SubPat2)
RS_ClientCountStatus:=SubPat2 ;Number of clients connected to the recording service

UrlDownloadToVar(URL, Proxy="", ProxyBypass="")
{
AutoTrim, Off
hModule := DllCall("LoadLibrary", "str", "wininet.dll")

If (Proxy != "")
AccessType=3
Else
AccessType=1
;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

io_hInternet := DllCall("wininet\InternetOpenA"
, "str", "" ;lpszAgent
, "uint", AccessType
, "str", Proxy
, "str", ProxyBypass
, "uint", 0) ;dwFlags

iou := DllCall("wininet\InternetOpenUrlA"
, "uint", io_hInternet
, "str", url
, "str", "" ;lpszHeaders
, "uint", 0 ;dwHeadersLength
, "uint", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
, "uint", 0) ;dwContext

If (ErrorLevel != 0 or iou = 0) {
DllCall("FreeLibrary", "uint", hModule)
return 0
}

VarSetCapacity(buffer, 512, 0)
VarSetCapacity(NumberOfBytesRead, 4, 0)
Loop
{
 irf := DllCall("wininet\InternetReadFile", "uint", iou, "uint", &buffer, "uint", 512, "uint", &NumberOfBytesRead)
 NOBR = 0
 Loop 4  ; Build the integer by adding up its bytes. - ExtractInteger
   NOBR += *(&NumberOfBytesRead + A_Index-1) << 8*(A_Index-1)
 IfEqual, NOBR, 0, break
 ;BytesReadTotal += NOBR
 DllCall("lstrcpy", "str", buffer, "uint", &buffer)
 res = %res%%buffer%
}
StringTrimRight, res, res, 2

DllCall("wininet\InternetCloseHandle",  "uint", iou)
DllCall("wininet\InternetCloseHandle",  "uint", io_hInternet)
DllCall("FreeLibrary", "uint", hModule)
AutoTrim, on
return, res
}

If DateVar between 2 and 6 ;Specifies hibernation rules between Monday=2 and Friday=6. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 00:00:00 and 15:00:00 ;Specifies which time to allow hibernation. Set to the value you prefer! Always use LowerBound and UpperBound format, like my example.
   If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
    ;If RS_ClientCountStatus = 0 ;Hibernation will be allowed only if no clients are connected to RS. 
     If RS_TimeToNextRecordingVar >= 30 ;If minutes to next recording is more than 30, HTPC will hibernate. Set to the value you prefer!
        {      
          Sleep, 4000 ;Just wait a little before creating pipe
          #NoEnv
          ptr := A_PtrSize ? "Ptr" : "UInt"
          char_size := A_IsUnicode ? 2 : 1
          Script=
          (
          SetTitleMatchMode, 2
          DetectHiddenWindows, On
          SendMessage, 0x5555, 0, 0,,InterceptShutdown.exe ; InterceptShutdown.exe is in my case the interceptionscript
          DetectHiddenWindows, Off
          )

          ; To prevent "collision", pipe_name could be something mostly "unique", like:
          ;   pipe_name := A_TickCount
          pipe_name := "Receiverscript"

          ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes
          ; the pipe to close, so we must create a second pipe for the actual file contents.
          ; Open them both before starting AutoHotkey, or the second attempt to open the
          ; "file" will be very likely to fail. The first created instance of the pipe
          ; seems to reliably be "opened" first. Otherwise, WriteFile would fail.
          pipe_ga := CreateNamedPipe(pipe_name, 2)
          pipe    := CreateNamedPipe(pipe_name, 2)
          if (pipe=-1 or pipe_ga=-1) 
           {
             MsgBox CreateNamedPipe failed.
             ExitApp
           }

          ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes().
          DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0)
          ; This pipe is not needed, so close it now. (The pipe instance will not be fully
          ; destroyed until AutoHotkey also closes its handle.)
          DllCall("CloseHandle", ptr, pipe_ga)
          ; Wait for AutoHotkey to connect to open the "file".
          DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0)

          ; Standard AHK needs a UTF-8 BOM to work via pipe.  If we're running on
          ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead:
          Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script

          char_size := (A_IsUnicode ? 2:1)
          if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0)
          MsgBox WriteFile failed: `%ErrorLevel`%/`%A_LastError`%

          DllCall("CloseHandle", ptr, pipe)


          CreateNamedPipe(Name, OpenMode=3, PipeMode=0, MaxInstances=255) 
           {
             global ptr
             return DllCall("CreateNamedPipe","str","\\.\pipe\" Name,"uint",OpenMode
             ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr)
           }
        }
    Else
        Return ;One or more conditions above is NOT met...hibernation will be cancelled.
}

If DateVar not between 2 and 6 ;Specifies hibernation rules between Saturday=7 and Sunday=1. Always use LowerBound and UpperBound format, like my example.
{
 If TimeVar between 02:00:00 and 09:00:00 
    If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
     ;If RS_ClientCountStatus = 0 ;Hibernation will be allowed only if no clients are connected to RS. 
      If RS_TimeToNextRecordingVar >= 30
        {
          Sleep, 4000 ;Just wait a little before creating pipe
          #NoEnv
          ptr := A_PtrSize ? "Ptr" : "UInt"
          char_size := A_IsUnicode ? 2 : 1
          Script=
          (
          SetTitleMatchMode, 2
          DetectHiddenWindows, On
          SendMessage, 0x5555, 0, 0,,InterceptShutdown.exe ; InterceptShutdown.exe is in my case the interceptionscript
          DetectHiddenWindows, Off
          )

          ; To prevent "collision", pipe_name could be something mostly "unique", like:
          ;   pipe_name := A_TickCount
          pipe_name := "Receiverscript"

          ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes
          ; the pipe to close, so we must create a second pipe for the actual file contents.
          ; Open them both before starting AutoHotkey, or the second attempt to open the
          ; "file" will be very likely to fail. The first created instance of the pipe
          ; seems to reliably be "opened" first. Otherwise, WriteFile would fail.
          pipe_ga := CreateNamedPipe1(pipe_name, 2)
          pipe    := CreateNamedPipe1(pipe_name, 2)
          if (pipe=-1 or pipe_ga=-1) 
           {
             MsgBox CreateNamedPipe failed.
             ExitApp
           }

          ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes().
          DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0)
          ; This pipe is not needed, so close it now. (The pipe instance will not be fully
          ; destroyed until AutoHotkey also closes its handle.)
          DllCall("CloseHandle", ptr, pipe_ga)
          ; Wait for AutoHotkey to connect to open the "file".
          DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0)

          ; Standard AHK needs a UTF-8 BOM to work via pipe.  If we're running on
          ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead:
          Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script

          char_size := (A_IsUnicode ? 2:1)
          if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0)
          MsgBox WriteFile failed: `%ErrorLevel`%/`%A_LastError`%

          DllCall("CloseHandle", ptr, pipe)


          CreateNamedPipe1(Name, OpenMode=3, PipeMode=0, MaxInstances=255) 
           {
             global ptr
             return DllCall("CreateNamedPipe","str","\\.\pipe\" Name,"uint",OpenMode
             ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr)
           }
        }
    Else
        Return
}

 

 

Adapted Intercept Shutdown script for Windows 7

 

 

#NoTrayIcon
#Persistent
SetTimer, RunBeforeShutdown, Off
SetTimer, RunBeforeShutdown2, Off
Gui,+LastFound
hwnd:=WinExist()
DllCall("ShutdownBlockReasonCreate","Uint",hwnd,"Str",A_ScriptFullPath "is still running")
DllCall("kernel32.dll\SetProcessShutdownParameters", UInt, 0x4FF, UInt, 0)
OnMessage(0x11, "WM_QUERYENDSESSION")
OnMessage(0x5555, "RunBeforeShutdown2")
Return

WM_QUERYENDSESSION(wParam, lParam)
 {
   static sdtry = 0
   ENDSESSION_Logoff = 0x80000000
   If (lParam & ENDSESSION_Logoff) ; User is logging off.
     EventType = Logoff
   Else     ; System is either shutting down or restarting. and
     EventType = Shutdown
   If (EventType = "Shutdown" and sdtry = 0)
    {
      SetTimer, RunBeforeShutdown, On
      Return false ; Tell the OS to Abort the Shutdown/Logoff.
    }
   Else If (EventType = "Shutdown" and sdtry = 1)
     Return true
 }

RunBeforeShutdown2(wParam, lParam, msg)
 {
   SetTimer, RunBeforeShutdown2, On
   Return true
 }

RunBeforeShutdown:
SetTimer, RunBeforeShutdown, Off
SendInput, {ENTER}
Sleep, 1000
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%  

FileDelete, demo.htm
FileAppend,
(
<html>
<body style="overflow:hidden">
<body bgcolor="#0033FF" leftmargin="1" topmargin="1">
<div align="Center"><p>
<font color="#FFFB02" face="Segoe Print" size="4"><br><b>
Your HTPC is about to be Closed Down.
<br>
You now have a chance to choose closedown method
<br>
or wait until default method gets choosen for you</b>
</p>
<font face="Segoe Print" size="5"><b>
<script type="text/javascript">
var countDownInterval=20; 
var countDownTime=countDownInterval+1; 
function countDown(){ 
countDownTime--; 
if (countDownTime <=0){ 
countDownTime=countDownInterval; 
clearTimeout(counter); 
//window.location=""; 
return 
} 
if (document.getElementById) //else if NS6+ 
document.getElementById("countDownText").innerHTML=countDownTime+" ";
else if (document.layers){ //CHANGE TEXT BELOW TO YOUR OWN 
document.c_reload.document.c_reload2.document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
document.c_reload.document.c_reload2.document.close() 
} 
counter=setTimeout("countDown()", 1000); 
} 

function startit(){ 
if (document.getElementById) //CHANGE TEXT BELOW TO YOUR OWN 
document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
countDown() 
} 

if (document.getElementById) 
startit() 
else 
window.onload=startit 
clearTimeout ( countDownTime );
</script>
</font></b>
</div>
</body>
</html>
)
, demo.htm


URL=file:///%A_ScriptDir%\demo.htm
Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=580, HtmH=200, BDefault=1, DlgBgColor=0xEE0000, DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"

Sel := HtmDlg( URL, "", Options )

if (Sel = 1)
 {
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
  Return
 }
else if (Sel = 2)
 {
  DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
  Return
 }
else if (Sel = 3)
 {
  Process, Close, DVBViewer.exe
  Shutdown, 1
  ExitApp
  Return
 }
else if (Sel = 4)
 {
  Process, Close, DVBViewer.exe
  Shutdown, 2
  ExitApp
  Return
 }
else if (Sel = 5)
 {
  hibernate = 0
  Return
 }

DllCall("ShutdownBlockReasonDestroy","Uint",hwnd)
Return                                                 ; // end of auto-execute section //

RunBeforeShutdown2:
SetTimer, RunBeforeShutdown2, Off
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%  

FileDelete, demo.htm
FileAppend,
(
<html>
<body style="overflow:hidden">
<body bgcolor="#0033FF" leftmargin="1" topmargin="1">
<div align="Center"><p>
<font color="#FFFB02" face="Segoe Print" size="4"><br><b>
Your HTPC is about to be Closed Down.
<br>
You now have a chance to choose closedown method
<br>
or wait until default method gets choosen for you</b>
</p>
<font face="Segoe Print" size="5"><b>
<script type="text/javascript">
var countDownInterval=20; 
var countDownTime=countDownInterval+1; 
function countDown(){ 
countDownTime--; 
if (countDownTime <=0){ 
countDownTime=countDownInterval; 
clearTimeout(counter); 
//window.location=""; 
return 
} 
if (document.getElementById) //else if NS6+ 
document.getElementById("countDownText").innerHTML=countDownTime+" ";
else if (document.layers){ //CHANGE TEXT BELOW TO YOUR OWN 
document.c_reload.document.c_reload2.document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
document.c_reload.document.c_reload2.document.close() 
} 
counter=setTimeout("countDown()", 1000); 
} 

function startit(){ 
if (document.getElementById) //CHANGE TEXT BELOW TO YOUR OWN 
document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
countDown() 
} 

if (document.getElementById) 
startit() 
else 
window.onload=startit 
clearTimeout ( countDownTime );
</script>
</font></b>
</div>
</body>
</html>
)
, demo.htm


URL=file:///%A_ScriptDir%\demo.htm
Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=580, HtmH=200, BDefault=1, DlgBgColor=0xEE0000, DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"

Sel := HtmDlg( URL, "", Options )

if (Sel = 1)
 {
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
  Return
 }
else if (Sel = 2)
 {
  DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
  Return
 }
else if (Sel = 3)
 {
  Process, Close, DVBViewer.exe
  Shutdown, 1
  ExitApp
  Return
 }
else if (Sel = 4)
 {
  Process, Close, DVBViewer.exe
  Shutdown, 2
  ExitApp
  Return
 }
else if (Sel = 5)
 {
  hibernate = 0
  Return
 }

DllCall("ShutdownBlockReasonDestroy","Uint",hwnd)
Return                                                 ; // end of auto-execute section //

;#Include HtmDlg.ahk ; You may copy/Paste HtmDlg() Instead
HtmDlg( _URL="", _Owner=0, _Options="", _ODL="," ) {     ; HTML DialogBox v0.57 -- by SKAN
; Topic: www.autohotkey.com/forum/viewtopic.php?t=60215    CD:09-Jul-2010 | LM:05-Aug-2010
; Credit: WebControl Demo by Sean - www.autohotkey.com/forum/viewtopic.php?p=103987#103987

Static _hInst,_hDLG,_DlgP,_B$,_B$L,_pIWEB,_pV,_DlgT,CliC, HtmF=0,_Brush=0,   BDef=1,BEsc=0

If ( A_EventInfo = 0xCBF ) {                                   ; nested Callback Function
  hWnd := _URL,  uMsg := _Owner,  wP := _Options,  lP := _ODL

  If ( uMsg=0x112 && wP=0xF060 )                               ; WM_SYSCOMMAND & SC_ClOSE
    Return DllCall( "DestroyWindow", UInt,_hDLG ) | ( BDEf:=BEsc )

  If ( uMsg=0x111 && (wP>>16)=0 )                              ; WM_COMMAND & BN_CLICKED
    Return DllCall( "DestroyWindow", UInt,_hDLG ) | ( BDef := (wP=2) ? BEsc : wP-100  )

  If ( uMsg=0x007 && HtmF=0 )                                  ; WM_SETFOCUS
    Return DllCall( "SetFocus", UInt,DllCall( "GetDlgItem", UInt,_hDLG, UInt,100+BDEF ) )

  If ( uMsg=0x201 && CliC )                                    ; WM_LBUTTONDOWN
    Return DllCall( "DestroyWindow", UInt,_hDLG ) |  ( BDEf := 1 )

  If ( uMsg=0x136 && _Brush<>0 )                               ; WM_CTLCOLORDLG
    Return _Brush

  if ( uMsg=0x002 && hWnd=_hDLG )                              ; WM_DESTROY
    Return _Brush := DllCall( "DeleteObject", UInt,_Brush, UInt ) >> 32

Return False
}

If ! ( _hInst ) {
_hInst := DllCall( "GetModuleHandle", Str,A_IsCompiled ? A_ScriptFullpath : A_AhkPath )

_DT := "61160CD3AFCDD0118A3EGC04FC9E26EZQ1GFFFFUCHC88GAZO9G9G1I4DG53G2H53G68G65G6CG6CG2H"
. "44G6CG67ZL5V64K41G74G6CG41G78G57G69G6EK7BG38G38G35G36G46G39G36G31G2DG33G34G3H41G2DG31"
. "G31G44G3H2DG41G39G36G42G2DG3H3H43G3H34G46G44G37G3H35G41G32G7DZS14V65KFFFF8ZP14V66KFFF"
. "F8ZP14V67KFFFF8ZP14V68KFFFF8ZP14V69KFFFF8ZP14V6AKFFFF8ZP14V6BKFFFF8ZP14V6CKFFFF8ZP14V"
. "6DKFFFF8P"

Loop 20   ;  Decompressing Nulls : www.autohotkey.com/forum/viewtopic.php?p=198560#198560
 StringReplace,_DT,_DT,% Chr(70+21-A_Index),% SubStr("000000000000000000000",A_Index),All

Loop % _B$L := VarSetCapacity( _B$, ( _DTLEN := StrLen(_DT) // 2 ), 0 )
 NumPut( "0x" . SubStr(_DT, 2*A_Index-1,2),_B$,A_Index-1,"Char" )  ; Creating Structure
_pIWEB := &_B$, _pV := &_B$+16, _DlgT := &_B$+32   ; Relevant pointers to Structure

DllCall( "GetModuleHandle", Str,"atl.dll" ) ? 0 : DllCall( "LoadLibrary", Str,"atl.dll" )
DllCall( "atl\AtlAxWinInit" ),          _DlgP := RegisterCallback( A_ThisFunc,0,4,0xCBF )
}

VarSetCapacity( _W$,_B$L,0 ), DllCall( "RtlMoveMemory", UInt,&_W$, UInt,&_B$, UInt,_B$L )
_pIWEB := &_W$, _pV := &_W$+16, _DlgT := &_W$+32         ; Relevant pointers to Structure

Butt:="OK", BWid:=75, BHei:=23, BSpH:=5, BSpV:=8, BAli:=1, Slee:=-1, HtmC:=0, CliC:=0
HtmD:=0, DlgT:=0, DlgN:=0, DlgX:="", DlgY:="", HtmW:=240, HtmH:=140, Left:=0, TopM:=0
Loop, Parse, _Options, =%_ODL%, %A_Space%        ; Override Variables with user 'Options'
  A_Index & 1  ? (  __  := (SubStr(A_LoopField,1,1)="_") ? "_" : SubStr(A_LoopField,1,4))
               : ( %__% := A_LoopField )

Cap  := DllCall( "GetSystemMetrics", UInt,4  ) ; SM_CYCAPTION    = Window Caption
Frm  := DllCall( "GetSystemMetrics", UInt,7  ) ; SM_CXFIXEDFRAME = Window Frame

NumPut( HtmC<>0 ? 0x200 : 0x0, _W$, 32+68 ), DlgD := DlgD ? 0x8000000 : 0x0
FonS ? NumPut( FonS < 8 ? 8 : ( FonS > 14 ? 14 : FonS ), _W$, 64, "UShort" ) : 0

If (  ( DlgS := SubStr( DlgS,1,1 ) ) <> ""  )
 _ := ( DlgS = "F" ) ? NumPut( 0x800000C0 | DlgD, _W$, 44 ) | ( Cap := 0 )
   :  ( DlgS = "N" ) ? NumPut( 0x80000040 | DlgD, _W$, 44 ) | ( Frm := Cap := 0 )
   :  ( DlgS = "B" ) ? NumPut( 0x80800040 | DlgD, _W$, 44 ) | ( Cap := 0 ) | ( Frm := 1 )
   :                   NumPut( 0x80C800C0 | DlgD, _W$, 44 )

IfNotEqual,DlgB,, SetEnv,_Brush,% DllCall( "CreateSolidBrush", UInt,DlgB )

_hDLG  := DllCall( "CreateDialogIndirectParam", UInt,_hInst, UInt,_DlgT, UInt
,_Owner := ( _Owner <> "" ) ? _Owner : DllCall( "GetShellWindow" ), UInt,_DlgP, UInt,0 )

VarSetCapacity( _WU, StrLen(_URL) * ( A_IsUnicode ? 1 : 2 ) + 2, 0 )
A_IsUnicode ? _WU := _URL : DllCall( "MultiByteToWideChar", UInt,0, UInt,0, UInt,&_URL
                                    , Int,-1, UInt,&_WU, Int,StrLen(_URL)+1 )

_hHTM := DllCall( "GetDlgItem", UInt,_hDLG, UInt,100 )
DllCall( "atl\AtlAxGetControl", UInt,_hHTM, UIntP,_ppunk )
DllCall( NumGet( NumGet( _ppunk+0 )+4*0 ), UInt,_ppunk, UInt,_pIWEB, UIntP,_ppwb )
DllCall( NumGet( NumGet( _ppunk+0 )+4*2 ), UInt,_ppunk ),_pwb := NumGet( _ppwb+0 )
DllCall( NumGet(_pwb+4*11),UInt,_ppwb, UInt,&_WU, UInt,_pV,UInt,_pV,UInt,_pV,UInt,_pV )
DllCall( NumGet(_pwb+4*2), UInt,_ppwb )

DllCall( "SetWindowPos", UInt,_hHTM,Int,0,Int,Left,Int,TopM,Int,HtmW,Int,HtmH,UInt,0x14 )
IfNotEqual,HtmD,0, Control,Disable,,,ahk_id %_hHTM%

DlgW := Frm + Left + HtmW + Frm + Left,       ClAW := DlgW - Frm - Frm ; ClientArea Width
DlgH := Frm + Cap + TopM + HtmH + BSpV + BHei + BSpV + Frm
DlgX := ( DlgX <> "" ) ? DlgX : ( A_ScreenWidth - DlgW ) // 2
DlgY := ( DlgY <> "" ) ? DlgY : ( A_ScreenHeight - DlgH ) // 2

StringReplace, Butt,Butt, /,/, UseErrorLevel
bCount := ErrorLevel+1
BY := TopM + HtmH + BSpV
BX := ( Bali=1 ? ( ( ClAW - (BSpH*(bCount-1)) - (BWid*bCount) ) / 2 )
   :  ( Bali=0 ? ( ( BSpH * 2 ) + ( HtmD ? 0 : Left ) )
   :  ( ClAW - (BSpH*(bCount+1)) - (BWid*bCount) - ( HtmD ? 0 : Left ) ) ) )

Loop, Parse, Butt, /   ;  SetWindowPos flags = SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOZORDER
  DllCall( "SetWindowPos", UInt,BH:=DllCall( "GetDlgItem", UInt,_hDLG, UInt,100+A_Index )
                       , UInt,0, Int,BX, Int,BY, Int,BWid, Int,BHei, UInt,0x40|0x10|0x4 )
, DllCall( "SetWindowText", UInt,BH, Str,A_LoopField ),   BX := BX + BSpH + BWid
, _ := ( BNoT<>"" ) ? DllCall( "uxtheme\SetWindowTheme", UInt,BH, UInt,0, UIntP,0 ) : 0
, _ := ( BSFl<>"" ) ? DllCall( "SetWindowLong", UInt,BH, Int,-16, UInt,0x50018000 ) : 0

BDef := ( BDef < 1 || BDef > bCount ) ? 1 : BDef ; Force Default Button
DllCall( "SendMessage", UInt,_hDLG, UInt,0x401, UInt,100+BDef, UInt,0 )    ;  DM_SETDEFID

DllCall( "SetWindowText", UInt,_hDLG, Str,Titl ? Titl : A_ScriptName ) ; Set Dialog Title
DllCall( "SetWindowPos", UInt,_hDLG, Int,DlgT ? -1 : 1, Int,DlgX, Int,DlgY, Int,DlgW, Int
                       , DlgH, UInt,0x10 )         ; DlgTopmost ? HWND_TOPMOST : HWND_TOP

While ( nReady <> 4 && DlgW<>"" )  ;  wait until webpage-load adapted from Seans's IE.ahk
  Sleep % 1 + ( DllCall( NumGet(NumGet(1*_ppwb)+224 ), UInt,_ppwb, UIntP,nReady ) >> 32 )
Sleep, %Slee%

DllCall( "ShowWindow", UInt,_hDLG, Int,DlgN ? 8 : 5 ) ; DlgNA ? SW_SHOWNA : SW_SHOW
IfNotEqual,HtmF,0, ControlFocus,, ahk_ID %_hDLG%
WinWaitClose, ahk_id %_hDLG%,, %Time%
TimedOut := Errorlevel  ? DllCall( "EndDialog", UInt,_hDLG, UInt,0 ) : 0
IfNotEqual,AltR,, IfGreater,BDef,0, StringSplit,B,Butt,/
DllCall( "SetLastError", UInt,TimedOut ? 1 : 0 )
Return AltR ? B%BDef% : BDef
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \
>-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  O P T I O N S  -  -<
\- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /

Usage: HtmDlg( URL, hwndOwner, Options, OptionsDelimiter )

Parameters :

URL              - A valid URL supported by Internet Explorer including Res:// and File://

hWndOwner        - Handle to the parent window. If invalid handle or 0 ( zero ) is passed,
                  the dialog will have a taskbar button. Passing "" as a parameter will
                  set 'Progman' the owner, thereby supressing the 'Taskbar Button'.

Options          - A series of 'variable overrides' delimited with character specified in
                  'Optionsdelimiter'. Please refer 'VARIABLE OVERRIDES' below.

OptionsDelimiter - The delimiter used in seperating 'variable overrides'


;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  * * *   V A R I A B L E   O V E R R I D E S   * * *
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Important Note: leading 4 characters of a variable will be sufficient.
               for eg.: Instead of 'AltReturn=1' you may use 'AltR=1'


DlgXpos         = X coordinate in pixels, relative to screen
                 Dialog is horizontally centered by default

DlgYpos         = Y coordinate in pixels, relative to screen
                 Dialog is vertically centered by default

DlgTopmost      = 1 will set the Dialog 'Always-on-Top'
                 0 is default

DlgDisable      = 1 will disable the Dialog window
                 No default value

                 Caution:
                 Since there is no way to interact, you may opt to TimeOut the Dialog

DlgStyle        = Frame or NoFrame or Border. Leading character is sufficient, like: F-N-B
                 Default is Caption

                 Note on Styles used:

                 Frame   = WS_POPUP | DS_MODALFRAME
                 NoFrame = WS_POPUP | DS_SETFONT
                 Border  = WS_POPUP | DS_SETFONT | WS_BORDER
                 Caption = WS_POPUP | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU

                 WS_DISABLED is additionally set when DlgDisable=1

DlgNoActivate   = 1 will Show the Dialog without activating it
                 0 is default

DlgBgColor      = ColorRef.  eg: 0x0000FF is Red / Invalid ColorRef will result in Black.

DlgWait         = 1 will delay Dialog from being shown - until HTM is fully loaded

Sleep           = MilliSeconds ( Will be used just before Dialog is shown )
                 Default value is -1, 'No sleep'

Title           = Captionbar Text
                 Default is A_ScriptName

AltReturn       = 1 will return Button-text
                 0 is default and Button-instance will be returned

TimeOut         = Seconds
                 No default value

                 Note: A_LastError will be true when a TimeOut occurs

ClickClose      = 1
                 Default value is 0

                 Note:
                 Mouse L-Click on window's unoccupied clientarea' will close the dialog

                 Tip: Use following to simulate a unobtrusive message ( like TrayTip )
                 DlgTopmost=1, HtmD=1, DlgNA=1, DlgStyle=Border, BHei=0, BSpV=0, Clic=1

LeftMargin      = Spacing in Pixels ( on the left/right sides of WebControl )
                 Default value is 0

TopMargin       = Spacing in Pixels ( above the WebControl )
                 Default value is 0

FonName           ( Not implemented yet )
                 Default is 'MS Shell Dlg' and equivalent

FonSize         = Pointsize ( text size of Button-labels - restricted to 8,10,12,14 )
                 Default value is 8

HtmClientEdge   = 1 to set WS_EX_CLIENTEDGE
                 Default value is 0

HtmDisable      = 1 to disable
                 Default value is 0

HtmWidth        = Width of WebControl in Pixels
                 Default value is 240

HtmHeight       = Height of WebControl in pixels
                 Default value is 140

HtmFocus        = 1 will activate the dialog and WebControl will have input focus
                 Default value is 0

                 Note: DlgNoActivate option will lose effect.
                       For best result, use this option along with DlgWait=1

Buttons         = Button labels seperated with "/"  eg: Buttons=Yes/No/Cancel
                 Default Button is "OK"

BDefault        = Instance of Default Button. eg: To make 3rd Button default, use BDef=3
                 Default forced value is 1

BEscape         = Instance of Button to return when dialog is closed or {Esc} is pressed
                 Default is 0

BWidth          = Button Width in Pixels
                 Default Value is 75

BHeight         = Button Height in Pixels
                 Default value is 23

BSpHorizontal   = Pixels ( affects the spacing on the sides of a button )

BSpVertical     = Pixels ( affects the spacing above/below a button )

BAlign          = 0 or 1 or 2  ( for Left, Center, Right alignment of buttons )
                 Default is 1

BNoTheme        = 1 will remove theme from buttons ( XP & greater )
                 No default value

BSFlat          = 1 will flatten the button by removing the 3D edge - requires BNoTheme=1
                 No default value

;< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >

*/

 

Edited by majstang
Link to comment
  • 1 month later...
If the following processes are NOT active: xbmc.exe and/or DVBViewer.exe and/or iexplore.exe put the htpc in hibernation mode.
This request came from DVBFan77 and this is the script how to accomplish it. This script no longer uses time as main variable to cancel standby/hibernation after recordings. It focuses mainly on processes (for example if xbmc.exe, iexplore.exe is found on the serverPC only) and clientcount (if DVBViewer is active on the serverPC or any clientPC) and if any of these are found the hibernation will be canceled after the recording finishes.

The usual variables RS_status and RS_TimeToNextRecording are still in play. Meaning HTPC will not be hibernated if a recording goes on at the moment and if time to next recording is less than 30 minutes. The script works with both WinXP and WinVista/7.

 

 

How to set it up

 

1. Download and install "Installer for AutoHotkey Basic" http://www.autohotkey.com/download/

 

2. Copy the script down below and paste it into an empty notepad sheet.

 

3. Fill in your username/password in the links (there are three of them) in the script (the username and password you are using for the RS webinterface). Also important to NOT remove any colons or anything like that. Be careful here!

 

4. You must possibly also change the port number on the same lines after the IP number/adress (in my case 8075). Check what port RS uses in Configuration/Web/UPnP. If not done right the script will not connect to RS WEB API and get the values for the variables the script works with.

 

5. Now it is time to save the notepad sheet. Name the file to IntelligentHibernation.ahk and save it. If you have installed Autohotkey on your computer navigate to the file you just saved with the explorer. Rightclick on the IntelligentHibernation.ahk and in the menu that pops up you should now have a new option named "Compile Script". Leftclick on it and this compiles the .ahk file to an .exe file (IntelligentHibernation.exe). This must be done since RS does not accept .ahk format as scripts (only .exe and .bat).

 

6. Rightclick the RS systrayicon and choose Configuration. Go to Tasks and create a new task. Name it IntelligentHibernation and also type in the path for the IntelligentHibernation.exe file (e.g. C:\IntelligentHibernation.exe) in the Filenamebox or click the 3 dot button to the right and navigate to the IntelligentHibernation.exe.

Close the Task Editor and the Configuration window.

 

7. Open up RS webinterface. Click on Configuration-->Recorder. Under "Default recording actions" and "Default task after recording:" select the process task you created "IntelligentHibernation". "Post record action" should be set to "Nothing". Save your new settings. Remember if you have search presets created before this step, they all have the old default task after recording inherited, so the change you just did wont have any effect on recordingtimers created with these old search presets. Simply bring up your searchpresets in the SearchEPG and manually edit them one by one until all old presets have the "IntelligentHibernation" as the default task after recording. This box is named only "Task". Do not confuse this with "post record action", this box must use "Nothing".

 

So this should be it and everything should be working. You do not need to make any changes such as disable all power options in Windows 7 or so. As long as hibernation works as it should for you earlier, these 7 steps above is the only ones that has to be done. You can quick test the result by doubleclicking the IntelligentHibernation.exe from the explorer with for example DVBViewer running and see that HTPC will not hibernate as long as that application is running (same with XBMC and IE8). If all of these apps are closed the HTPC will go into hibernation (provided no recording is going on and there is more than 30 minutes to next recording).

Enjoy!

 

 

#NoTrayIcon
FormatTime, TimeVar,, HH:mm:ss ;Current local time.
FormatTime, DateVar,, WDay ; 1=Sunday, 2=Monday etc.
Process, Exist, xbmc.exe
XBMC_Status:=ErrorLevel
Process, Exist, iexplore.exe
iexplore_Status:=ErrorLevel


OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/timerlist.html[?utf8=]") ;Fill in your own username and password
StringReplace, OutputVar, OutputVar, <Timer, % Chr(4) . "<Timer", All
StringReplace, OutputVar, OutputVar, </Timer>, % "</Timer>" . Chr(4), All
MyList := A_Now A_Tab "<now>"
While pos := RegexMatch( OutputVar,"<Timer[^>]*Date=""(?<_D>\d+)\D(?<_M>\d+)\D(?<_Y>\d+)""[^>]*Start="""
. "(?<_H>\d+)\D(?<_N>\d+)\D(?<_S>\d+)""[^\x04]*<ID>(?<_ID>\d*)", Tmr, A_Index = 1 ? 1 : pos + StrLen(Tmr) )
  MyList .= "`n" . Tmr_Y . Tmr_M . Tmr_D . Tmr_H . Tmr_N . Tmr_S . A_Tab . Tmr_ID
Sort, MyList, N

set=0
Loop, Parse,MyList, `n
{
if set=1
{
datetime:=A_LoopField
break
}
IfInString, a_loopfield,<now>
set=1
}
StringSplit, datetime,datetime,%A_Tab%
EnvSub, datetime1,A_Now,min
RS_TimeToNextRecordingVar:=datetime1 ;time in minutes to next recording


OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html") ;Fill in your own username and password
FoundPos := RegExMatch(OutputVar, "(?<=recordcount>)(.)", SubPat)
RS_StatusVar:=SubPat ;status of the recording service

OutputVar := UrlDownloadToVar("http://user:password@127.0.0.1:8075/api/status.html") ;Fill in your own username and password and portnumber.
FoundPos := RegExMatch(OutputVar, "(?<=clientcount>)(.)", SubPat2)
RS_ClientCountStatus:=SubPat2 ;Number of clients connected to the recording service

UrlDownloadToVar(URL, Proxy="", ProxyBypass="")
{
AutoTrim, Off
hModule := DllCall("LoadLibrary", "str", "wininet.dll")

If (Proxy != "")
AccessType=3
Else
AccessType=1
;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

io_hInternet := DllCall("wininet\InternetOpenA"
, "str", "" ;lpszAgent
, "uint", AccessType
, "str", Proxy
, "str", ProxyBypass
, "uint", 0) ;dwFlags

iou := DllCall("wininet\InternetOpenUrlA"
, "uint", io_hInternet
, "str", url
, "str", "" ;lpszHeaders
, "uint", 0 ;dwHeadersLength
, "uint", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item
, "uint", 0) ;dwContext

If (ErrorLevel != 0 or iou = 0) {
DllCall("FreeLibrary", "uint", hModule)
return 0
}

VarSetCapacity(buffer, 512, 0)
VarSetCapacity(NumberOfBytesRead, 4, 0)
Loop
{
 irf := DllCall("wininet\InternetReadFile", "uint", iou, "uint", &buffer, "uint", 512, "uint", &NumberOfBytesRead)
 NOBR = 0
 Loop 4  ; Build the integer by adding up its bytes. - ExtractInteger
   NOBR += *(&NumberOfBytesRead + A_Index-1) << 8*(A_Index-1)
 IfEqual, NOBR, 0, break
 ;BytesReadTotal += NOBR
 DllCall("lstrcpy", "str", buffer, "uint", &buffer)
 res = %res%%buffer%
}
StringTrimRight, res, res, 2

DllCall("wininet\InternetCloseHandle",  "uint", iou)
DllCall("wininet\InternetCloseHandle",  "uint", io_hInternet)
DllCall("FreeLibrary", "uint", hModule)
AutoTrim, on
return, res
}

;If DateVar between 2 and 6 ;Specifies hibernation rules between Monday=2 and Friday=6. Always use LowerBound and UpperBound format, like my example.
If XBMC_Status = 0
{
;If TimeVar between 00:00:00 and 15:00:00 ;Specifies which time to allow hibernation. Set to the value you prefer! Always use LowerBound and UpperBound format, like my example.
  If iexplore_Status = 0
   If RS_StatusVar <= 1 ;If Recording Service status is idle this condition will be met. DO NOT alter this value!
    If RS_ClientCountStatus = 0 ;Hibernation will be allowed only if no clients are connected to RS. 
     If RS_TimeToNextRecordingVar >= 30 ;If minutes to next recording is more than 30, HTPC will hibernate. Set to the value you prefer!
        /*
        If you prefer some other default System Closedown method than Hibernate, activate the one you prefer by removing semicolon for choosen PowerTask below and remember to
        inactivate the DllCall for Hibernation by inserting a semicolon in front of that codeline. 
        WindowsXP users only!!! If using the "Intercept Hibernation/shutdown script" you will have the opportunity to cancel System Closedown through a messagbox and
        simultainously be presented with several options (Hibernate, Standby, Shutdown, Restart or Cancel ) what to do next.  
        */
        DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0) ;Hibernates HTPC if all above conditions are met. 
        ;DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0) ;Standby mode for your HTPC if all above conditions are met. 
        ;Shutdown, 1 ;This option will shutdown your HTPC.

        /*
        Codelines below can be used to activate Rec.Service native PowerTASKs. WinXP users will get the RS messagebox which allows you to abort shutdown within 10 seconds.   
        If using this option the "Intercept Hibernation/shutdown script" will not be needed (WinXP only). Activate by removing semicolon for Task of choice below and remember to 
        inactivate the DllCall above by inserting a semicolon in front of that codeline. Don't forget to fill in your username and password in the URL otherwise it won't work.
        */
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Hibernate&aktion=tasks") ;If choosen activates Rec.Service own Hibernation task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Standby&aktion=tasks") ;If choosen activates Rec.Service own Standby task.
        ;UrlDownloadToVar("http://user:password@127.0.0.1:8075/tasks.html?task=Shutdown&aktion=tasks") ;If choosen activates Rec.Service own Shutdown task.
     Else
        Return ;One or more conditions above is NOT met...hibernation will be cancelled.
}

 

Edited by majstang
Link to comment
  • 3 weeks later...

Hey majstang. I have adapted your intelligent hibernation script to my specific needs (using standby, chrome), and it works great.

 

But the Windows 7 intercept script doesnt seem to work. I tested by compiling it and making sure it was running in memory, then executing the standby script - the machine immediately entered standby.

 

Any ideas (Im on 7 Ultimate x64)?

Link to comment

Hey majstang. I have adapted your intelligent hibernation script to my specific needs (using standby, chrome), and it works great.

 

But the Windows 7 intercept script doesnt seem to work. I tested by compiling it and making sure it was running in memory, then executing the standby script - the machine immediately entered standby.

 

Any ideas (Im on 7 Ultimate x64)?

 

Not to worry about this - I have got the native RS standby task working from the intelligent standby script.

 

Thanks!

 

 

 

PS: When using the direct standby call within the Intelligent Standby script (instead of the RS standby task) my machine would not wake from sleep via USB - Id have to hit the power button to wake it.

The RS standby method doesnt have this problem.

Edited by subvertbeats
Link to comment

Hey majstang. I have adapted your intelligent hibernation script to my specific needs (using standby, chrome), and it works great.

 

But the Windows 7 intercept script doesnt seem to work. I tested by compiling it and making sure it was running in memory, then executing the standby script - the machine immediately entered standby.

 

Any ideas (Im on 7 Ultimate x64)?

Yes, the cause for that is you seem to be using the intelligent hibernation script from post 27 together with the interceptionscript for Windows 7 from post 26. You see the interceptionscript are not abled to intercept anything else than shutdown and the 0x5555 message. Standby and hibernation calls can not be blocked/intercepted. If configuring the intelligent hibernationscript making a standby call as RS after recording task, the interceptionscript will unconditional miss it. Therefor the intelligent hibernationscript for Windows 7 (post 26) must be configured to make the shutdown call or send the 0x5555 message (which also will be intercepted and fire up the msgbox). Unfortunately RS uses forcelful shutdown on Win7 which can not be intercepted/blocked. That is why I had to add the named pipe solution which makes the shutdown call non-forceful and therefor interceptable for the interceptionscript (it also allows sending messages between the service session where RS runs to the desktop users session where the interceptionscript runs). That is why scripts in post 26 should be used as a unit. If you wanna have processes (Chrome) as main variable to cancel standby/hibernation in the Adapted Intelligent Hibernationscript for Windows 7 (it uses time as main variable today) I can easily adapt it for you. Let me know if so. If you wanna use standby as the default closedown method the interceptionscript will also need some tweaks.

 

Thus for your personal preferences I recommend you to mapp your remotecontrol to NOT use shutdown or standby nor hibernation. Mapp it to the intelligent hibernationscript instead. In that way the shutdown command will never be sent if not all RS conditions are met, so it is practically impossible to manage to standby the system while for example a recording is going on. Its neat to have the intelligent hibernation script to gather some intelligence about the current conditions of RS (even executed from outside of the Windows Services user session) before making any attempts to shutdowm-->standby the system.

:bye:

Edited by majstang
Link to comment

Hey majstang

 

Thanks for the reply - think we crossed posts.

Ive got it all working well calling the RS standby mechanism from the intelligent standby script.

 

I think that Ive also discovered the real cause of my failed recordings issues - sometimes my TBS 6981 cards (x2) resume from S3 just fine, sometimes they dont.

Very annoying. Have tried numerous driver versions, but no complete fix.

TBS forums suggest that any resume problems are fixed in latest driver versions, and I think my problem may be related to the interaction between my MoBo (Gigabyte P55-US3L, Hardware rev 1.0 (latest h/w rev is 2.3)) and the TBS cards. Its a very early version of that Mobo and they made several hardware revisions afterwards.

I suspect that swapping the MoBo out may be the real solution but its expensive (in time and money) to do so :/

 

Hibernate works as expected (would seem obvious) and TBS cards initialize fine after resume.

But of course you have the nearly full Windows start time to wait. Not the best for family acceptance.

How do you find using hibernate in day to day scenario?

Link to comment

Thanks for the reply - think we crossed posts.

Ive got it all working well calling the RS standby mechanism from the intelligent standby script.

Well, I posted some background info anyway, just in case you wanted to try the intercept hibernationscript out.

The remote control tip is definitely a hit I can assure you :)

 

Hibernate works as expected (would seem obvious) and TBS cards initialize fine after resume.

But of course you have the nearly full Windows start time to wait. Not the best for family acceptance.

How do you find using hibernate in day to day scenario?

No prob at all. HomeSeer takes care of resuming the HTPC, turns on the TV and the surroundsystem certain times every day when me and my girlfriend gets home from work. Intelligent hibernationscript denies all hibernation until midnight. It is actually rare we have to turn on turn HTPC system (resume from S4) by remote control :) Considering getting a z-wave motionsensor controlling this process instead..I know what a tech-geek ;) But since I do control all outlets, blinds, door lock, lamps in the appartment with z-wave, so why not :biggrin: The electric bill is in fact considerably lower :)

Link to comment

Sounds great!

 

Ive updated my EventGhost config to have the remote power button first close DVBViewer (else the standby script will never standby), and on second press, run the intelligent standby script.

ill switch to hibernate if I cant figure out this TBS card issue. Great suggestion thanks.

 

Never heard of HomeSeer - going to look that up now! Another gadget geek here, but right now Ive focused on getting the whole thing working, Projector, AV Receiver and surround setup, HTPC (now with DVBViewer for TV, but also still running sabnzbd with sickbeard - awesome couple of apps - check them out if you havent already).

 

Only now working on getting it running all smooth with the additional considerations like powersave, automation etc.

 

Thanks for all your help so far, its much appreciated.

Link to comment

You are welcome...it is great fun helping out a fellow tech-fan :biggrin:

 

ADD: Yes, that was a neat way to solve the fact a running DVBViewer client cancels the standby. I my case I use time as main variable to cancel hibernation and therefor have no need of using the clientcount function. During time of day/night when my script allows hibernation I use the intercept shutdown script in order to give me an opportunity to cancel the hibernation if I choose to. I prefer having DVBViewer running when HTPC resumes from hibernation. Pretty much like an ordinary TV.

:bye:

Edited by majstang
Link to comment
  • 6 months later...

Intelligent hibernation script update

 

Additions and changes

- Added unicode support. RS has now unicode support and it was time to add it to this script as well.

Mainly to integrate it with other scripts i've made recently.

Download and install Autohotkey (AHK_L) unicode for the script to work:

http://www.autohotkey.net/~Lexikos/AutoHotkey_L/AutoHotkey_L_Install.exe

That implies the old intelligent hibernationscript can't be used with AHK_L Unicode.

 

- Cleaned up and structured the script better. Labeled the code to easier follow what it does and finding

code sections.

 

- Added a PATH, URL AND CONDITIONS CONFIGURATION SECTION. All configuration of the script takes place here.

Fill in all your details. You will activate and inactivate new functionalities from here. Your URL details

to RS API shall only be entered in the PATH, URL AND CONDITIONS CONFIGURATION SECTION, no other place in

the script. Conditioning of when hibernation shall be allowed and not will be done in this section only.

 

- Added automatic recording database backup functionality. Default is activated. Keeps a complete recordings

database even if you delete the actual recording. More info on what it does here:

http://www.DVBViewer.tv/forum/topic/45486-automatically-delete-recordings-older-than-x-days/

To inactivate this functionality add a semicolon ; in front of "RS_recording_folder", "EPG_files_location",

"PropCopy_location" and "Recording_database_backup_location_2" in the PATH, URL AND CONDITIONS CONFIGURATION

SECTION.

 

- Added Grigas PropCopy. Default is activated. Property-/metadata will be copied from actual recording to the

"dummy".ts backup file. Tip! Use the recordings properties for Windows Explorer to better see the result

(choose this option on one of the first splash screens in RS installer).

 

- Added CommercialRemoval functionality. Default is inactivated. It can be activated if removing the semicolon

in front Edited_Video_Folder in PATH, URL AND CONDITIONS CONFIGURATION SECTION. OBSERVE! This functionality requires

additional software/payware. For information and setup of the Automatic Commercial Removal script visit:

http://www.DVBViewer.tv/forum/topic/44842-automatic-commercial-removal-script/

 

- Added automatic Delete old recordings functionality. Default is inactivated. For configuration go down to the

DELETE OLD RECORDINGS CONFIGURATION. More info on how it works can be found in the same link as for the

automatic recording database backup functionality.

 

- Clientcount as hibernation blocker. Default inactivated. If wanna use "clientcount" as main variable for canceling

hibernation it has to be activated into the PATH, URL AND CONDITIONS CONFIGURATION SECTION.

 

Remaining issues

- It is currently not possible to hibernate HTPC with the intelligent hibernation script, if two recordings

with same starttime finishes at the exact same time. This is impossible cuz the two after recording tasks,

which both are process timers, gets executed simultaneously when the recordings finishes, increases the

recordcount value by 2 and the hibernation fails, even when hibernation is allowed.

When RS API was made all sorts of timers, unrelated to the the actual recording process, is allowed to

interfer with the recordcount value in the Status API. If instead the recordcount variable would be reserved

for recording timers only and having an another variable collecting the Process Task Timers, the Internal Task

Timers and the Autosearch Timer values under it. In this way these timers would NOT alter the "recordcount"

value one bit.

All support would be much appreciated to get this well needed change higher up on the developers priority list.

If feeling like giving me support here is the thread to do it in:

http://www.DVBViewer.tv/forum/topic/41329-after-recording-task-recservice-status-issue/page__view__findpost__p__329900

 

- If using the Commercial removal option, sometimes this script/after-recording-task can get stuck in rec.mode in RS

Timers tab for unknown resasons.

 

- If using the Commercial removal option, sometimes when this script/after-recording-task gets launched multiple times

(for instance when many recordings finishes simultaneously) the intercept reciever script can display a messagebox

informing you the named pipe has not been created yet. I therefor modified the Reciever script a tiny bit.

 

Other Info

- The Receiverscript and InterceptShutdown script can be used as before. Scripts and instructions on how to set them

up can be found earlier in this thread here:

http://www.DVBViewer.tv/forum/topic/41387-another-intelligent-hibernationscript/page__view__findpost__p__318292

 

 

Unicode Intelligent Hibernation script

 

#NoTrayIcon
;-----------------------------------------------------------------------------------------------------------------
;Activate codelines by removing the semicolon ";" infront of a line if you wanna use this feature
;-----------------------------------------------------------------------------------------------------------------
;PATH, URL AND CONDITIONS CONFIGURATION
;-----------------------------------------------------------------------------------------------------------------
Recording_Service_API_URL := "http://username:password@127.0.0.1:8089" ;fill in user details, IP and port number to Recording Service API here.  
RS_recording_folder := "D:\TV\Recording Service" ;Activate if wanting recordings database backup. Fill in path to your RS recording folder. 
EPG_files_location := "D:\TV\Recording Service\EPG Info-Log Files" ;Activate if wanting recordings database backup. OBSERVE! Must be a subfolder to RS recording folder
PropCopy_location := "D:\AVI_VOB_BLU-RAY_AC3-tools\TV-tools\DVBViewer\PropCopy_1_2_2\PropCopy.exe" ;Activate if wanting recordings database backup. Fill in path to PropCopy
Recording_database_backup_location_1 := "D:\AVI_VOB_BLU-RAY_AC3-tools\TV-tools\EPG Info-Log Files Backup" ;Activate if wanting recordings database backup on other location. 
Recording_database_backup_location_2 := "E:\EPG Info-Log Files Backup"
;Edited_Video_Folder := "D:\Edited Recordings" ;Activate if wanting comskip/videoredo commercial removal. Fill in path to CommercialRemover.exe. More info on setup read next section. 
Allow_hibernate_starttime_weekdays := "01:00:00" ;Configurate starttime from when hibernation should be allowed for weekdays. Change time value to your own preference.
Allow_hibernate_stoptime_weekdays := "15:00:00"  ;Configurate stoptime up to when hibernation should be allowed for weekdays. Change time value to your own preference.
Allow_hibernate_starttime_weekend := "02:00:00"  ;Configurate starttime from when hibernation should be allowed for weekends. Change time value to your own preference.
Allow_hibernate_stoptime_weekend := "09:00:00"   ;Configurate stoptime up to when hibernation should be allowed for weekends. Change time value to your own preference.
;Use_clientcount_status_as_Hibernationblock := "ErrorLevel" ;Activate if using Clientcount as a variable to cancel hibernation instead of the default TimeVar
/*
This last configuration line above disables time as main hibernation blocker and enables hibernation block as long as the local DVBViewer 
client on RS server is running. Default inactivated. Don't change value...to activate remove semicolon in front of the 
"Use_clientcount_status_as_Hibernationblock" line. To make it work for local client on server enable: 
RS Configure/DVBServer tab/"Block Standby/Hibernate if a DVBViewer client is connected on the same computer" option.
If not this option is checked, the local client will not be counted when doing the RS API check and this feature will fail.   
*/
;-----------------------------------------------------------------------------------------------------------------
;COMSKIP/VIDEOREDO COMMERCIAL REMOVAL ;This feature Requires additional software. 
;For setup go to: http://www.DVBViewer.tv/forum/topic/44842-automatic-commercial-removal-script/page__view__findpost__p__330318
;-----------------------------------------------------------------------------------------------------------------
;DELETE OLD RECORDINGS CONFIGURATION ;Activate to use. Fill in number of days to keep files and path to them
;-----------------------------------------------------------------------------------------------------------------
;OldConfigCleanup("2","D:\TV\Inspelat","*.ts") ;Recordings older than 2 days will be deleted from Inspelat folder.
;OldConfigCleanup("2","D:\TV\Seen Recordings","*.ts") ;Recordings older than 2 days will be deleted from Seen Recordings folder.
;OldConfigCleanup("1","D:\TV\Timeshift","*.ts") ;Timeshifted Recordings older than 1 day will be deleted.

;-----------------------------------------------------------------------------------------------------------------
;CODE BODY
;---CURRENT TIME AND DAY RETRIEVAL--------------------------------------------------------------------------------
FormatTime, TimeVar,, HH:mm:ss ;Current local time.
FormatTime, DateVar,, WDay ; 1=Sunday, 2=Monday etc.

;---RECORDING SERVICE STATUS RETRIEVAL----------------------------------------------------------------------------
UrlDownloadToVar(Recording_Service_API_URL . "/api/status.html", OutputVar) 
FoundPos := RegExMatch(OutputVar, "(?<=recordcount>)(.)", SubPat)
RS_StatusVar:=SubPat ;status of the recording service

;---TIME TO NEXT RECORDING RETRIEVAL------------------------------------------------------------------------------
UrlDownloadToVar(Recording_Service_API_URL . "/api/timerlist.html[?utf8=]", OutputVar2)
x1 := loadXML(OutputVar2)
MyList := A_Now A_Tab "<now>"
for timer in x1.selectNodes("/Timers/Timer") ;Loop
{
  timer_status := timer.selectSingleNode("@Enabled").text ;Retrieves if timer is enabled or not. Activated=-1 Deactivated=0
  date := timer.selectSingleNode("@Date").text ;Date of timer 
  start_time := timer.selectSingleNode("@Start").text ;Start time of timer
  date_starttime_orig_format = %date%`n%start_time% ;Original date and start time format
  date_starttime := ReFormatTime( date_starttime_orig_format, "DD MM YYYY HH MI SS", ".`n:" ) ;ReFormat date and start time of timer
  MyList .= "`n" . date_starttime . "|" . timer_status
}
Sort, MyList, N
NewString := RegexReplace( MyList, "\v*\d{14}\|0" )
set=0
Loop, Parse, NewString, `n
{
  If set=1
  {
    datetime := A_LoopField
    break
  }
  IfInString, A_Loopfield, <now>
    set=1
}
StringSplit, datetime, datetime, %A_Tab%
EnvSub, datetime1, A_Now, min
If datetime1 = 0
  RS_TimeToNextRecordingVar := 31
Else 
  RS_TimeToNextRecordingVar := datetime1 ;time in minutes to next recording

;---RECORDING SERVICE CLIENTCOUNT STATUS RETRIEVAL-----------------------------------------------------------------
UrlDownloadToVar(Recording_Service_API_URL . "/api/status.html", OutputVar)
FoundPos := RegExMatch(OutputVar, "(?<=clientcount>)(.)", SubPat2)
RS_ClientCountStatus:=SubPat2 ;Number of clients connected to the recording service

;---CONDITIONING OF CLIENTCOUNT VARIABLE---------------------------------------------------------------------------
If Use_clientcount_status_as_Hibernationblock =
  Use_clientcount_status_as_Hibernationblock := ErrorLevel
Else 
  Use_clientcount_status_as_Hibernationblock := RS_ClientCountStatus

;---CONDITIONING OF EDITED_VIDEO_FOLDER VARIABLE-------------------------------------------------------------------
If Edited_Video_Folder
  Edited_Video_Folder := Edited_Video_Folder
Else
  Edited_Video_Folder := %ErrorLevel%

;---DEBUG IF THE VARIABLES GETS VALUES-----------------------------------------------------------------------------
;IniWrite, %DateVar%, C:\ScriptsForWindows7\DVBViewer RecService Status.ini, Day_of_Week, Key
;IniWrite, %TimeVar%, C:\ScriptsForWindows7\DVBViewer RecService Status.ini, CurrentTime, Key
;IniWrite, %RS_StatusVar%, C:\ScriptsForWindows7\DVBViewer RecService Status.ini, RS_Status, Key
;IniWrite, %RS_TimeToNextRecordingVar%, C:\ScriptsForWindows7\DVBViewer RecService Status.ini, RS_TimeToNextRecording, Key
;IniWrite, %RS_ClientCountStatus%, C:\ScriptsForWindows7\DVBViewer RecService Status.ini, RS_ClientCountStatus, Key

;---TEST VARIABLES-------------------------------------------------------------------------------------------------
;DateVar = 7
;TimeVar = 16:00:00
;RS_StatusVar = 2
;RS_TimeToNextRecordingVar = 30
;Use_clientcount_status_as_Hibernationblock = 1

;---RECORDINGS DATABASE BACKUP AND METADATA COPY-------------------------------------------------------------------
right_Now := a_now
timelimit := right_Now
EnvAdd, timelimit, -60, seconds
FileList =
b_index=0
Loop, %RS_recording_folder%\*.log 
{ 
    if A_LoopFileTimeModified between %timelimit% and %right_Now% 
    {
       b_index++
	file%b_index% := A_LoopFileFullPath 
	;FileList = %FileList%%A_LoopFileTimeModified%`t%b_index%`t%A_LoopFileName%`n ;Enable this line to debug with msgbox Please hit
    }
} 
;msgbox Please hit ^c (while this is displayed) to copy to clipboard `n`n%FileList%
Loop %b_index% 
{ 
   SplitPath, file%a_index%, OutFileName, OutDir,, OutNameNoExt
FileCopy, %OutDir%\%OutFileName%, %EPG_files_location%\ ;RS log file will be copied to backupfolder 
FileMove, %OutDir%\%OutNameNoExt%.txt, %EPG_files_location%\ ;EPG information file will be moved to a subfolder
   Filemove, %OutDir%\%OutFileName%, %EPG_files_location%\%OutNameNoExt%.ts ;RS Log file will be moved and renamed to .ts extension
   RunWait, %PropCopy_location% "%RS_recording_folder%\%OutNameNoExt%.ts" "%EPG_files_location%\%OutNameNoExt%.ts" ;Metadata/Fileinfo copy
   FileCopy, %EPG_files_location%\*.*, %Recording_database_backup_location_1%\, 0 ;Backup of database
FileCopy, %EPG_files_location%\*.*, %Recording_database_backup_location_2%\, 0 ;Backup of database
}
UrlDownloadToVar(Recording_Service_API_URL . "/tasks.html?task=RefreshDB&aktion=tasks", OutputVar) ;Refresh Recording Service Database

;---CONDITIONING OF VARIABLES--------------------------------------------------------------------------------------
If DateVar between 2 and 6 ;Specifies hibernation rules between Monday=2 and Friday=6. Always use LowerBound and UpperBound format, like my example.
{
  If TimeVar not between %Allow_hibernate_starttime_weekdays% and %Allow_hibernate_stoptime_weekdays% ;Between 01:00-15:00 hibernation will be allowed. 
      Gosub, Label1 ; One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.
  Else
   {
    If RS_StatusVar <= 1 ;If Recording Service status is idle hibernation will be allowed. DO NOT alter this value!
     If Use_clientcount_status_as_Hibernationblock = 0 ;Hibernation will be allowed only if no clients are connected to RS.
       If RS_TimeToNextRecordingVar >= 30 ;If more than 30 minutes to next recording, HTPC will hibernate. Set to the value you prefer! 
        If Edited_Video_Folder = %ErrorLevel% ;Edited video folder is inactivated
  {
   Sleep, 4000 ;Just wait a little before creating pipe
          #NoEnv
          ptr := A_PtrSize ? "Ptr" : "UInt"
          char_size := A_IsUnicode ? 2 : 1
          Script=
          (
          SetTitleMatchMode, 2
          DetectHiddenWindows, On
          SendMessage, 0x5555, 0, 0,,InterceptShutdown.exe ; InterceptShutdown.exe is in my case the interceptionscript
          DetectHiddenWindows, Off
          )

          ; To prevent "collision", pipe_name could be something mostly "unique", like:
          ;   pipe_name := A_TickCount
          pipe_name := "InterceptShutdown"

          ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes
          ; the pipe to close, so we must create a second pipe for the actual file contents.
          ; Open them both before starting AutoHotkey, or the second attempt to open the
          ; "file" will be very likely to fail. The first created instance of the pipe
          ; seems to reliably be "opened" first. Otherwise, WriteFile would fail.
          pipe_ga := CreateNamedPipe0(pipe_name, 2)
          pipe    := CreateNamedPipe0(pipe_name, 2)
          if (pipe=-1 or pipe_ga=-1)
           {
             MsgBox CreateNamedPipe failed.
             ExitApp
           }

          ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes().
          DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0)
          ; This pipe is not needed, so close it now. (The pipe instance will not be fully
          ; destroyed until AutoHotkey also closes its handle.)
          DllCall("CloseHandle", ptr, pipe_ga)
          ; Wait for AutoHotkey to connect to open the "file".
          DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0)

          ; Standard AHK needs a UTF-8 BOM to work via pipe.  If we're running on
          ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead:
          Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script

          char_size := (A_IsUnicode ? 2:1)
          if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0)
          MsgBox WriteFile failed: `%ErrorLevel`%/`%A_LastError`%

          DllCall("CloseHandle", ptr, pipe)


          CreateNamedPipe0(Name, OpenMode=3, PipeMode=0, MaxInstances=255)
           {
             global ptr
             return DllCall("CreateNamedPipe","str","\\.\pipe\" Name,"uint",OpenMode
             ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr)
           }
          ExitApp
	  }
        Else if Edited_Video_Folder
         {	
           Sleep, 4000 ;Just wait a little before creating pipe
           #NoEnv
           ptr := A_PtrSize ? "Ptr" : "UInt"
           char_size := A_IsUnicode ? 2 : 1

           Script=
           (
           RunWait, CommercialRemover.exe, %Edited_Video_Folder%
           SetTitleMatchMode, 2
           DetectHiddenWindows, On
           SendMessage, 0x5555, 0, 0,,InterceptShutdown.exe ; InterceptShutdown.exe is in my case the interceptionscript
           DetectHiddenWindows, Off
           )
           ; To prevent "collision", pipe_name could be something mostly "unique", like:
           ;   pipe_name := A_TickCount
           pipe_name := "InterceptShutdown"

           ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes
           ; the pipe to close, so we must create a second pipe for the actual file contents.
           ; Open them both before starting AutoHotkey, or the second attempt to open the
           ; "file" will be very likely to fail. The first created instance of the pipe
           ; seems to reliably be "opened" first. Otherwise, WriteFile would fail.
           pipe_ga := CreateNamedPipe1(pipe_name, 2)
           pipe    := CreateNamedPipe1(pipe_name, 2)
           if (pipe=-1 or pipe_ga=-1)
            {
              MsgBox CreateNamedPipe failed.
              ExitApp
            }

           ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes().
           DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0)
           ; This pipe is not needed, so close it now. (The pipe instance will not be fully
           ; destroyed until AutoHotkey also closes its handle.)
           DllCall("CloseHandle", ptr, pipe_ga)
           ; Wait for AutoHotkey to connect to open the "file".
           DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0)

           ; Standard AHK needs a UTF-8 BOM to work via pipe.  If we're running on
           ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead:
           Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script

           char_size := (A_IsUnicode ? 2:1)
           if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0)
           MsgBox WriteFile failed: `%ErrorLevel`%/`%A_LastError`%

           DllCall("CloseHandle", ptr, pipe)

           CreateNamedPipe1(Name, OpenMode=3, PipeMode=0, MaxInstances=255)
            {
              global ptr
              return DllCall("CreateNamedPipe","str","\\.\pipe\" Name,"uint",OpenMode
              ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr)
            }
           ExitApp
         }
        Else if RS_TimeToNextRecordingVar <= 29
	      GoSub, Label1 ;One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.
        Else if Use_clientcount_status_as_Hibernationblock >= 1
	      GoSub, Label1 ;One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.
        Else if RS_StatusVar >= 2
	      GoSub, Label1 ;One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.		  
}	  
}		  

;---CONDITIONING OF VARIABLES WEEKENDS-----------------------------------------------------------------------------
If DateVar not between 2 and 6 ;Specifies hibernation rules between Saturday=7 and Sunday=1. Always use LowerBound and UpperBound format, like my example.
{
  If TimeVar not between %Allow_hibernate_starttime_weekend% and %Allow_hibernate_stoptime_weekend% ;Between 02:00-09:00 hibernation will be allowed. 
      Gosub, Label1 ; One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.
  Else
   {
    If RS_StatusVar <= 1 ;If Recording Service status is idle hibernation will be allowed. DO NOT alter this value!
     If Use_clientcount_status_as_Hibernationblock = 0 ;Hibernation will be allowed only if no clients are connected to RS.
       If RS_TimeToNextRecordingVar >= 30 ;If more than 30 minutes to next recording, HTPC will hibernate. Set to the value you prefer! 
        If Edited_Video_Folder = %ErrorLevel% ;Edited video folder is inactivated
         {
   Sleep, 4000 ;Just wait a little before creating pipe
          #NoEnv
          ptr := A_PtrSize ? "Ptr" : "UInt"
          char_size := A_IsUnicode ? 2 : 1
          Script=
          (
	   SetTitleMatchMode, 2
          DetectHiddenWindows, On
          SendMessage, 0x5555, 0, 0,,InterceptShutdown.exe ; InterceptShutdown.exe is in my case the interceptionscript
          DetectHiddenWindows, Off
          )

          ; To prevent "collision", pipe_name could be something mostly "unique", like:
          ;   pipe_name := A_TickCount
          pipe_name := "InterceptShutdown"

          ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes
          ; the pipe to close, so we must create a second pipe for the actual file contents.
          ; Open them both before starting AutoHotkey, or the second attempt to open the
          ; "file" will be very likely to fail. The first created instance of the pipe
          ; seems to reliably be "opened" first. Otherwise, WriteFile would fail.
          pipe_ga := CreateNamedPipe2(pipe_name, 2)
          pipe    := CreateNamedPipe2(pipe_name, 2)
          if (pipe=-1 or pipe_ga=-1)
           {
             MsgBox CreateNamedPipe failed.
             ExitApp
           }

          ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes().
          DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0)
          ; This pipe is not needed, so close it now. (The pipe instance will not be fully
          ; destroyed until AutoHotkey also closes its handle.)
          DllCall("CloseHandle", ptr, pipe_ga)
          ; Wait for AutoHotkey to connect to open the "file".
          DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0)

          ; Standard AHK needs a UTF-8 BOM to work via pipe.  If we're running on
          ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead:
          Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script

          char_size := (A_IsUnicode ? 2:1)
          if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0)
          MsgBox WriteFile failed: `%ErrorLevel`%/`%A_LastError`%

          DllCall("CloseHandle", ptr, pipe)


          CreateNamedPipe2(Name, OpenMode=3, PipeMode=0, MaxInstances=255)
           {
             global ptr
             return DllCall("CreateNamedPipe","str","\\.\pipe\" Name,"uint",OpenMode
             ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr)
           }
          ExitApp
	  }
        Else if Edited_Video_Folder
         {	
           Sleep, 4000 ;Just wait a little before creating pipe
           #NoEnv
           ptr := A_PtrSize ? "Ptr" : "UInt"
           char_size := A_IsUnicode ? 2 : 1

           Script=
           (
           RunWait, CommercialRemover.exe, %Edited_Video_Folder%
           SetTitleMatchMode, 2
           DetectHiddenWindows, On
           SendMessage, 0x5555, 0, 0,,InterceptShutdown.exe ; InterceptShutdown.exe is in my case the interceptionscript
           DetectHiddenWindows, Off
           )
           ; To prevent "collision", pipe_name could be something mostly "unique", like:
           ;   pipe_name := A_TickCount
           pipe_name := "InterceptShutdown"

           ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes
           ; the pipe to close, so we must create a second pipe for the actual file contents.
           ; Open them both before starting AutoHotkey, or the second attempt to open the
           ; "file" will be very likely to fail. The first created instance of the pipe
           ; seems to reliably be "opened" first. Otherwise, WriteFile would fail.
           pipe_ga := CreateNamedPipe3(pipe_name, 2)
           pipe    := CreateNamedPipe3(pipe_name, 2)
           if (pipe=-1 or pipe_ga=-1)
            {
              MsgBox CreateNamedPipe failed.
              ExitApp
            }

           ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes().
           DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0)
           ; This pipe is not needed, so close it now. (The pipe instance will not be fully
           ; destroyed until AutoHotkey also closes its handle.)
           DllCall("CloseHandle", ptr, pipe_ga)
           ; Wait for AutoHotkey to connect to open the "file".
           DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0)

           ; Standard AHK needs a UTF-8 BOM to work via pipe.  If we're running on
           ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead:
           Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script

           char_size := (A_IsUnicode ? 2:1)
           if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0)
           MsgBox WriteFile failed: `%ErrorLevel`%/`%A_LastError`%

           DllCall("CloseHandle", ptr, pipe)

           CreateNamedPipe3(Name, OpenMode=3, PipeMode=0, MaxInstances=255)
            {
              global ptr
              return DllCall("CreateNamedPipe","str","\\.\pipe\" Name,"uint",OpenMode
              ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr)
            }
           ExitApp
         }
        Else if RS_TimeToNextRecordingVar <= 29
	      GoSub, Label1 ;One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.
        Else if Use_clientcount_status_as_Hibernationblock >= 1
	      GoSub, Label1 ;One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.
        Else if RS_StatusVar >= 2
	      GoSub, Label1 ;One or more conditions above is NOT met...hibernation will be cancelled but automatic commercial removal will commence.		  
}	  
}

;---SUBROUTINES----------------------------------------------------------------------------------------------------
Label1:

If Edited_Video_Folder ;Edited video folder is activated
{ 
  Sleep, 4000 ;Just wait a little before creating pipe
  #NoEnv
  ptr := A_PtrSize ? "Ptr" : "UInt"
  char_size := A_IsUnicode ? 2 : 1

  Script=Run, CommercialRemover.exe, %Edited_Video_Folder%

  ; To prevent "collision", pipe_name could be something mostly "unique", like:
  ;   pipe_name := A_TickCount
  pipe_name := "InterceptShutdown"

  ; Before reading the file, AutoHotkey calls GetFileAttributes(). This causes
  ; the pipe to close, so we must create a second pipe for the actual file contents.
  ; Open them both before starting AutoHotkey, or the second attempt to open the
  ; "file" will be very likely to fail. The first created instance of the pipe
  ; seems to reliably be "opened" first. Otherwise, WriteFile would fail.
  pipe_ga := CreateNamedPipe4(pipe_name, 2)
  pipe    := CreateNamedPipe4(pipe_name, 2)
  if (pipe=-1 or pipe_ga=-1)
   {
    MsgBox CreateNamedPipe failed.
    ExitApp
   }

  ; Wait for AutoHotkey to connect to pipe_ga via GetFileAttributes().
  DllCall("ConnectNamedPipe", ptr, pipe_ga, ptr, 0)
  ; This pipe is not needed, so close it now. (The pipe instance will not be fully
  ; destroyed until AutoHotkey also closes its handle.)
  DllCall("CloseHandle", ptr, pipe_ga)
  ; Wait for AutoHotkey to connect to open the "file".
  DllCall("ConnectNamedPipe", ptr, pipe, ptr, 0)

  ; Standard AHK needs a UTF-8 BOM to work via pipe.  If we're running on
  ; Unicode AHK_L, 'Script' contains a UTF-16 string so add that BOM instead:
  Script := (A_IsUnicode ? chr(0xfeff) : chr(239) chr(187) chr(191)) . Script

  char_size := (A_IsUnicode ? 2:1)
  if !DllCall("WriteFile", ptr, pipe, "str", Script, "uint", (StrLen(Script)+1)*char_size, "uint*", 0, ptr, 0)
  MsgBox WriteFile failed: `%ErrorLevel`%/`%A_LastError`%

  DllCall("CloseHandle", ptr, pipe)

  CreateNamedPipe4(Name, OpenMode=3, PipeMode=0, MaxInstances=255)
   {
    global ptr
    return DllCall("CreateNamedPipe","str","\\.\pipe\" Name,"uint",OpenMode
    ,"uint",PipeMode,"uint",MaxInstances,"uint",0,"uint",0,"uint",0,ptr,0,ptr)
   }
  ExitApp
}
Else If Edited_Video_Folder = %ErrorLevel% ;Edited Video folder does not exist
  ExitApp

;----------------------------------------------------------------------------------------------------------------
;FUNCTIONS
;----------------------------------------------------------------------------------------------------------------
UrlDownloadToVar(URL, ByRef Result, UserAgent = "", Proxy = "", ProxyBypass = "") {
   ; Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation 4.0,
   ; Windows Me, Windows 98, or Windows 95.
   ; Requires Internet Explorer 3.0 or later.
   pFix:=a_isunicode ? "W" : "A"
   hModule := DllCall("LoadLibrary", "Str", "wininet.dll") 

   AccessType := Proxy != "" ? 3 : 1
   ;INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration 
   ;INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net 
   ;INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy 
   ;INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS 

   io := DllCall("wininet\InternetOpen" . pFix
   , "Str", UserAgent ;lpszAgent 
   , "UInt", AccessType 
   , "Str", Proxy 
   , "Str", ProxyBypass 
   , "UInt", 0) ;dwFlags 

   iou := DllCall("wininet\InternetOpenUrl" . pFix
   , "UInt", io 
   , "Str", url 
   , "Str", "" ;lpszHeaders 
   , "UInt", 0 ;dwHeadersLength 
   , "UInt", 0x80000000 ;dwFlags: INTERNET_FLAG_RELOAD = 0x80000000 // retrieve the original item 
   , "UInt", 0) ;dwContext 

   If (ErrorLevel != 0 or iou = 0) { 
       DllCall("FreeLibrary", "UInt", hModule) 
       return 0 
   } 

   VarSetCapacity(buffer, 10240, 0)
   VarSetCapacity(BytesRead, 4, 0)

   Loop 
   { 
       ;http://msdn.microsoft.com/library/en-us/wininet/wininet/internetreadfile.asp
       irf := DllCall("wininet\InternetReadFile", "UInt", iou, "UInt", &buffer, "UInt", 10240, "UInt", &BytesRead) 
       VarSetCapacity(buffer, -1) ;to update the variable's internally-stored length

       BytesRead_ = 0 ; reset
       Loop, 4  ; Build the integer by adding up its bytes. (From ExtractInteger-function)
           BytesRead_ += *(&BytesRead + A_Index-1) << 8*(A_Index-1) ;Bytes read in this very DllCall

       ; To ensure all data is retrieved, an application must continue to call the
       ; InternetReadFile function until the function returns TRUE and the lpdwNumberOfBytesRead parameter equals zero.
       If (irf = 1 and BytesRead_ = 0)
           break
       Else ; append the buffer's contents
       {
           a_isunicode ? buffer:=StrGet(&buffer, "CP0")
           Result .= SubStr(buffer, 1, BytesRead_ * (a_isunicode ? 2 : 1))
       }

       /* optional: retrieve only a part of the file
       BytesReadTotal += BytesRead_
       If (BytesReadTotal >= 30000) ; only read the first x bytes
       break                      ; (will be a multiple of the buffer size, if the file is not smaller; trim if neccessary)
       */
   }

   DllCall("wininet\InternetCloseHandle",  "UInt", iou) 
   DllCall("wininet\InternetCloseHandle",  "UInt", io) 
   DllCall("FreeLibrary", "UInt", hModule)
}
;----------------------------------------------------------------------------------------------------------------------
OldConfigCleanup(Daystokeep,Pathtoconfigs,exttodelete)
{
 difdays = %Daystokeep%
 Source = %Pathtoconfigs%\%exttodelete%
 Time := A_Now
 Loop, %Source%, 0, 0
 {
  TimeStamp := Time
  EnvSub, TimeStamp, %A_LoopFileTimeModified%, Days
  If ( TimeStamp >= difdays )
  {
   ;MsgBox, file to delete: %A_LoopFileLongPath%   
   ;FileDelete, %A_LoopFileLongPath% ;Files gets deleted instantly and permanent. 
   FileRecycle, %A_LoopFileLongPath% ;Files gets moved to the Recycle Bin
  }
  continue
 }
 ;ExitApp
}
;----------------------------------------------------------------------------------------------------------------------
loadXML(ByRef data)
{
  o := ComObjCreate("MSXML2.DOMDocument.6.0")
  o.async := false
  o.preserveWhiteSpace := true
  o.loadXML(data)
  return o
}
;----------------------------------------------------------------------------------------------------------------------
ReFormatTime( Time, Format, Delimiters  ) {
StringSplit F,Format, %A_Space%
Loop, Parse, Time, %Delimiters%
  Var := F%A_Index%,  %Var% := A_LoopField
Return YYYY MM DD HH MI SS
}
;----------------------------------------------------------------------------------------------------------------------

 

Edited by majstang
Link to comment
  • 2 weeks later...
Add: Autosearch: All recordings are now additionally added to the recordings history database. The entries will not be deleted, if you delete the actual recording. The check for previous recordings function of the auto recording timers now checks the search results against this database.

On every usage of the "Cleanup and Refresh Recording DB" task missing entries of existing recordings are added automatically to the history db.

Intelligent hibernation script update

 

Added: Correct handling of deactivated recording timers.

 

Since Lars added this great new feature "check for previous recordings function" all deactivated recording timers were treated as if they had active status by the Intelligent Hibernation script. Consequence of this fact was Hibernation got denied if less than 30 minutes to next recording start, even if this next recording start was a deactivated recording timer. Since the deactivated timer never starts for obvious reasons the Intelligent Hibernation script denied hibernation falsely. Not so Intelligent ;) In the updated script I re-wrote the "TIME TO NEXT RECORDING RETRIEVAL" section for correct handling of deactivated recording timers, which are now disregarded before the calculation of time to next recording. To make this work I also added some new functions in the bottom of script, so if wanting to update your script, copy the whole script from the post just above this one, which I just edited now.

 

Cheers :bye:

Majstang

Edited by majstang
Link to comment
  • 5 months later...

Windows 7 64-bit support

 

The latest revision of the intelligent hibernation script seem to work alright on Windows 7 64-bit, without any need for porting. EDIT: The commercial removal script does now work on 64-bit windows. A beta version of the detailed fileinfo/property tool for windows explorer has been released, which works fairly well retrieving the media format. This tool can be downloaded here:

http://www.DVBViewer.tv/forum/topic/48856-DVBViewer-recording-properties/

 

However the script not supporting 64-bit was the Intercept Shutdown script. Turns out this one didnt work at all on 64-bit windows (Vista/7) with Autohotkey_L Unicode 64-bit. I therefor ported the function and it is now working and tested on Windows 7 64-bit. Same setup as before...instructions here:

http://www.DVBViewer.tv/forum/topic/41387-another-intelligent-hibernationscript/page__view__findpost__p__318292

 

Regards

majstang

 

Intercept Shutdown script for Windows 7 64-bit

 

#NoTrayIcon
#Persistent

;While !DllCall("WaitNamedPipe","Str","\\.\pipe\InterceptShutdown","UInt",0xffffffff)
;Sleep, 100
;Run % """" A_AhkPath """ \\.\pipe\InterceptShutdown"

SetTimer, RunBeforeShutdown, Off
SetTimer, RunBeforeShutdown2, Off
Gui,+LastFound
hwnd:=WinExist()
DllCall("ShutdownBlockReasonCreate","Uint",hwnd,"Str",A_ScriptFullPath "is still running")
DllCall("kernel32.dll\SetProcessShutdownParameters", UInt, 0x4FF, UInt, 0)
OnMessage(0x11, "WM_QUERYENDSESSION")
OnMessage(0x5555, "RunBeforeShutdown2")
Return

WM_QUERYENDSESSION(wParam, lParam)
 {
   static sdtry = 0
   ENDSESSION_Logoff = 0x80000000
   If (lParam & ENDSESSION_Logoff) ; User is logging off.
     EventType = Logoff
   Else     ; System is either shutting down or restarting. and
     EventType = Shutdown
   If (EventType = "Shutdown" and sdtry = 0)
    {
      SetTimer, RunBeforeShutdown, On
      Return false ; Tell the OS to Abort the Shutdown/Logoff.
    }
   Else If (EventType = "Shutdown" and sdtry = 1)
     Return true
 }

RunBeforeShutdown2(wParam, lParam, msg)
 {
   SetTimer, RunBeforeShutdown2, On
   Return true
 }

RunBeforeShutdown:
SetTimer, RunBeforeShutdown, Off
Sleep, 200
SendInput, {ENTER}
Sleep, 1000
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%  

FileDelete, demo.htm
FileAppend,
(
<html>
<body style="overflow:hidden">
<body bgcolor="#0033FF" leftmargin="1" topmargin="1">
<div align="Center"><p>
<font color="#FFFB02" face="Segoe Print" size="4"><br><b>
Your HTPC is about to be Closed Down.
<br>
You now have a chance to choose closedown method
<br>
or wait until default method gets choosen for you</b>
</p>
<font face="Segoe Print" size="5"><b>
<script type="text/javascript">
var countDownInterval=20; 
var countDownTime=countDownInterval+1; 
function countDown(){ 
countDownTime--; 
if (countDownTime <=0){ 
countDownTime=countDownInterval; 
clearTimeout(counter); 
//window.location=""; 
return 
} 
if (document.getElementById) //else if NS6+ 
document.getElementById("countDownText").innerHTML=countDownTime+" ";
else if (document.layers){ //CHANGE TEXT BELOW TO YOUR OWN 
document.c_reload.document.c_reload2.document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
document.c_reload.document.c_reload2.document.close() 
} 
counter=setTimeout("countDown()", 1000); 
} 

function startit(){ 
if (document.getElementById) //CHANGE TEXT BELOW TO YOUR OWN 
document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
countDown() 
} 

if (document.getElementById) 
startit() 
else 
window.onload=startit 
clearTimeout ( countDownTime );
</script>
</font></b>
</div>
</body>
</html>
)
, demo.htm


URL=file:///%A_ScriptDir%\demo.htm
Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=650, HtmH=250, BDefault=1, DlgBgColor=0xEE0000, DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"

Sel := HtmDlg( URL, "", Options )

if (Sel = 1)
 {
  ;Run, InterceptShutdown.exe, D:\ScriptsForWindows7
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
  Return
 }
else if (Sel = 2)
 {
  ;Run, InterceptShutdown.exe, D:\ScriptsForWindows7
  DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
  Return
 }
else if (Sel = 3)
 {
  ;SetWorkingDir, C:\Program\HomeSeer HS2
  ;RunWait, destroy_homeseer_speaker_client.vbs, D:\Extremt Bra Programvara\Scripts\VBS Code project\gopal_code_demo
  ;RunWait, Jon00ShutdownHS.exe, C:\Program\HomeSeer HS2
  ;IniRead, HomeSeerPID, HomeSeerPID.ini, IExplorerPID, key
  ;WinClose, ahk_pid %HomeSeerPID%
  Process, Close, DVBViewer.exe
  Shutdown, 1
  ExitApp
  Return
 }
else if (Sel = 4)
 {
  ;SetWorkingDir, C:\Program\HomeSeer HS2
  ;RunWait, destroy_homeseer_speaker_client.vbs, D:\Extremt Bra Programvara\Scripts\VBS Code project\gopal_code_demo
  ;RunWait, Jon00ShutdownHS.exe, C:\Program\HomeSeer HS2
  ;IniRead, HomeSeerPID, HomeSeerPID.ini, IExplorerPID, key
  ;WinClose, ahk_pid %HomeSeerPID%
  Process, Close, DVBViewer.exe
  Shutdown, 2
  ExitApp
  Return
 }
else if (Sel = 5)
 {
  hibernate = 0
  ;Run, InterceptShutdown.exe, D:\ScriptsForWindows7
  Return
 }

DllCall("ShutdownBlockReasonDestroy","Uint",hwnd)
Return                                                 ; // end of auto-execute section //

RunBeforeShutdown2:
SetTimer, RunBeforeShutdown2, Off
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%  

FileDelete, demo.htm
FileAppend,
(
<html>
<body style="overflow:hidden">
<body bgcolor="#0033FF" leftmargin="1" topmargin="1">
<div align="Center"><p>
<font color="#FFFB02" face="Segoe Print" size="4"><br><b>
Your HTPC is about to be Closed Down.
<br>
You now have a chance to choose closedown method
<br>
or wait until default method gets choosen for you</b>
</p>
<font face="Segoe Print" size="5"><b>
<script type="text/javascript">
var countDownInterval=20; 
var countDownTime=countDownInterval+1; 
function countDown(){ 
countDownTime--; 
if (countDownTime <=0){ 
countDownTime=countDownInterval; 
clearTimeout(counter); 
//window.location=""; 
return 
} 
if (document.getElementById) //else if NS6+ 
document.getElementById("countDownText").innerHTML=countDownTime+" ";
else if (document.layers){ //CHANGE TEXT BELOW TO YOUR OWN 
document.c_reload.document.c_reload2.document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
document.c_reload.document.c_reload2.document.close() 
} 
counter=setTimeout("countDown()", 1000); 
} 

function startit(){ 
if (document.getElementById) //CHANGE TEXT BELOW TO YOUR OWN 
document.write('<b id="countDownText">'+countDownTime+' </b> seconds') 
countDown() 
} 

if (document.getElementById) 
startit() 
else 
window.onload=startit 
clearTimeout ( countDownTime );
</script>
</font></b>
</div>
</body>
</html>
)
, demo.htm


URL=file:///%A_ScriptDir%\demo.htm
Options := "Buttons=Hibernate/Standby/Shutdown/Restart/Cancel, HtmW=650, HtmH=250, BDefault=1, DlgBgColor=0xEE0000, DlgTopmost=1, TimeOut=20, Title=System Closedown in 20 seconds, DlgStyle=NoFrame"

Sel := HtmDlg( URL, "", Options )

if (Sel = 1)
 {
  ;Run, InterceptShutdown.exe, D:\ScriptsForWindows7
  DllCall("PowrProf\SetSuspendState", "int", 1, "int", 0, "int", 0)
  Return
 }
else if (Sel = 2)
 {
  ;Run, InterceptShutdown.exe, D:\ScriptsForWindows7
  DllCall("PowrProf\SetSuspendState", "int", 0, "int", 0, "int", 0)
  Return
 }
else if (Sel = 3)
 {
  SetWorkingDir, C:\Program\HomeSeer HS2
  RunWait, destroy_homeseer_speaker_client.vbs, D:\Extremt Bra Programvara\Scripts\VBS Code project\gopal_code_demo
  RunWait, Jon00ShutdownHS.exe, C:\Program\HomeSeer HS2
  IniRead, HomeSeerPID, HomeSeerPID.ini, IExplorerPID, key
  WinClose, ahk_pid %HomeSeerPID%
  Process, Close, DVBViewer.exe
  Shutdown, 1
  ExitApp
  Return
 }
else if (Sel = 4)
 {
  SetWorkingDir, C:\Program\HomeSeer HS2
  RunWait, destroy_homeseer_speaker_client.vbs, D:\Extremt Bra Programvara\Scripts\VBS Code project\gopal_code_demo
  RunWait, Jon00ShutdownHS.exe, C:\Program\HomeSeer HS2
  IniRead, HomeSeerPID, HomeSeerPID.ini, IExplorerPID, key
  WinClose, ahk_pid %HomeSeerPID%
  Process, Close, DVBViewer.exe
  Shutdown, 2
  ExitApp
  Return
 }
else if (Sel = 5)
 {
  hibernate = 0
  ;Run, InterceptShutdown.exe, D:\ScriptsForWindows7
  Return
 }

DllCall("ShutdownBlockReasonDestroy","Uint",hwnd)
Return                                                 ; // end of auto-execute section //

;#Include HtmDlg.ahk ; You may copy/Paste HtmDlg() Instead
HtmDlg( _URL="", _Owner=0, _Options="", _ODL="," ) {     ; HTML DialogBox v0.57 -- by SKAN
; Topic: www.autohotkey.com/forum/viewtopic.php?t=60215    CD:09-Jul-2010 | LM:05-Aug-2010
; Credit: WebControl Demo by Sean - www.autohotkey.com/forum/viewtopic.php?p=103987#103987

Static _hInst,_hDLG,_DlgP,_B$,_B$L,_pIWEB,_pV,_DlgT,CliC,HtmF=0,_Brush=0,Pntr,PtrS,BDef=1,BEsc=0

If ( A_EventInfo = 0xCBF ) {                                   ; nested Callback Function
  hWnd := _URL,  uMsg := _Owner,  wP := _Options,  lP := _ODL

  If ( uMsg=0x112 && wP=0xF060 )                               ; WM_SYSCOMMAND & SC_ClOSE
    Return DllCall( "DestroyWindow", Pntr,_hDLG ) | ( BDEf:=BEsc )

  If ( uMsg=0x111 && (wP>>16)=0 )                              ; WM_COMMAND & BN_CLICKED
    Return DllCall( "DestroyWindow", Pntr,_hDLG ) | ( BDef := (wP=2) ? BEsc : wP-100  )

  If ( uMsg=0x007 && HtmF=0 )                                  ; WM_SETFOCUS
    Return DllCall( "SetFocus", Pntr,DllCall( "GetDlgItem", Pntr,_hDLG, UInt,100+BDEF, Pntr ) )

  If ( uMsg=0x201 && CliC )                                    ; WM_LBUTTONDOWN
    Return DllCall( "DestroyWindow", Pntr,_hDLG ) |  ( BDEf := 1 )

  If ( uMsg=0x136 && _Brush<>0 )                               ; WM_CTLCOLORDLG
    Return _Brush

  if ( uMsg=0x002 && hWnd=_hDLG )                              ; WM_DESTROY
    Return _Brush := DllCall( "DeleteObject", Pntr,_Brush, UInt ) >> 32

Return False
}

If ! ( _hInst ) {
Pntr := InStr( A_AhkVersion, "L" ) ? "Ptr" : "UInt", PtrS := (A_PtrSize != "") ? A_PtrSize : 4
_hInst := DllCall( "GetModuleHandle", Str,A_IsCompiled ? A_ScriptFullpath : A_AhkPath, Pntr )

_DT := "61160CD3AFCDD0118A3EGC04FC9E26EZQ1GFFFFUCHC88GAZO9G9G1I4DG53G2H53G68G65G6CG6CG2H"
. "44G6CG67ZL5V64K41G74G6CG41G78G57G69G6EK7BG38G38G35G36G46G39G36G31G2DG33G34G3H41G2DG31"
. "G31G44G3H2DG41G39G36G42G2DG3H3H43G3H34G46G44G37G3H35G41G32G7DZS14V65KFFFF8ZP14V66KFFF"
. "F8ZP14V67KFFFF8ZP14V68KFFFF8ZP14V69KFFFF8ZP14V6AKFFFF8ZP14V6BKFFFF8ZP14V6CKFFFF8ZP14V"
. "6DKFFFF8P"

Loop 20   ;  Decompressing Nulls : www.autohotkey.com/forum/viewtopic.php?p=198560#198560
 StringReplace,_DT,_DT,% Chr(70+21-A_Index),% SubStr("000000000000000000000",A_Index),All

Loop % _B$L := VarSetCapacity( _B$, ( _DTLEN := StrLen(_DT) // 2 ), 0 )
 NumPut( "0x" . SubStr(_DT, 2*A_Index-1,2),_B$,A_Index-1,"Char" )  ; Creating Structure
_pIWEB := &_B$, _pV := &_B$+16, _DlgT := &_B$+32   ; Relevant pointers to Structure

DllCall( "GetModuleHandle", Str,"atl.dll" ) ? 0 : DllCall( "LoadLibrary", Str,"atl.dll" )
DllCall( "atl\AtlAxWinInit" ),          _DlgP := RegisterCallback( A_ThisFunc,0,4,0xCBF )
}

VarSetCapacity( _W$,_B$L,0 ), DllCall( "RtlMoveMemory", Pntr,&_W$, Pntr,&_B$, Pntr,_B$L )
_pIWEB := &_W$, _pV := &_W$+16, _DlgT := &_W$+32         ; Relevant pointers to Structure

Butt:="OK", BWid:=75, BHei:=23, BSpH:=5, BSpV:=8, BAli:=1, Slee:=-1, HtmC:=0, CliC:=0
HtmD:=0, DlgT:=0, DlgN:=0, DlgX:="", DlgY:="", HtmW:=240, HtmH:=140, Left:=0, TopM:=0
Loop, Parse, _Options, =%_ODL%, %A_Space%        ; Override Variables with user 'Options'
  A_Index & 1  ? (  __  := (SubStr(A_LoopField,1,1)="_") ? "_" : SubStr(A_LoopField,1,4))
               : ( %__% := A_LoopField )

Cap  := DllCall( "GetSystemMetrics", UInt,4  ) ; SM_CYCAPTION    = Window Caption
Frm  := DllCall( "GetSystemMetrics", UInt,7  ) ; SM_CXFIXEDFRAME = Window Frame

NumPut( HtmC<>0 ? 0x200 : 0x0, _W$, 32+68, "UInt" ), DlgD := DlgD ? 0x8000000 : 0x0
FonS ? NumPut( FonS < 8 ? 8 : ( FonS > 14 ? 14 : FonS ), _W$, 64, "UShort" ) : 0

If (  ( DlgS := SubStr( DlgS,1,1 ) ) <> ""  )
 _ := ( DlgS = "F" ) ? NumPut( 0x800000C0 | DlgD, _W$, 44, "UInt" ) | ( Cap := 0 )
   :  ( DlgS = "N" ) ? NumPut( 0x80000040 | DlgD, _W$, 44, "UInt" ) | ( Frm := Cap := 0 )
   :  ( DlgS = "B" ) ? NumPut( 0x80800040 | DlgD, _W$, 44, "UInt" ) | ( Cap := 0 ) | ( Frm := 1 )
   :                   NumPut( 0x80C800C0 | DlgD, _W$, 44, "UInt" )

IfNotEqual,DlgB,, SetEnv,_Brush,% DllCall( "CreateSolidBrush", UInt,DlgB, Pntr )

_hDLG  := DllCall( "CreateDialogIndirectParam", Pntr,_hInst, Pntr,_DlgT, Pntr
,_Owner := ( _Owner <> "" ) ? _Owner : DllCall( "GetShellWindow", Pntr ), Pntr,_DlgP, Pntr,0 )

VarSetCapacity( _WU, StrLen(_URL) * ( A_IsUnicode ? 1 : 2 ) + 2, 0 )
A_IsUnicode ? _WU := _URL : DllCall( "MultiByteToWideChar", UInt,0, UInt,0, Pntr,&_URL
                                    , Int,-1, Pntr,&_WU, Int,StrLen(_URL)+1 )

_hHTM := DllCall( "GetDlgItem", Pntr,_hDLG, UInt,100, Pntr )
DllCall( "atl\AtlAxGetControl", Pntr,_hHTM, Pntr "P",_ppunk )
DllCall( NumGet( NumGet( _ppunk+0 )+PtrS*0 ), Pntr,_ppunk, Pntr,_pIWEB, Pntr "P",_ppwb )
DllCall( NumGet( NumGet( _ppunk+0 )+PtrS*2 ), Pntr,_ppunk ),_pwb := NumGet( _ppwb+0 )
DllCall( NumGet(_pwb+PtrS*11),Pntr,_ppwb, Pntr,&_WU, Pntr,_pV,Pntr,_pV,Pntr,_pV,Pntr,_pV )
DllCall( NumGet(_pwb+PtrS*2), Pntr,_ppwb )

DllCall( "SetWindowPos", Pntr,_hHTM,Pntr,0,Int,Left,Int,TopM,Int,HtmW,Int,HtmH,UInt,0x14 )
IfNotEqual,HtmD,0, Control,Disable,,,ahk_id %_hHTM%

DlgW := Frm + Left + HtmW + Frm + Left,       ClAW := DlgW - Frm - Frm ; ClientArea Width
DlgH := Frm + Cap + TopM + HtmH + BSpV + BHei + BSpV + Frm
DlgX := ( DlgX <> "" ) ? DlgX : ( A_ScreenWidth - DlgW ) // 2
DlgY := ( DlgY <> "" ) ? DlgY : ( A_ScreenHeight - DlgH ) // 2

StringReplace, Butt,Butt, /,/, UseErrorLevel
bCount := ErrorLevel+1
BY := TopM + HtmH + BSpV
BX := ( Bali=1 ? ( ( ClAW - (BSpH*(bCount-1)) - (BWid*bCount) ) / 2 )
   :  ( Bali=0 ? ( ( BSpH * 2 ) + ( HtmD ? 0 : Left ) )
   :  ( ClAW - (BSpH*(bCount+1)) - (BWid*bCount) - ( HtmD ? 0 : Left ) ) ) )

Loop, Parse, Butt, /   ;  SetWindowPos flags = SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOZORDER
  DllCall( "SetWindowPos", Pntr,BH:=DllCall( "GetDlgItem", Pntr,_hDLG, UInt,100+A_Index, Pntr )
                       , Pntr,0, Int,BX, Int,BY, Int,BWid, Int,BHei, UInt,0x40|0x10|0x4 )
, DllCall( "SetWindowText", Pntr,BH, Str,A_LoopField ),   BX := BX + BSpH + BWid
, _ := ( BNoT<>"" ) ? DllCall( "uxtheme\SetWindowTheme", Pntr,BH, Pntr,0, Pntr "P",0 ) : 0
, _ := ( BSFl<>"" ) ? DllCall( "SetWindowLong", Pntr,BH, Int,-16, UInt,0x50018000 ) : 0

BDef := ( BDef < 1 || BDef > bCount ) ? 1 : BDef ; Force Default Button
DllCall( "SendMessage", Pntr,_hDLG, UInt,0x401, Pntr,100+BDef, Pntr,0 )    ;  DM_SETDEFID

DllCall( "SetWindowText", Pntr,_hDLG, Str,Titl ? Titl : A_ScriptName ) ; Set Dialog Title
DllCall( "SetWindowPos", Pntr,_hDLG, Pntr,DlgT ? -1 : 1, Int,DlgX, Int,DlgY, Int,DlgW, Int
                       , DlgH, UInt,0x10 )         ; DlgTopmost ? HWND_TOPMOST : HWND_TOP

While ( nReady <> 4 && DlgW<>"" )  ;  wait until webpage-load adapted from Seans's IE.ahk
  Sleep % 1 + ( DllCall( NumGet(NumGet(1*_ppwb)+PtrS*56 ), Pntr,_ppwb, UintP,nReady ) >> 32 )
Sleep, %Slee%

DllCall( "ShowWindow", Pntr,_hDLG, Int,DlgN ? 8 : 5 ) ; DlgNA ? SW_SHOWNA : SW_SHOW
IfNotEqual,HtmF,0, ControlFocus,, ahk_ID %_hDLG%
WinWaitClose, ahk_id %_hDLG%,, %Time%
TimedOut := Errorlevel  ? DllCall( "EndDialog", Pntr,_hDLG, Pntr,0 ) : 0
IfNotEqual,AltR,, IfGreater,BDef,0, StringSplit,B,Butt,/
DllCall( "SetLastError", UInt,TimedOut ? 1 : 0 )
Return AltR ? B%BDef% : BDef
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \
>-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  O P T I O N S  -  -<
\- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /

Usage: HtmDlg( URL, hwndOwner, Options, OptionsDelimiter )

Parameters :

URL              - A valid URL supported by Internet Explorer including Res:// and File://

hWndOwner        - Handle to the parent window. If invalid handle or 0 ( zero ) is passed,
                  the dialog will have a taskbar button. Passing "" as a parameter will
                  set 'Progman' the owner, thereby supressing the 'Taskbar Button'.

Options          - A series of 'variable overrides' delimited with character specified in
                  'Optionsdelimiter'. Please refer 'VARIABLE OVERRIDES' below.

OptionsDelimiter - The delimiter used in seperating 'variable overrides'


;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  * * *   V A R I A B L E   O V E R R I D E S   * * *
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Important Note: leading 4 characters of a variable will be sufficient.
               for eg.: Instead of 'AltReturn=1' you may use 'AltR=1'


DlgXpos         = X coordinate in pixels, relative to screen
                 Dialog is horizontally centered by default

DlgYpos         = Y coordinate in pixels, relative to screen
                 Dialog is vertically centered by default

DlgTopmost      = 1 will set the Dialog 'Always-on-Top'
                 0 is default

DlgDisable      = 1 will disable the Dialog window
                 No default value

                 Caution:
                 Since there is no way to interact, you may opt to TimeOut the Dialog

DlgStyle        = Frame or NoFrame or Border. Leading character is sufficient, like: F-N-B
                 Default is Caption

                 Note on Styles used:

                 Frame   = WS_POPUP | DS_MODALFRAME
                 NoFrame = WS_POPUP | DS_SETFONT
                 Border  = WS_POPUP | DS_SETFONT | WS_BORDER
                 Caption = WS_POPUP | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU

                 WS_DISABLED is additionally set when DlgDisable=1

DlgNoActivate   = 1 will Show the Dialog without activating it
                 0 is default

DlgBgColor      = ColorRef.  eg: 0x0000FF is Red / Invalid ColorRef will result in Black.

DlgWait         = 1 will delay Dialog from being shown - until HTM is fully loaded

Sleep           = MilliSeconds ( Will be used just before Dialog is shown )
                 Default value is -1, 'No sleep'

Title           = Captionbar Text
                 Default is A_ScriptName

AltReturn       = 1 will return Button-text
                 0 is default and Button-instance will be returned

TimeOut         = Seconds
                 No default value

                 Note: A_LastError will be true when a TimeOut occurs

ClickClose      = 1
                 Default value is 0

                 Note:
                 Mouse L-Click on window's unoccupied clientarea' will close the dialog

                 Tip: Use following to simulate a unobtrusive message ( like TrayTip )
                 DlgTopmost=1, HtmD=1, DlgNA=1, DlgStyle=Border, BHei=0, BSpV=0, Clic=1

LeftMargin      = Spacing in Pixels ( on the left/right sides of WebControl )
                 Default value is 0

TopMargin       = Spacing in Pixels ( above the WebControl )
                 Default value is 0

FonName           ( Not implemented yet )
                 Default is 'MS Shell Dlg' and equivalent

FonSize         = Pointsize ( text size of Button-labels - restricted to 8,10,12,14 )
                 Default value is 8

HtmClientEdge   = 1 to set WS_EX_CLIENTEDGE
                 Default value is 0

HtmDisable      = 1 to disable
                 Default value is 0

HtmWidth        = Width of WebControl in Pixels
                 Default value is 240

HtmHeight       = Height of WebControl in pixels
                 Default value is 140

HtmFocus        = 1 will activate the dialog and WebControl will have input focus
                 Default value is 0

                 Note: DlgNoActivate option will lose effect.
                       For best result, use this option along with DlgWait=1

Buttons         = Button labels seperated with "/"  eg: Buttons=Yes/No/Cancel
                 Default Button is "OK"

BDefault        = Instance of Default Button. eg: To make 3rd Button default, use BDef=3
                 Default forced value is 1

BEscape         = Instance of Button to return when dialog is closed or {Esc} is pressed
                 Default is 0

BWidth          = Button Width in Pixels
                 Default Value is 75

BHeight         = Button Height in Pixels
                 Default value is 23

BSpHorizontal   = Pixels ( affects the spacing on the sides of a button )

BSpVertical     = Pixels ( affects the spacing above/below a button )

BAlign          = 0 or 1 or 2  ( for Left, Center, Right alignment of buttons )
                 Default is 1

BNoTheme        = 1 will remove theme from buttons ( XP & greater )
                 No default value

BSFlat          = 1 will flatten the button by removing the 3D edge - requires BNoTheme=1
                 No default value

;< - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >

*/

 

Edited by majstang
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...