Win32: How to quit perl script during log off automatically ?

Discussion in 'Perl Misc' started by Peter Sobisch, Jun 12, 2007.

  1. Hi folks,

    on Unix its a simplest thing, perl do it for me or I can set $SIG{HUP} :)
    but, how can I do this in Windows ?

    Every time I try to shutdown or log off, pop-up is comming up with
    "application doesn't response" and expecting to kill by clicking a
    button -> very dirty thing :-/

    So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no
    WM_QUERYENDSESSION will be sent to the script (although the script is able
    to receive other Window-Messages send by SendMessage).

    Is it so, because perl is a "console based application" and windows sends
    WM_QUERYENDSESSION + WM_ENDSESSION only to GUI applications ?

    I "googled" and found something about SetConsoleCtrlHandler, which should give
    similar funcitionality as WM_QUERYENDSESSION mechanism, but in order to set
    this, I need to define a callback using Win32::API::Callback in my perl code,
    but, this module doesn't work for me at all, it generates segfault every time,
    even using the very simple examples from the documentation (nmake test fails
    also).

    Is there any other simple way to recognize inside of a perl script
    that the Windows is shutting down or the user is logging off ?

    I run ActivePerl 5.8.8 on W2k/XPpro.

    regards,
    Peter
     
    Peter Sobisch, Jun 12, 2007
    #1
    1. Advertising

  2. Peter Sobisch

    Lambik Guest

    "Peter Sobisch" <> wrote in message
    news:f4merj$h5f$...
    > Hi folks,
    >
    > on Unix its a simplest thing, perl do it for me or I can set $SIG{HUP} :)
    > but, how can I do this in Windows ?
    >
    > Every time I try to shutdown or log off, pop-up is comming up with
    > "application doesn't response" and expecting to kill by clicking a
    > button -> very dirty thing :-/
    >
    > So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no


    You should reveive a WM_CLOSE according to Bill.
     
    Lambik, Jun 13, 2007
    #2
    1. Advertising

  3. Lambik <> schrieb:
    >> on Unix its a simplest thing, perl do it for me or I can set $SIG{HUP} :)
    >> but, how can I do this in Windows ?
    >>
    >> Every time I try to shutdown or log off, pop-up is comming up with
    >> "application doesn't response" and expecting to kill by clicking a
    >> button -> very dirty thing :-/
    >>
    >> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no

    >
    > You should reveive a WM_CLOSE according to Bill.



    not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.

    There must be something more in the Win32-universe :)


    regards
    Peter
     
    Peter Sobisch, Jun 13, 2007
    #3
  4. Peter Sobisch wrote:
    > Lambik <> schrieb:
    >>> on Unix its a simplest thing, perl do it for me or I can set $SIG{HUP} :)
    >>> but, how can I do this in Windows ?
    >>>
    >>> Every time I try to shutdown or log off, pop-up is comming up with
    >>> "application doesn't response" and expecting to kill by clicking a
    >>> button -> very dirty thing :-/
    >>>
    >>> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no

    >>
    >> You should reveive a WM_CLOSE according to Bill.

    >
    >
    > not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    > WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.
    >
    > There must be something more in the Win32-universe :)


    Have you also read the MSDN documentation about SetConsoleCtrlHandler?
    The last paragraph say:

    The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
    CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off,
    or shuts down the system so that the process has an opportunity to clean
    up before termination. Console functions, or any C run-time functions
    that call console functions, may not work reliably during processing of
    any of the three signals mentioned previously. The reason is that some
    or all of the internal console cleanup routines may have been called
    before executing the process signal handler.

    Can you send me the code you are using, maybe I can find it out why the
    Win32::API::Callback Module crashes.

    regards,
    Reinhard




    --
    PM Mails an rpirpag <at> gmx dot at
     
    Reinhard Pagitsch, Jun 14, 2007
    #4
  5. Reinhard Pagitsch <> schrieb:
    >>>> Every time I try to shutdown or log off, pop-up is comming up with
    >>>> "application doesn't response" and expecting to kill by clicking a
    >>>> button -> very dirty thing :-/
    >>>> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no
    >>> You should reveive a WM_CLOSE according to Bill.

    >> not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    >> WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.

    >
    > Have you also read the MSDN documentation about SetConsoleCtrlHandler?
    > The last paragraph say:
    >
    > The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
    > CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off,
    > or shuts down the system so that the process has an opportunity to clean
    > up before termination. Console functions, or any C run-time functions
    > that call console functions, may not work reliably during processing of
    > any of the three signals mentioned previously. The reason is that some
    > or all of the internal console cleanup routines may have been called
    > before executing the process signal handler.


    this is the thing I wanted to do but the Win32::API::Callback doesn't
    work :-(
    But I have a small workaround for now, I wrote a C module where I
    register a C-written-callback where I run ExitProcess().
    It's dirty to me, because I have no possibility to clean up or do
    something else, but, the process really ends on logoff.

    Neverthereless, I still interesting in Win32::API::Callback to get it
    work, because it would be very useful feature in Win32 enviroment.

    I tried to write something similars, but how I mentioned above, I've a
    problem to call a perl routine from the C-callback, not even the
    simplest one from perlcall manpage worked, I got SEGFAULT every time.

    I'm not sure, but could it be a problem calling the call_pv() or call_sv()
    from the callback which is launching in another thread ?

    MS says the CtrlHandler will be called in separated thread, see
    the "HandlerRoutine" in MSDN:

    ------snip------
    Because the system creates a new thread in the process to execute the
    handler function, it is possible that the handler function will be
    terminated by another thread in the process. Be sure to synchronize
    threads in the process with the thread for the handler function.
    ------snap------

    > Can you send me the code you are using, maybe I can find it out why the
    > Win32::API::Callback Module crashes.


    just a simple define of a callback:

    ----snip---
    use Win32::API;
    use Win32::API::Callback;

    my $callback = Win32::API::Callback->new(
    sub { my($a, $b) = @_; return $a+$b; },
    "NN", "N",
    );
    ----snap---

    gives the SEGFAULT and following message written to the console:
    "Free to wrong pool 15e2660 not e58b2660, <DATA> line 164."
     
    Peter Sobisch, Jun 15, 2007
    #5
  6. Peter Sobisch

    Thomas Kratz Guest

    Peter Sobisch wrote:
    > ----snip---
    > use Win32::API;
    > use Win32::API::Callback;
    >
    > my $callback = Win32::API::Callback->new(
    > sub { my($a, $b) = @_; return $a+$b; },
    > "NN", "N",
    > );
    > ----snap---
    >
    > gives the SEGFAULT and following message written to the console:
    > "Free to wrong pool 15e2660 not e58b2660, <DATA> line 164."


    Your Win32::API::Callback seems to be broken. The code runs without
    errors on my 5.8.8 (windows non ActiveState). Where did you install it from?

    Thomas

    --
    $/=$,,$_=<DATA>,s,(.*),$1,see;__END__
    s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
    $_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
    '%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
    print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e.r^.>l^..>k^.-
     
    Thomas Kratz, Jun 15, 2007
    #6
  7. Thomas Kratz <> schrieb:
    > Peter Sobisch wrote:
    >> ----snip---
    >> use Win32::API;
    >> use Win32::API::Callback;
    >>
    >> my $callback = Win32::API::Callback->new(
    >> sub { my($a, $b) = @_; return $a+$b; },
    >> "NN", "N",
    >> );
    >> ----snap---
    >>
    >> gives the SEGFAULT and following message written to the console:
    >> "Free to wrong pool 15e2660 not e58b2660, <DATA> line 164."

    >
    > Your Win32::API::Callback seems to be broken. The code runs without
    > errors on my 5.8.8 (windows non ActiveState). Where did you install it from?


    I've also ActiveState 5.8.8 Build 817 installed, I got the Win32::API-0.46 from
    CPAN and installed it by using Bloodshed Dev-C++ 4.9.9.2 and nmake1.5.

    Evereything went well, except the Callback test, which has failed.
    Nevertheless I did "nmake install" in order to use the other
    Win32::API functionality.

    I run Windows XP Pro SP 2.

    Regards,
    Peter
     
    Peter Sobisch, Jun 15, 2007
    #7
  8. Peter Sobisch wrote:
    > Reinhard Pagitsch <> schrieb:
    >>>>> Every time I try to shutdown or log off, pop-up is comming up with
    >>>>> "application doesn't response" and expecting to kill by clicking a
    >>>>> button -> very dirty thing :-/
    >>>>> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no
    >>>> You should reveive a WM_CLOSE according to Bill.
    >>> not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    >>> WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.

    >>
    >> Have you also read the MSDN documentation about SetConsoleCtrlHandler?
    >> The last paragraph say:
    >>
    >> The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
    >> CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off,
    >> or shuts down the system so that the process has an opportunity to clean
    >> up before termination. Console functions, or any C run-time functions
    >> that call console functions, may not work reliably during processing of
    >> any of the three signals mentioned previously. The reason is that some
    >> or all of the internal console cleanup routines may have been called
    >> before executing the process signal handler.

    >
    > this is the thing I wanted to do but the Win32::API::Callback doesn't
    > work :-(
    > But I have a small workaround for now, I wrote a C module where I
    > register a C-written-callback where I run ExitProcess().
    > It's dirty to me, because I have no possibility to clean up or do
    > something else, but, the process really ends on logoff.
    >
    > Neverthereless, I still interesting in Win32::API::Callback to get it
    > work, because it would be very useful feature in Win32 enviroment.
    >
    > I tried to write something similars, but how I mentioned above, I've a
    > problem to call a perl routine from the C-callback, not even the
    > simplest one from perlcall manpage worked, I got SEGFAULT every time.
    >
    > I'm not sure, but could it be a problem calling the call_pv() or call_sv()
    > from the callback which is launching in another thread ?
    >
    > MS says the CtrlHandler will be called in separated thread, see
    > the "HandlerRoutine" in MSDN:
    >
    > ------snip------
    > Because the system creates a new thread in the process to execute the
    > handler function, it is possible that the handler function will be
    > terminated by another thread in the process. Be sure to synchronize
    > threads in the process with the thread for the handler function.
    > ------snap------
    >
    >> Can you send me the code you are using, maybe I can find it out why the
    >> Win32::API::Callback Module crashes.

    >
    > just a simple define of a callback:
    >
    > ----snip---
    > use Win32::API;
    > use Win32::API::Callback;
    >
    > my $callback = Win32::API::Callback->new(
    > sub { my($a, $b) = @_; return $a+$b; },
    > "NN", "N",
    > );
    > ----snap---
    >
    > gives the SEGFAULT and following message written to the console:
    > "Free to wrong pool 15e2660 not e58b2660, <DATA> line 164."
    >
    >


    As Thomas wrote, the Module is broken. I assume to remove it and install
    it again. In my environment, Activestate 5.8.8 on XP Sp2, this code
    works perfect.

    You can download it from http://www.bribes.org/perl/ppm/ (30-Jan-2007)
    or Activestate.

    Here you can find a list of PPM repositories:
    http://win32.perl.org/wiki/index.php?title=PPM_Repositories

    regards,
    Reinhard


    --
    PM Mails an rpirpag <at> gmx dot at
     
    Reinhard Pagitsch, Jun 15, 2007
    #8
  9. Peter Sobisch

    Lambik Guest

    "Peter Sobisch" <> wrote in message
    news:f4ogqo$uun$...
    >
    > Lambik <> schrieb:
    > >> on Unix its a simplest thing, perl do it for me or I can set $SIG{HUP}

    :)
    > >> but, how can I do this in Windows ?
    > >>
    > >> Every time I try to shutdown or log off, pop-up is comming up with
    > >> "application doesn't response" and expecting to kill by clicking a
    > >> button -> very dirty thing :-/
    > >>
    > >> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but

    no
    > >
    > > You should reveive a WM_CLOSE according to Bill.

    >
    >
    > not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    > WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.
    >


    I hate to state the obvious, but I recon you considered making it a windows
    program using win32::gui. It has a getMessage
    http://dada.perl.it/gui_docs/Win32_GUI.html#GetMessage_MIN_MAX_



    And you could use threads adding a thread which listens to a c program. But
    I guess you've already done that. There is always the possibility to make
    your own XS module.



    #include <windows.h>

    #include <stdio.h>



    BOOL CtrlHandler( DWORD fdwCtrlType )

    {

    switch( fdwCtrlType )

    {

    case CTRL_LOGOFF_EVENT:

    Beep( 1000, 200 );

    printf( "Ctrl-Logoff event\n\n" );

    return FALSE;



    case CTRL_SHUTDOWN_EVENT:

    Beep( 750, 500 );

    printf( "Ctrl-Shutdown event\n\n" );

    return FALSE;



    default:

    return FALSE;

    }

    }



    void main( void )

    {

    if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) )

    {

    while( 1 ){ }

    }

    else

    printf( "\nERROR: Could not set control handler");

    }
     
    Lambik, Jun 15, 2007
    #9
  10. Reinhard Pagitsch <> schrieb:
    > Peter Sobisch wrote:
    >> Reinhard Pagitsch <> schrieb:
    >>>>>> Every time I try to shutdown or log off, pop-up is comming up with
    >>>>>> "application doesn't response" and expecting to kill by clicking a
    >>>>>> button -> very dirty thing :-/
    >>>>>> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no
    >>>>> You should reveive a WM_CLOSE according to Bill.
    >>>> not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    >>>> WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.
    >>>
    >>> Have you also read the MSDN documentation about SetConsoleCtrlHandler?
    >>> The last paragraph say:
    >>>
    >>> The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
    >>> CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off,
    >>> or shuts down the system so that the process has an opportunity to clean
    >>> up before termination. Console functions, or any C run-time functions
    >>> that call console functions, may not work reliably during processing of
    >>> any of the three signals mentioned previously. The reason is that some
    >>> or all of the internal console cleanup routines may have been called
    >>> before executing the process signal handler.

    >>
    >> this is the thing I wanted to do but the Win32::API::Callback doesn't
    >> work :-(
    >> But I have a small workaround for now, I wrote a C module where I
    >> register a C-written-callback where I run ExitProcess().
    >> It's dirty to me, because I have no possibility to clean up or do
    >> something else, but, the process really ends on logoff.
    >>
    >> Neverthereless, I still interesting in Win32::API::Callback to get it
    >> work, because it would be very useful feature in Win32 enviroment.
    >>
    >> I tried to write something similars, but how I mentioned above, I've a
    >> problem to call a perl routine from the C-callback, not even the
    >> simplest one from perlcall manpage worked, I got SEGFAULT every time.
    >>
    >> I'm not sure, but could it be a problem calling the call_pv() or call_sv()
    >> from the callback which is launching in another thread ?
    >>
    >> [...]
    >>
    >>> Can you send me the code you are using, maybe I can find it out why the
    >>> Win32::API::Callback Module crashes.

    >>
    >> just a simple define of a callback:
    >>
    >> ----snip---
    >> use Win32::API;
    >> use Win32::API::Callback;
    >>
    >> my $callback = Win32::API::Callback->new(
    >> sub { my($a, $b) = @_; return $a+$b; },
    >> "NN", "N",
    >> );
    >> ----snap---
    >>
    >> gives the SEGFAULT and following message written to the console:
    >> "Free to wrong pool 15e2660 not e58b2660, <DATA> line 164."
    >>

    >
    > As Thomas wrote, the Module is broken. I assume to remove it and install
    > it again. In my environment, Activestate 5.8.8 on XP Sp2, this code
    > works perfect.
    >
    > You can download it from http://www.bribes.org/perl/ppm/ (30-Jan-2007)
    > or Activestate.
    >
    > Here you can find a list of PPM repositories:
    > http://win32.perl.org/wiki/index.php?title=PPM_Repositories
    >


    thanks for the link !
    Module doesn't crash anymore :)
    now I only one step further, but the call I wanted to do fails now
    in calling the callback, here the code:

    ------------------------snip-----------------
    use strict;
    use Win32::API;
    use Win32::API::Callback;

    sub handler {
    my $type = shift;
    print "RECEIVED SIGNAL: $type\n",;
    return 1;
    }

    my $callback =
    Win32::API::Callback->new(\&handler, "I", "I" );
    my $function =
    Win32::API->new('kernel32','SetConsoleCtrlHandler','KI','I');
    $function->Call($callback,1);

    my $i= 0;
    while ($i<2000) {
    print ++$i,"\n";
    sleep(1); # in this loop press Ctrl+C
    }
    -----------------------snap----------------------

    it crashs now not by defining the callback but
    after I press "Ctrl+C" inside the loop :-/

    If I do this in XSUB it seems to work, but only to do ExitProcess(),
    But I'd like to be able to call a callback.

    For comparison here comes my working XS code (with ExitProcess()):

    -----------snip------------------
    #include "EXTERN.h"
    #include "perl.h"
    #include "XSUB.h"
    #include "ppport.h"
    #include "windows.h"
    #include "wincon.h"

    #define MAX_EVENT CTRL_SHUTDOWN_EVENT
    int event[7] = { 0,0,0,0,0,0,0 };

    BOOL WINAPI CtrlHandler(DWORD type) {
    printf("received: %d\n",type);
    if (type > MAX_EVENT)
    return FALSE;
    if (event[type])
    ExitProcess(0);
    return FALSE;
    }

    MODULE = Logoff PACKAGE = Logoff

    int
    LogoffOnEvent(ev, logoff)
    int ev
    int logoff
    CODE:
    int rv;
    if (ev > MAX_EVENT) {
    rv = -1;
    } else {
    event[ev] = logoff;
    rv = SetConsoleCtrlHandler(CtrlHandler,TRUE);
    }
    RETVAL = rv;
    OUTPUT:
    RETVAL
    -----------snap------------------

    to test this module I use this simple piece of perl code:

    -----------snip-----------------
    use Logoff;
    Logoff::LogoffOnEvent(5,1); # quits after Logoff
    Logoff::LogoffOnEvent(0,1); # quits after Ctrl+C

    do {
    print "sleeping...$i\n"; # try to logoff or Ctrl+C
    sleep(1);
    } until $i > 10000;
    ------------snap----------------

    the big disadvantage of this is that I have no possibility to clean up
    my perl code.

    As I wrote before, I tried already to call a perl callback in
    CtrlHandler using call_sv() or call_pv(), without any success,
    this ends every time with segfault calling the perl code,
    the same thing as the perl variant using Win32::API::Callback
    also does (ofcourse after I re-installed the Win32::API-0.46
    module from http://www.bribes.org/perl/ppm/).

    Are there a more restrictions inside a CtrlHandler which disallow to
    do something like call a perl callback ?

    regards
    Peter
     
    Peter Sobisch, Jun 15, 2007
    #10
  11. Lambik <> schrieb:
    > "Peter Sobisch" <> wrote in message
    > news:f4ogqo$uun$...
    >>
    >> Lambik <> schrieb:
    >> >> on Unix its a simplest thing, perl do it for me or I can set $SIG{HUP}

    >:)
    >> >> but, how can I do this in Windows ?
    >> >>
    >> >> Every time I try to shutdown or log off, pop-up is comming up with
    >> >> "application doesn't response" and expecting to kill by clicking a
    >> >> button -> very dirty thing :-/
    >> >>
    >> >> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but

    > no


    >> > You should reveive a WM_CLOSE according to Bill.

    >> not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    >> WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.

    > I hate to state the obvious, but I recon you considered making it a windows
    > program using win32::gui. It has a getMessage
    > http://dada.perl.it/gui_docs/Win32_GUI.html#GetMessage_MIN_MAX_
    >
    > And you could use threads adding a thread which listens to a c program. But
    > I guess you've already done that. There is always the possibility to make
    > your own XS module.
    >
    > #include <windows.h>
    > #include <stdio.h>
    >
    > BOOL CtrlHandler( DWORD fdwCtrlType )
    > {
    > switch( fdwCtrlType )
    > {
    > case CTRL_LOGOFF_EVENT:
    > Beep( 1000, 200 );
    > printf( "Ctrl-Logoff event\n\n" );
    > return FALSE;
    >
    > case CTRL_SHUTDOWN_EVENT:
    > Beep( 750, 500 );
    > printf( "Ctrl-Shutdown event\n\n" );
    > return FALSE;
    >
    > default:
    > return FALSE;
    > }
    > }
    >
    > void main( void )
    > {
    > if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) )
    > {
    > while( 1 ){ }
    > }
    > else
    > printf( "\nERROR: Could not set control handler");
    > }


    thas is easy ! This works for me already inside a XS to do ExitProcess(),
    but my problem is: I'd like to do more than "beep" and "printf".

    Please try to call perl code inside CtrlHandler and tellme how :)
    Actually I expected I can do this using Win32::API::Callback(),
    but I can't get it work :-( See my another posting.

    Regards
    Peter
     
    Peter Sobisch, Jun 15, 2007
    #11
  12. Peter Sobisch

    Lambik Guest

    "Peter Sobisch" <> wrote in message
    news:f4uj73$k0c$...
    > Please try to call perl code inside CtrlHandler and tellme how :)
    > Actually I expected I can do this using Win32::API::Callback(),
    > but I can't get it work :-( See my another posting.


    The other posting seem to have more promise. What i sugested isn't all that
    either.

    use threads;
    my $thread = threads->create(sub { &exitNicely if (`code.exe` =~
    /Ctrl-Shutdown event/)});
     
    Lambik, Jun 15, 2007
    #12
  13. Peter Sobisch wrote:
    > Reinhard Pagitsch <> schrieb:
    >> Peter Sobisch wrote:
    >>> Reinhard Pagitsch <> schrieb:
    >>>>>>> Every time I try to shutdown or log off, pop-up is comming up with
    >>>>>>> "application doesn't response" and expecting to kill by clicking a
    >>>>>>> button -> very dirty thing :-/
    >>>>>>> So, I tried to catch WM_QUERYENDSESSION (using Win32::GUI::Hook), but no
    >>>>>> You should reveive a WM_CLOSE according to Bill.
    >>>>> not really, I'm affraid windows doesn't sent neither WM_CLOSE nor
    >>>>> WM_QUIT because of the same reason of not sending WM_QUERYENDSESSION.
    >>>>
    >>>> Have you also read the MSDN documentation about SetConsoleCtrlHandler?
    >>>> The last paragraph say:
    >>>>
    >>>> The system generates CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
    >>>> CTRL_SHUTDOWN_EVENT signals when the user closes the console, logs off,
    >>>> or shuts down the system so that the process has an opportunity to clean
    >>>> up before termination. Console functions, or any C run-time functions
    >>>> that call console functions, may not work reliably during processing of
    >>>> any of the three signals mentioned previously. The reason is that some
    >>>> or all of the internal console cleanup routines may have been called
    >>>> before executing the process signal handler.
    >>>
    >>> this is the thing I wanted to do but the Win32::API::Callback doesn't
    >>> work :-(
    >>> But I have a small workaround for now, I wrote a C module where I
    >>> register a C-written-callback where I run ExitProcess().
    >>> It's dirty to me, because I have no possibility to clean up or do
    >>> something else, but, the process really ends on logoff.
    >>>
    >>> Neverthereless, I still interesting in Win32::API::Callback to get it
    >>> work, because it would be very useful feature in Win32 enviroment.
    >>>
    >>> I tried to write something similars, but how I mentioned above, I've a
    >>> problem to call a perl routine from the C-callback, not even the
    >>> simplest one from perlcall manpage worked, I got SEGFAULT every time.
    >>>
    >>> I'm not sure, but could it be a problem calling the call_pv() or call_sv()
    >>> from the callback which is launching in another thread ?
    >>>
    >>> [...]
    >>>
    >>>> Can you send me the code you are using, maybe I can find it out why the
    >>>> Win32::API::Callback Module crashes.
    >>>
    >>> just a simple define of a callback:
    >>>
    >>> ----snip---
    >>> use Win32::API;
    >>> use Win32::API::Callback;
    >>>
    >>> my $callback = Win32::API::Callback->new(
    >>> sub { my($a, $b) = @_; return $a+$b; },
    >>> "NN", "N",
    >>> );
    >>> ----snap---
    >>>
    >>> gives the SEGFAULT and following message written to the console:
    >>> "Free to wrong pool 15e2660 not e58b2660, <DATA> line 164."
    >>>

    >>
    >> As Thomas wrote, the Module is broken. I assume to remove it and install
    >> it again. In my environment, Activestate 5.8.8 on XP Sp2, this code
    >> works perfect.
    >>
    >> You can download it from http://www.bribes.org/perl/ppm/ (30-Jan-2007)
    >> or Activestate.
    >>
    >> Here you can find a list of PPM repositories:
    >> http://win32.perl.org/wiki/index.php?title=PPM_Repositories
    >>

    >
    > thanks for the link !
    > Module doesn't crash anymore :)
    > now I only one step further, but the call I wanted to do fails now
    > in calling the callback, here the code:
    >
    > ------------------------snip-----------------
    > use strict;
    > use Win32::API;
    > use Win32::API::Callback;
    >
    > sub handler {
    > my $type = shift;
    > print "RECEIVED SIGNAL: $type\n",;
    > return 1;
    > }
    >
    > my $callback =
    > Win32::API::Callback->new(\&handler, "I", "I" );
    > my $function =
    > Win32::API->new('kernel32','SetConsoleCtrlHandler','KI','I');
    > $function->Call($callback,1);
    >
    > my $i= 0;
    > while ($i<2000) {
    > print ++$i,"\n";
    > sleep(1); # in this loop press Ctrl+C
    > }
    > -----------------------snap----------------------
    >
    > it crashs now not by defining the callback but
    > after I press "Ctrl+C" inside the loop :-/


    Hmm in my case it does not crash but do also nothing. The print in the
    handler sub will not be executed. Could it be that if have to do with
    threads?

    >
    > If I do this in XSUB it seems to work, but only to do ExitProcess(),
    > But I'd like to be able to call a callback.
    >
    > For comparison here comes my working XS code (with ExitProcess()):
    >
    > -----------snip------------------
    > #include "EXTERN.h"
    > #include "perl.h"
    > #include "XSUB.h"
    > #include "ppport.h"
    > #include "windows.h"
    > #include "wincon.h"
    >
    > #define MAX_EVENT CTRL_SHUTDOWN_EVENT
    > int event[7] = { 0,0,0,0,0,0,0 };
    >
    > BOOL WINAPI CtrlHandler(DWORD type) {
    > printf("received: %d\n",type);
    > if (type > MAX_EVENT)
    > return FALSE;
    > if (event[type])
    > ExitProcess(0);
    > return FALSE;
    > }
    >
    > MODULE = Logoff PACKAGE = Logoff
    >
    > int
    > LogoffOnEvent(ev, logoff)
    > int ev
    > int logoff
    > CODE:
    > int rv;
    > if (ev > MAX_EVENT) {
    > rv = -1;
    > } else {
    > event[ev] = logoff;
    > rv = SetConsoleCtrlHandler(CtrlHandler,TRUE);
    > }
    > RETVAL = rv;
    > OUTPUT:
    > RETVAL
    > -----------snap------------------
    >
    > to test this module I use this simple piece of perl code:
    >
    > -----------snip-----------------
    > use Logoff;
    > Logoff::LogoffOnEvent(5,1); # quits after Logoff
    > Logoff::LogoffOnEvent(0,1); # quits after Ctrl+C
    >
    > do {
    > print "sleeping...$i\n"; # try to logoff or Ctrl+C
    > sleep(1);
    > } until $i > 10000;
    > ------------snap----------------
    >
    > the big disadvantage of this is that I have no possibility to clean up
    > my perl code.


    Why not? You call the XS function direct, but if you do it via a .pm
    than you can pass to the method a callback function which have to
    executed before the XS code, theoretical.

    >
    > As I wrote before, I tried already to call a perl callback in
    > CtrlHandler using call_sv() or call_pv(), without any success,
    > this ends every time with segfault calling the perl code,
    > the same thing as the perl variant using Win32::API::Callback
    > also does (ofcourse after I re-installed the Win32::API-0.46
    > module from http://www.bribes.org/perl/ppm/).
    >
    > Are there a more restrictions inside a CtrlHandler which disallow to
    > do something like call a perl callback ?
    >


    regards,
    Reinhard

    --
    PM Mails an rpirpag <at> gmx dot at
     
    Reinhard Pagitsch, Jun 18, 2007
    #13
  14. Reinhard Pagitsch <> schrieb:
    >>> [...]
    >>> http://win32.perl.org/wiki/index.php?title=PPM_Repositories

    >> thanks for the link !
    >> Module doesn't crash anymore :)
    >> now I only one step further, but the call I wanted to do fails now
    >> in calling the callback, here the code:
    >>
    >> ------------------------snip-----------------
    >> use strict;
    >> use Win32::API;
    >> use Win32::API::Callback;
    >>
    >> sub handler {
    >> my $type = shift;
    >> print "RECEIVED SIGNAL: $type\n",;
    >> return 1;
    >> }
    >>
    >> my $callback =
    >> Win32::API::Callback->new(\&handler, "I", "I" );
    >> my $function =
    >> Win32::API->new('kernel32','SetConsoleCtrlHandler','KI','I');
    >> $function->Call($callback,1);
    >>
    >> my $i= 0;
    >> while ($i<2000) {
    >> print ++$i,"\n";
    >> sleep(1); # in this loop press Ctrl+C
    >> }
    >> -----------------------snap----------------------
    >>
    >> it crashs now not by defining the callback but
    >> after I press "Ctrl+C" inside the loop :-/

    >
    > Hmm in my case it does not crash but do also nothing. The print in the
    > handler sub will not be executed. Could it be that if have to do with
    > threads?


    it should at least print the numbers, because it is regular perl code,
    thats strange...

    >> If I do this in XSUB it seems to work, but only to do ExitProcess(),
    >> But I'd like to be able to call a callback.
    >> For comparison here comes my working XS code (with ExitProcess()):
    >>
    >> -----------snip------------------
    >> #include "EXTERN.h"
    >> #include "perl.h"
    >> #include "XSUB.h"
    >> #include "ppport.h"
    >> #include "windows.h"
    >> #include "wincon.h"
    >>
    >> #define MAX_EVENT CTRL_SHUTDOWN_EVENT
    >> int event[7] = { 0,0,0,0,0,0,0 };
    >>
    >> BOOL WINAPI CtrlHandler(DWORD type) {
    >> printf("received: %d\n",type);
    >> if (type > MAX_EVENT)
    >> return FALSE;
    >> if (event[type])
    >> ExitProcess(0);
    >> return FALSE;
    >> }
    >>
    >> MODULE = Logoff PACKAGE = Logoff
    >>
    >> int
    >> LogoffOnEvent(ev, logoff)
    >> int ev
    >> int logoff
    >> CODE:
    >> int rv;
    >> if (ev > MAX_EVENT) {
    >> rv = -1;
    >> } else {
    >> event[ev] = logoff;
    >> rv = SetConsoleCtrlHandler(CtrlHandler,TRUE);
    >> }
    >> RETVAL = rv;
    >> OUTPUT:
    >> RETVAL
    >> -----------snap------------------
    >>
    >> to test this module I use this simple piece of perl code:
    >>
    >> -----------snip-----------------
    >> use Logoff;
    >> Logoff::LogoffOnEvent(5,1); # quits after Logoff
    >> Logoff::LogoffOnEvent(0,1); # quits after Ctrl+C
    >>
    >> do {
    >> print "sleeping...$i\n"; # try to logoff or Ctrl+C
    >> sleep(1);
    >> } until $i > 10000;
    >> ------------snap----------------
    >>
    >> the big disadvantage of this is that I have no possibility to clean up
    >> my perl code.

    >
    > Why not? You call the XS function direct, but if you do it via a .pm
    > than you can pass to the method a callback function which have to
    > executed before the XS code, theoretical.


    the call of Logoff::LogoffOnEvent() is not the problem, this registers only
    a C-routine as a callback, which is called later (on event).
    This doesn't make any difference.

    What I need here is: how to call a perl routine from the CtrlHandler()
    in XS. There are several API calls to do this: (perl_)call_pv,
    (perl_)call_sv and so on. But none of them seems to run in this
    callback.

    Regards,
    Peter
     
    Peter Sobisch, Jun 19, 2007
    #14
  15. Peter Sobisch wrote:
    > Reinhard Pagitsch <> schrieb:
    >>>> [...]
    >>>> http://win32.perl.org/wiki/index.php?title=PPM_Repositories
    >>> thanks for the link !
    >>> Module doesn't crash anymore :)
    >>> now I only one step further, but the call I wanted to do fails now
    >>> in calling the callback, here the code:
    >>>
    >>> ------------------------snip-----------------
    >>> use strict;
    >>> use Win32::API;
    >>> use Win32::API::Callback;
    >>>
    >>> sub handler {
    >>> my $type = shift;
    >>> print "RECEIVED SIGNAL: $type\n",;
    >>> return 1;
    >>> }
    >>>
    >>> my $callback =
    >>> Win32::API::Callback->new(\&handler, "I", "I" );
    >>> my $function =
    >>> Win32::API->new('kernel32','SetConsoleCtrlHandler','KI','I');
    >>> $function->Call($callback,1);
    >>>
    >>> my $i= 0;
    >>> while ($i<2000) {
    >>> print ++$i,"\n";
    >>> sleep(1); # in this loop press Ctrl+C
    >>> }
    >>> -----------------------snap----------------------
    >>>
    >>> it crashs now not by defining the callback but
    >>> after I press "Ctrl+C" inside the loop :-/

    >>
    >> Hmm in my case it does not crash but do also nothing. The print in the
    >> handler sub will not be executed. Could it be that if have to do with
    >> threads?

    >
    > it should at least print the numbers, because it is regular perl code,
    > thats strange...
    >
    >>> If I do this in XSUB it seems to work, but only to do ExitProcess(),
    >>> But I'd like to be able to call a callback.
    >>> For comparison here comes my working XS code (with ExitProcess()):
    >>>
    >>> -----------snip------------------
    >>> #include "EXTERN.h"
    >>> #include "perl.h"
    >>> #include "XSUB.h"
    >>> #include "ppport.h"
    >>> #include "windows.h"
    >>> #include "wincon.h"
    >>>
    >>> #define MAX_EVENT CTRL_SHUTDOWN_EVENT
    >>> int event[7] = { 0,0,0,0,0,0,0 };
    >>>
    >>> BOOL WINAPI CtrlHandler(DWORD type) {
    >>> printf("received: %d\n",type);
    >>> if (type > MAX_EVENT)
    >>> return FALSE;
    >>> if (event[type])
    >>> ExitProcess(0);
    >>> return FALSE;
    >>> }
    >>>
    >>> MODULE = Logoff PACKAGE = Logoff
    >>>
    >>> int
    >>> LogoffOnEvent(ev, logoff)
    >>> int ev
    >>> int logoff
    >>> CODE:
    >>> int rv;
    >>> if (ev > MAX_EVENT) {
    >>> rv = -1;
    >>> } else {
    >>> event[ev] = logoff;
    >>> rv = SetConsoleCtrlHandler(CtrlHandler,TRUE);
    >>> }
    >>> RETVAL = rv;
    >>> OUTPUT:
    >>> RETVAL
    >>> -----------snap------------------
    >>>
    >>> to test this module I use this simple piece of perl code:
    >>>
    >>> -----------snip-----------------
    >>> use Logoff;
    >>> Logoff::LogoffOnEvent(5,1); # quits after Logoff
    >>> Logoff::LogoffOnEvent(0,1); # quits after Ctrl+C
    >>>
    >>> do {
    >>> print "sleeping...$i\n"; # try to logoff or Ctrl+C
    >>> sleep(1);
    >>> } until $i > 10000;
    >>> ------------snap----------------
    >>>
    >>> the big disadvantage of this is that I have no possibility to clean up
    >>> my perl code.

    >>
    >> Why not? You call the XS function direct, but if you do it via a .pm
    >> than you can pass to the method a callback function which have to
    >> executed before the XS code, theoretical.

    >
    > the call of Logoff::LogoffOnEvent() is not the problem, this registers only
    > a C-routine as a callback, which is called later (on event).
    > This doesn't make any difference.
    >
    > What I need here is: how to call a perl routine from the CtrlHandler()
    > in XS. There are several API calls to do this: (perl_)call_pv,
    > (perl_)call_sv and so on. But none of them seems to run in this
    > callback.


    Can you try to ask in perl.xs news group? In the libwin32-0.191 and also
    in Win32-API-0.46 module I can see that call_pv have to work, but I have
    not the time to find out how to make it working in your XS.

    regards,
    Reinhard




    --
    PM Mails an rpirpag <at> gmx dot at
     
    Reinhard Pagitsch, Jun 19, 2007
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dpackwood
    Replies:
    3
    Views:
    1,803
  2. globalrev

    close GUI and quit script?

    globalrev, Apr 20, 2008, in forum: Python
    Replies:
    2
    Views:
    294
    Michael Torrie
    Apr 21, 2008
  3. kk
    Replies:
    6
    Views:
    577
    Hendrik van Rooyen
    Aug 15, 2009
  4. stan
    Replies:
    2
    Views:
    97
    Björn Paetzel
    Apr 25, 2007
  5. Philippe Lang

    Win32 OLE event sink & Quit

    Philippe Lang, Apr 21, 2008, in forum: Ruby
    Replies:
    2
    Views:
    210
    Philippe Lang
    Apr 22, 2008
Loading...

Share This Page