The code that I was using is shown below. The API calls were declared
using Win32::API, Win32::API:

rototype and Win32:

rocess
A portion of the creation routine:
Win32:

rocess->Create ($ProcessObj, "E:\Tools\Hdeperf.exe","", 0,
CREATE_DEFAULT_ERROR_MODE |
CREATE_NEW_CONSOLE |
CREATE_NEW_PROCESS_GROUP, "." );
return($ProcessObj);
Attempting to use GenerateConsoleCtrlEvent():
sub HaltHdPerf
{
my ($Pid) = @_;
my $CTRL_C_EVENT = pack('L',0);
# my $CTRL_C_EVENT = pack('L',1); # ctrl break
my $ProcessID = pack('L',$Pid->GetProcessID());
LogPrint("pid for hdperf = ".$Pid->GetProcessID()."\n");
LogPrint("pid for perl = $$ \n");
LogPrint("Halting HdPerf on pid ".unpack('L',$ProcessID)."\n");
my $Status = GenerateConsoleCtrlEvent($CTRL_C_EVENT, $ProcessID);
my $lasterror = GetLastError();
LogPrint("Status = $Status and last error = $lasterror\n");
}
Output from above code using a ctrl-c event:
pid for hdperf = 3424
pid for perl = 3436
Halting HdPerf on pid 3424
Terminating on signal SIGINT(2)
Status = 1 and last error = 183
Unfortunately it is my program that was terminated.
If I use ctrl break instead of ctrl c I get:
pid for hdperf = 3244
pid for perl = 4064
Halting HdPerf on pid 3244
Terminating on signal SIGINT(2)
And, again, it is my program that terminates. After failing at this, I
tried using SendInput(). This would be my preferred method (as if I had
a choice) since I need to send a ctrl-c to stop the program and then
follow that with a "Y" to actually close the window. The code for using
SendInput() is as follows. It is messier and there are better ways to
do it, but I went for the most simplistic since this was new to me.
sub HaltHdPerf2
{
my ($Pid) = @_;
my $ProcessID = pack('L',$Pid->GetProcessID());
my $CTRL_C_EVENT = pack('L',0);
my $INPUT_KEYBOARD = 1;
my $KEYEVENTF_KEYUP = 2;
my $KEYEVENTF_KEYDOWN = 0;
my $VK_CONTROL = 17;
my $StructSize = 20;
# This is an INPUT struct
Win32::API::Struct->typedef( KBD_INPUT => qw {
DWORD inputType; # 4 bytes
WORD wVK; # 2 bytes start of KEYBDINPUT struct
WORD wScan; # 2 bytes
DWORD dwFlags; # 4 bytes
DWORD dwTime; # 4 bytes
DWORD dwExtraInfo; # 4 bytes end of KEYBDINPUT
struct
} ); # total = 20 bytes
LogPrint("size of DWORD = ".Win32::API::Type->sizeof('DWORD')." and
size of WORD = ".Win32::API::Type->sizeof('WORD')."\n");
# Create a structure for SendInput
my $kbdInput = Win32::API::Struct->new ( 'KBD_INPUT' );
$kbdInput->{inputType} = $INPUT_KEYBOARD;
$kbdInput->{wVK} = $VK_CONTROL;
$kbdInput->{wScan} = 0;
$kbdInput->{dwFlags} = $KEYEVENTF_KEYDOWN;
$kbdInput->{dwTime} = time();
$kbdInput->{dwExtraInfo} = 0;
# Use the topmost window as a starting point
my $hWnd = GetTopWindow( 0 );
my $CharSize = 1 + Win32::API::IsUnicode();
# Cycle thru each window and find the one with the desired string in
the title
do {
# Allocate a buffer for the window title and set it to all null
characters
my $Size = ( GetWindowTextLength( $hWnd ) + 1 ) * $CharSize;
my $Buff = "\x0" x $Size;
# Get the window's title and get rid of any remaining null characters
from above
GetWindowText( $hWnd, $Buff, $Size );
$Buff =~ s/\x0//g;
# If the title matches then send crtl-c to the window
if( $Buff =~ m/WINDOWS\\system32\\cmd.exe/i ) {
LogPrint("HdPerf window found\n");
# Bring this window into focus
SetForegroundWindow($hWnd);
LogPrint("Sending ctrl-c command to HdPerf\n");
# Press ctrl key
my $InsertedEvents = SendInput(pack('I',1), $kbdInput,
pack('i',$StructSize));
LogPrint("InsertedEvents = $InsertedEvents\n");
# Press 'c' key
$kbdInput->{wVK} = 'c';
$InsertedEvents = SendInput(pack('I',1), $kbdInput,
pack('i',$StructSize));
LogPrint("InsertedEvents = $InsertedEvents\n");
# Release 'c' key
$kbdInput->{dwFlags} = $KEYEVENTF_KEYUP;
$InsertedEvents = SendInput(pack('I',1), $kbdInput,
pack('i',$StructSize));
LogPrint("InsertedEvents = $InsertedEvents\n");
# Release ctrl key
$kbdInput->{wVK} = $VK_CONTROL;
$InsertedEvents = SendInput(pack('I',1), $kbdInput,
pack('i',$StructSize));
LogPrint("InsertedEvents = $InsertedEvents\n");
}
}
while( $hWnd = GetWindow( $hWnd, 0x02 ) ); # get the next window
LogPrint("All done\n");
}
}
Output from the above code:
size of DWORD = 4 and size of WORD = 2
HdPerf window found
Sending ctrl-c command to HdPerf
InsertedEvents = 0
InsertedEvents = 0
InsertedEvents = 0
InsertedEvents = 0
All done