Autoit - Get Window Class by PID - class

I want Autoit to press a certain key on a program, but the programs window has no title and changes its class everytime I start it. The only thing that stays consistently the same is the process name.
So my question is simply: How do I get a Windows Class by using only the PID?

Does this help?
#include <Array.au3>
#include <WinAPI.au3>
Opt("WinDetectHiddenText", 1) ;0=don't detect, 1=do detect
Opt("WinSearchChildren", 1) ;0=no, 1=search children also
Opt("WinTextMatchMode", 2) ;1=complete, 2=quick
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
$a = ProcessGetId('firefox.exe')
For $i = 1 To UBound($a) - 1
ConsoleWrite(ProcessGetWindow($a[$i]) & #CRLF)
Next
Func ProcessGetWindow($PId)
If IsNumber($PId) = 0 Or ProcessExists(ProcessGetName($PId)) = 0 Then
SetError(1)
Else
Local $WinList = WinList()
Local $i = 1
Local $WindowTitle = ""
While $i <= $WinList[0][0] And $WindowTitle = ""
If WinGetProcess($WinList[$i][0], "") = $PId Then
$WindowTitle = $WinList[$i][0]
Else
$i += 1
EndIf
WEnd
Return $WindowTitle
EndIf
EndFunc ;==>ProcessGetWindow
Func ProcessGetId($Process)
If IsString($Process) = 0 Then
SetError(2)
ElseIf ProcessExists($Process) = 0 Then
SetError(1)
Else
Local $PList = ProcessList($Process)
Local $i
Local $PId[$PList[0][0] + 1]
$PId[0] = $PList[0][0]
For $i = 1 To $PList[0][0]
$PId[$i] = $PList[$i][1]
Next
Return $PId
EndIf
EndFunc ;==>ProcessGetId
Func ProcessGetName($PId)
If IsNumber($PId) = 0 Then
SetError(2)
ElseIf $PId > 9999 Then
SetError(1)
Else
Local $PList = ProcessList()
Local $i = 1
Local $ProcessName = ""
While $i <= $PList[0][0] And $ProcessName = ""
If $PList[$i][1] = $PId Then
$ProcessName = $PList[$i][0]
Else
$i = $i + 1
EndIf
WEnd
Return $ProcessName
EndIf
EndFunc ;==>ProcessGetName

Related

Converting C++ to PowerShell

I had an assignment for which I need to list the first 100 Prime Numbers in PowerShell Script. So I coded using C++ and try to convert to PowerShell Script. And the output in PowerShell was not what I am expected.
Note: I am new to PowerShell. Just start learning since past 2 days
I tried to understand the PowerShell syntax and convert it
C++:
int i, j, count = 1, b = 0;
for ( i = 3; i > 0; ++i )
{
for ( j = 2; j <= i / 2; ++j )
{
if ( i % j == 0 )
{
b = 1;
break;
}
}
if ( b == 0 )
{
cout << i << endl;
count++;
}
b = 0;
if ( count == 101 )
break;
}
PowerShell:
$i
$j
$count = 0
$prime = 0
for ( $i = 3; $i -lt 0; ++$i )
{
for ( $j = 2; $j -le $i / 2; ++$j )
{
if ( $i % $j -eq 0 )
{
$prime = 1
break
}
}
if ( $prime -eq 0 )
{
Write-Host("$i 'r 'n")
$count++
}
$prime = 0
if ( $count -eq 101 )
{
break
}
}
I expect the result will be first 100 prime numbers from 3 to 547
But I get 3 2 from PowerShell.
Any advice is welcomed. Thank you in advance
You were close.
> is -gt, you used -lt in your script.
$i = 0
$j = 0
$count = 0
$prime = 0
for ($i = 3; $i -gt 0; ++$i) {
for ($j = 2; $j -le $i / 2; ++$j) {
if ($i % $j -eq 0 ) {
$prime = 1
break
}
}
if ($prime -eq 0) {
Write-Output $i
$count++
}
$prime = 0
if ($count -eq 100) {
break
}
}

Is there a way to center text in PowerShell

How can we center text in PowerShell? WindowWidth doesn't exist apparently, so is there a way somehow to keep the text centered?
We want this output :
*
***
*****
*******
So I wrote
for ($i=1; $i -le 7; $i+=2)
{
write-host("*" * $i)
}
But we get
*
***
*****
*******
function Write-HostCenter { param($Message) Write-Host ("{0}{1}" -f (' ' * (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Floor($Message.Length / 2)))), $Message) }
Write-HostCenter '*'
Write-HostCenter '***'
Write-HostCenter '*****'
I had a bit of fun and wrote some code based on this, that makes a box and center the text inside.
Im sure someone can make a cleaner version, but this do the job just fine :)
# ----------------------------------------------------------------------------------
#
# Script functions
#
# ----------------------------------------------------------------------------------
function MakeTopAndButtom
{
$string = "# "
for($i = 0; $i -lt $Host.UI.RawUI.BufferSize.Width - 4; $i++)
{
$string = $string + "-"
}
$string = $string + " #"
return $string
}
function MakeSpaces
{
$string = "# "
for($i = 0; $i -lt $Host.UI.RawUI.BufferSize.Width - 4; $i++)
{
$string = $string + " "
}
$string = $string + " #"
return $string
}
function CenterText
{
param($Message)
$string = "# "
for($i = 0; $i -lt (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Max(0, $Message.Length / 2))) - 4; $i++)
{
$string = $string + " "
}
$string = $string + $Message
for($i = 0; $i -lt ($Host.UI.RawUI.BufferSize.Width - ((([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Max(0, $Message.Length / 2))) - 2 + $Message.Length)) - 2; $i++)
{
$string = $string + " "
}
$string = $string + " #"
return $string
}
function LinesOfCodeInCorrentFolder
{
return (gci -include *.ps1 -recurse | select-string .).Count
}
$MakeTopAndButtom = MakeTopAndButtom
$MakeSpaces = MakeSpaces
$lines = LinesOfCodeInCorrentFolder
# ----------------------------------------------------------------------------------
#
# Run
#
# ----------------------------------------------------------------------------------
$MakeTopAndButtom
$MakeSpaces
$MakeSpaces
$MakeSpaces
$MakeSpaces
CenterText "Lines of .ps1 code in this folder: $($lines)"
CenterText "Press any key to exit"
$MakeSpaces
$MakeSpaces
$MakeSpaces
$MakeSpaces
$MakeTopAndButtom
Read-Host
This gives an output like this:
# ---------------------------------------------------------------------------------------- #
# #
# #
# #
# #
# Lines of .ps1 code in this folder: 6524 #
# Press any key to exit #
# #
# #
# #
# #
# ---------------------------------------------------------------------------------------- #
You can calculate the spaces you need to add and then include them as follows:
$Width = 3
for ($i=1; $i -le 7; $i+=2)
{
Write-Host (' ' * ($width - [math]::floor($i / 2))) ('*' * $i)
}

switch - multiple variables

I'm trying to create a script which will work assign different IP ranges depending on the choice, currently I've done something like this:
# Get DHCP Scope Start - first IP to check - End Last IP to check
$X = 0
$Y = 0
$Z = 0
$End = 0
$DHCPServer = "DHCP"
$ScopeID = "10.0.0.0"
switch (Read-Host "Choose device to add: 1 PS3,2 PS4,3 PS4Pro,4 XboxOne,") {
1 {$z = 1 $End = 20}
2 {$z = 30 $End = 50}
3 {$z = 100 $End = 255}
4 {$y = 1 $z = 1 $end = 100}
}
But no matter how I type arguments, PowerShell always return the errors like
Unexpected token $end in expression or statement
Is there a way to fix it?
Adding some semicolons should do the trick. Alternatively, you could use new lines.
# Get DHCP Scope Start - first IP to check - End Last IP to check
$X = 0
$Y = 0
$Z = 0
$End = 0
$DHCPServer = "DHCP"
$ScopeID = "10.0.0.0"
switch (Read-Host "Choose device to add: 1 PS3,2 PS4,3 PS4Pro,4 XboxOne,") {
1 {$z = 1; $End = 20}
2 {$z = 30; $End = 50}
3 {$z = 100; $End = 255}
4 {$y = 1; $z = 1; $end = 100}
}

modify this code to print elements that differ a x number from previous position

I wrote this code to find substrings every x elements:
print "enter file path\n";
$letters = <>;
chomp ($letters);
$sequence = "";
open (LETTERS, $letters) or die "error opening\n";
print "how many letters at a shot\n";
$number = <>;
chomp ($number);
$size = length $sequence;
chomp ($size);
for ($i = 0; $i < $size; $i++) {
$test = substr ($sequence, $i, $number);
print "> Test $i\n";
print "$test\n";
if ($i >= $size - $number) {
last;
}
}
so if I open a file with this string and choose x = 3:
abcdefg
I get this result:
> Test 0 abc
> Test 1 bcd
> Test 2 cde
> Test 3 def
> Test 4 efg
Each substring differs from one position from the previous substring, I'd like to be able to control this number and dislocate the substring by 2 for example. So the result would be:
> Test 0 abc
> Test 2 cde
> Test 4 efg
Any suggestions? Thanks
Add:
...
$step = <>;
...
And change:
for ($i = 0; $i < $size; $i++) {
to
for ($i = 0; $i < $size; $i+=$step) {
for ($i = 0; $i < $size; $i += 2) {

Collatz Conjecture - Iteration rather than Recursion

I am working on something for learning purposes where I have tackled Collatz using recursion. If you see below I make use of #_ and $_ to keep the for alive.
#!/usr/bin/env perl
sub collatz {
my ($num, $count) = #_;
$count++;
if ($num == 1) {
return $count;
} elsif ($num % 2 == 0) {
return collatz($num/2, $count);
} else {
return collatz($num*3 + 1, $count);
}
}
my $max = 0;
my $saved = 0;
for (1..1000) {
my $length = collatz($_, 0);
print "Num: " . $_ . " Length: " . $length . "\n";
if ($length > $max) {
$max = $length;
$saved = $_;
}
}
print "The longest sequence starts with " . $saved . "\n";
I am trying to use iteration instead of recursion but I just can't think of how to tackle this. I am not after the code in the question, I just want some tips / hints on how to tackle this to get the same result.
I suspect I will need to use a while or an until field.
Any help would be appreciated, again I don't want the exact answer.
Update
Here is my second attempt, which is giving me an error of
Can't return outside a subroutine at answer2.pl line 38.
my $number = 0;
my $counter = 0;
while ($number != 1000) {
$counter++;
if ($number == 1) {
return $counter;
}
elsif ($number % 2 == 0) {
return ($number / 2, $counter);
}
else {
return ($number * 3 + 1, $counter);
}
$number++;
}
print "number" . $number . "counter" . $counter . "\n";
Basically you have tail recursion, which is nice and simple to eliminate.
Instead of collatz calling itself to generate the next step in the sequence, you simply change the variables in-place and loop back to the top.
In its crudest form this would be
sub collatz2 {
my ($num, $count) = #_;
NEXT:
$count++;
if ($num == 1) {
return $count;
}
elsif ($num % 2 == 0) {
$num = $num / 2;
}
else {
$num = $num * 3 + 1;
}
goto NEXT;
}
but it should be written much more nicely than that.
I ended up with this
sub collatz {
my ($num) = #_;
my $count = 1;
while ($num > 1) {
$num = $num % 2 ? $num * 3 + 1 : $num / 2;
++$count;
}
$count;
}
Consider adding the logic that returns when the condition is met in the while.
Spoiler:
my $iter = 0;
while($num != 1){ #do stuff; $iter++ }
Just use a for or while loop with the end condition that your number == 1.
Spoiler:
use strict;
use warnings;
my $max_num = 0;
my $max_steps = 0;
for my $num (1..1000) {
my $steps = 0;
for (my $i = $num; $i != 1; $steps++) {
$i = $i % 2 ? 3 * $i + 1 : $i / 2;
}
print "Num: " . $num . " Length: " . $steps . "\n";
if ($steps > $max_steps) {
$max_num = $num;
$max_steps = $steps;
}
}
print "The longest sequence starts with " . $max_num . "\n";