I would like to program my mIRC bot so every time someone writes "W" in the chat, the bot simulates the W key on my keyboard.
I have tried:
on *:text:W:#:sendkeys {W}
alias sendkeys var %a = $ticks
.comopen %a WScript.Shell | if !$comerr {
.comclose %a $com(%a,SendKeys,3,bstr,$1-)
}
This doesn't seem to be working. Any advice?
The code is fine, the blocks in which you execute that code are incorrect. Due to a lack of brackets, your alias will only execute the var command, and be done after that.
Taken from the mIRC help files:
The { } brackets: You can create multi-line scripts by using the { } brackets. This allows you to create an alias which performs several commands.
alias sendkeys {
var %a = $ticks
.comopen %a WScript.Shell
if !$comerr {
.comclose %a $com(%a,SendKeys,3,bstr,$1-)
}
}
Related
trying to create a macro program with expect to help me manage my cisco devices>
I want to keep all native cisco functions like tab complete ETC.
initially I wanted to type "!...!" where my macro is inside the bangs, my code looked like this:
interact {
-re "!(.+)!" { #find correct macro }
}
but with this method, there is no feedback to the user. what happens if they misspell? etc then they can't see their corrections with backspace.
then I started thinking about just capturing each character press and building a string
interact {
#book says backspace character
"\b" {
set command [lreplace $command end end]
}
#detect return, sending command
-re "\r" {
set command [join $command ""]
if [regexp "^!" $command] {
#send ctrl+u to erase line sent
send "\025"
findMacro $command
}
set command ""
send "\r"
}
#send tab for tab completion
"\t" { send "\t" }
-re "(.)" {
send $interact_out(1,string)
lappend command $interact_out(1,string)
}
}
but I can't "expect" the backspace. I've tried 0x08.. etc nothing is working. in the end I'm not even sure this is the way to go simply because there are to many other buttons a user could push and mess up my string I'm building.
the real solution, I think, is to wait until "\r" is pressed, and then run a regex on that line. but I'm not sure how to do that.
I've got a script that's chewing through a lot of objects, and sometimes I want to kill it in the middle of the run because I see something going south. Unfortunately, I'm writing to a log file using System.IO.StreamWriter, and whenever I send a Ctrl-C, my log files are stuck open.
Is there any way I can define some kind of handler or exiting function that allows me to gracefully close filehandles and connections that I have open?
Might try using Try/Catch/Finally, putting your close() commands in the Finally block.
With PowerShell 2.0 and up, you can define a Trap which will fire when a terminating error occurs. You can define multiple traps to capture different exceptions. This could result in much cleaner code than try/catch littered everywhere, or wrapping the entire script in one big try/catch.
To terminate a script, use exit .If an exception is thrown, use try/catch/finally with close() commands in finally. If it's just an if-test, try something like this:
function Close-Script {
#If stream1 is created
if($stream1) {
$stream1.Close()
}
#Terminate script
exit
}
$stream1 = New-Object System.IO.StreamWriter filename.txt
If(a test that detects your error) {
Close-Script
}
If the amounts of streamwriters varies from time to time, you can collect them to an array and close them. Ex:
function Close-Script {
#Close streams
$writers | % { $_.Close() }
#Terminate script
exit
}
$writers = #()
$stream1 = New-Object System.IO.StreamWriter filename.txt
$writers += $stream1
$stream2 = New-Object System.IO.StreamWriter filename2.txt
$writers += $stream2
If(a test that detects your error) {
Close-Script
}
I am trying to implement RSpec/Jasmine like BDD framework in Powershell (or at least research the potential problems with making one).
Currently I am having problems with implementing simple before/after functionality. Given
$ErrorActionPreference = "Stop"
function describe()
{
$aaaa = 0;
before { $aaaa = 2; };
after { $aaaa; }
}
function before( [scriptblock]$sb )
{
& $sb
}
function after( $sb )
{
& $sb
}
describe
the output is 0, but I would like it to be 2. Is there any way to achieve it in Powershell (short of making $aaaa global, traversing parent scopes in script blocks till $aaaa is found, making $aaaa an "object" and other dirty hacks:) )
What I would ideally like is a way to invoke a script block in some other scope but I don't have a clue whether it is possible at all. I found an interesting example at https://connect.microsoft.com/PowerShell/feedback/details/560504/scriptblock-gets-incorrect-parent-scope-in-module (see workaround), but am not sure how it works and if it helps me in any way.
TIA
The call operator (&) always uses a new scope. Instead, use the dot source (.) operator:
$ErrorActionPreference = "Stop"
function describe()
{
$aaaa = 0;
. before { $aaaa = 2; };
. after { $aaaa; }
}
function before( [scriptblock]$sb )
{
. $sb
}
function after( $sb )
{
. $sb
}
describe
Note the use of . function to invoke the function in same scope as where `$aaaa is defined.
I realize the title is a little confusing but I couldn't figure out a better way to phrase it.
I have a Powershell script with a couple dozen functions. Currently, I have the exact same code in every function to format the output. Here's a snippet:
function function1 () {
do something...
output code here
}
function function2 () {
do something...
output code here
}
The output code is exactly the same. Being a fan of code deduplication, this is driving me crazy because every time I add a new function I have this template code that I have to apply. I've tried putting the entire script in a try/catch block and throwing the object that is output but I couldn't get it to work and this still requires coding in the same throw statement in every function.
Does anyone know of something I can do to have all of these functions in this script to automatically send their output to another function or am I just going to have to live with this?
If the functions have no parameters, you can use this simple solution:
function addOutputCode {
param($name)
$oldBody = (get-item function:$name).ScriptBlock
$newBody = {
param($computer)
$funcOutput = . $oldBody $computer
# some formatting
$funcOutput | % { 'FORMATTED: ' + $_ }
}.GetNewClosure()
Set-Item function:$name -value $newBody
}
As you can see the functions gets the body of the function and assignes new body with formatting code. You can try it, just copy & paste the code below.
# this is your file with defined functions
function f1 { param($c) 'this is test of ' + $c }
function f2 { $c.Length; 'this was length of $c' }
# now f1 and f2 would return unformatted data
# f1
# f2
# add formatting code
addOutputCode f1
addOutputCode f2
# now if you call f1 or f2, they return formatted data
# f1 comp1
# f2 comp2
I want to type directly into the Powershell prompt too, not pipe in a text file.
Foo`r doesn't work for me. For example:
echo "RJ`r`n" | .\nc.exe -u 192.168.1.247 2639
but what I'd really like to do is just
.\nc.exe -u 192.168.1.247 2639
then start typing into the prompt.
Try:
"Foo`ndoes work for me"
If you need a full CRLF sequence then:
"Foo`r`ndoes work for me"
Note that the escapes chars only work in double-quoted strings - not single quoted strings.
Update: Redirect in < is not supported in PowerShell at this time so you can only get stdin to the exe from the interactive prompt using the pipeline. Is it possible nc.exe is expecting another character (or escape char) to terminate the input? I know that console exes can receive stdin from PowerShell. If you have the C# compiler, you can see this by compiling the following source (csc echostdin.cs):
using System;
public class App
{
public static void Main()
{
int ch;
while ((ch = Console.In.Read()) != -1)
{
Console.Write((char)ch);
}
}
}
Then execute the exe:
PS> "foo`r`n" | .\echostdin.exe
foo
PS>