Is there a way that I can imitate the pressing of a function key (F1-F12) from a Perl script on Windows 7?
I have a program that requires F7 to be pressed in order to stop it.
I have tried killing the program process, but that doesn't stop the process cleanly.
If you're on Windows, Win32::GuiTest can do what you want. They have several examples of using SendKeys to press function keys.
On Unix the situation is both easier and harder. Function keys are usually mapped in a terminal to send several characters. You can find out what they are using ord and sprintf to get their hex values (easier to work with). Here's an example of "kj" as a simple example, then F1 through F7.
$ perl -wle 'while(<>) { chomp; print join ", ", map { sprintf "%x", ord } split //, $_ }'
kj
6b, 6a
^[OP
1b, 4f, 50
^[OQ
1b, 4f, 51
^[OR
1b, 4f, 52
^[OS
1b, 4f, 53
^[[15~
1b, 5b, 31, 35, 7e
^[[17~
1b, 5b, 31, 37, 7e
^[[18~
1b, 5b, 31, 38, 7e
^[[19~
1b, 5b, 31, 39, 7e
ASCII 1b is the escape character (represented on the terminal by a ^[). 5b is [, and so on. So you can print those strings to the program's input or to the tty. For example, F8 would be "\x{1b}[19~".
Why are F1-F4 different? The VT100 terminal, upon which this is all based, only had four function keys. The later VT220 added the rest.
There's probably a module to take care of this for you, but I can't find it.
Related
Hi I was wondering if yall could help me figure this error out. Im rather new to cobol as it is my first (and only) cobol class in my major.
I keep getting this error lab3a.cob:23: Error: syntax error, unexpected "Identifier", expecting EXTERNAL or GLOBAL
whenever I try to compile. And I cant seem to see what I'm doing wrong.
My Code
IDENTIFICATION DIVISION.
PROGRAM-ID. "LAB3A".
Author. Fielding Featherston
* Takes inputs from file and seperates.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT InFile
ASSIGN to "lab3-in.dat"
ORGANIZATION is LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD InFile.
01 InString.
05 PIC X(13).
05 Instrument PIC X(12).
88 Brass value "Bugle" "Flugelhorn"
"Sousaphone" "Trombone"
"Trumpet" "Tuba".
88 Percussion value "Bass Drum" "Bells" "Bongos"
"Castanets" "Chimes" "Cymbals"
"Snare Drum" "Xylophone".
88 Strings value "Banjo" "Bass" "Cello" "Guitar"
"Harp" "Lyre"
"Mandolin" "Violin".
88 Woodwind value "Bagpipes" "Bassoon" "Clarinet"
"Flute" "Oboe"
"Piccolo" "Saxophone".
WORKING-STORAGE SECTION.
01 BrassCount PIC 9(3).
01 PerCount PIC 9(3).
01 StringCount PIC 9(3).
01 WoodCount PIC 9(3).
01 OtherCount PIC 9(3).
01 BrassStr PIC ZZ9.
01 PerStr PIC ZZ9.
01 StringStr PIC ZZ9.
01 WoodStr PIC ZZ9.
01 OtherStr PIC ZZ9.
01 InStringLength PIC 99.
01 EndFileStr PIC X VALUE "n".
88 EndFile VALUE "y"
When Set to False is "y".
PROCEDURE DIVISION.
000-Main.
Open Input InFile
Perform until EndFile
Read InFile
At end
Set EndFile to FALSE
Not at End
PERFORM 100-SeperateStrings
PERFORM 200-ClassCount
END-READ
END-PERFORM
CLOSE InFile
Move BrassCount to BrassStr
Move PerCount to PerStr
Move StringCount to StringStr
Move WoodCount to WoodStr
Move OtherCount to OtherStr
DISPLAY "Counts"
DISPLAY " Brass: " FUNCTION TRIM(BrassStr)
DISPLAY " Percussion: " FUNCTION TRIM(PerStr)
DISPLAY " String: " FUNCTION TRIM(StringStr)
DISPLAY " Woodwind: " FUNCTION TRIM(WoodStr)
DISPLAY " OTHER: " FUNCTION TRIM(OtherStr)
STOP RUN.
100-SeperateStrings.
MOVE FUNCTION Length(InString) to InStringLength
UNSTRING InString (14:InStringLength)
INTO Instrument
END-UNSTRING.
200-ClassCount.
IF Brass
Add 1 to BrassCount
ELSE IF Percussion
Add 1 to PerCount
ELSE IF Strings
Add 1 to StringCount
ELSE IF Woodwind
Add 1 to WoodCount
ELSE
Add 1 to OtherCount
END-IF.
An EXTERNAL or GLOBAL clause in the context of the error may only occur in a record description entry; that is, a data entry that begins with 1 or 01. Given that the error occurs between two 88 level items, it appears the compiler is confused about where it is while scanning the source code.
There is some unusual formatting that may be creating a problem with an the compiler. In particular, line 22 contains a number of TAB characters that should not, but may, confuse the compiler. Also, lines 33 and 46 contain a number of TAB characters at the end of each source line causing the lines to exceed 72 characters.
Another possible issue is expansion of tabs, whether each TAB character is replaced by 4 or 8 spaces by the compiler. Again this will affect whether the text exceeds 72 characters. In the absence of a SOURCE FORMAT directive, source text after column 72 is ignored.
Until you know the effect that tabs have on the source code, I suggest replacing all tabs with spaces.
I have a log file summarising calculation results that I need to prepare for analysis. Each result is given a heading, of the form:
Excited State 1: Triplet-A 3.1118 eV 398.43 nm f=0.0000"
Followed by an unknown number of data lines of the form:
"76 -> 81 0.36917"
(an integer, an arrow, another integer, then a float). Each result is separated from the next result by a blank line. I want to be able to take the first two sets (including the data lines) of results where the heading contains the pattern "Triplet". Later, I need to be able to do the same for the "Singlet" pattern, so I can't just delete those.
Unfortunately, it is important for later analysis that the data lines be kept separated in some way, as I will need to order the data lines in decreasing order of magnitude (by the float column).
I have been able to use sed to return all instances of the Triplet headings and following data lines (until the blank line), as follows:
sed -n '/Triplet/,/^ *$/p' test.txt
But I don't know how to get only the first two instances.
Ideally, if the input file looks like the following:
Excited State 1: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
Excited State 2: Singlet-A 3.3656 eV 379.43 nm f=0.0029
76 -> 81 0.38068
76 ->101 0.10777
...
Excited State 3: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
...
I'd like to be able to get:
Excited State 1: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
Excited State 3: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
And while, in this case, I could just remove the second data set, that won't generalise.
$ awk '/Triplet/ { n += 1 } n <= 2 && /Triplet/,/^ *$/' input.txt
Excited State 1: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
Excited State 3: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
...
A gnu awk version (gnu due to RS with multiple characters)
awk -v RS='Excited State' '/Triplet/ {if (n++<2) printf "%s",RS$0}' file
Excited State 1: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
Excited State 3: Triplet-A 3.1118 eV 398.43 nm f=0.0000
76 -> 81 0.36917
76 ->101 0.11911
...
...
RS='Excited State' set record selector to Excited State so awk works in block mode
/Triplet/ test if line contains Triplet if so:
if (n++<2) test if counter is less then two starting by zero to get two block only, then:
print RS$0 print record selector and block
PS this will work even if blank line is missing between blocks
This might work for you (GNU sed):
sed -E '/Triplet/{x;s/^/x/;/^x{1,2}$/{x;:a;n;/\S/ba;p;x};x};d' file
Focus on a line containing Triplet and after incrementing a counter in the hold space, determine if to print that line upto and including an empty one.
If you have blank lines between all records, then it is easy to do the following:
$ awk 'BEGIN{RS="";FS=OFS="\n";n=2}($1~/Triplet/ && n-->0);(n==0){exit}' file
I'm currently using software called LineView. It generates downtime reason codes for our factory lines. An operator scans the barcodes with an RS232 scanner and it goes into our XL board system.
The software itself generates the barcodes within an internet browser, but I am trying to make it so our own labeling machine can also print out the barcodes. However, the barcodes that are produced by the labeler (and the many online barcode generators I've tried) look longer and do not work.
The data for the example 128 barcode that I am trying to replicate is [SOH]1[STX]65;1067[ETX].
According to the manual:
- The Start of Header character (ASCII 0x01) starts the XL Command packet.
1 - The Serial Address of the XL device (the default is 1).
- The Start of Transmission character (ASCII 0x02) marks the start of the actual command.
65; - The ID of the Production State > Set Reason Code command.
The Reason Code ID (which can range from 1 to 999 for system reasons or 1000 to 1999 for user defined reasons). In my case it is 1067
- The End of Transmission character (ASCII 0x03) ends the XL Command packet.
I have attatched the pictures of what LineView produces (which is what I want it to look like) and what it is currently printing like on our labeller.
When I scan them they both come up with the [SOH]1[STX]65;1067[ETX] code despite them looking different.
Any help with this would be very much appreciated.
Your intended barcode is constructed internally using the following series of Code 128 codewords which correctly represent the ASCII control characters:
103 Start-in-Mode-A (Upper-case and control characters)
65 [SOH] (ASCII 1)
17 1
66 [STX] (ASCII 2)
22 6
21 5
27 ;
99 Switch-to-Mode-C (Double-density numeric)
10 10
67 67
101 Switch-to-Mode-A
67 [ETX] (ASCII 3)
67 Check-digit
106 Stop
Your label printer is printing a barcode representing the literal string [SOH]1[STX]65;1067[ETX] with no ASCII control characters (i.e. left-bracket, S, O, H, right-bracket, ...) using the following internal codewords:
104 Start-in-Mode-B (Mixed-case)
59 [
51 S
47 O
40 H
61 ]
17 1
59 [
51 S
52 T
56 X
61 ]
22 6
21 5
27 ;
99 Switch-to-Mode-C (Double-density numeric)
10 10
67 67
100 Switch-to-Mode-B
59 [
37 E
52 T
56 X
61 ]
57 Check-digit
106 Stop
So you need to work out how to correctly specify ASCII control characters in the input to your labelling machine.
I have an old VB executable that has been used for a long time in my project.
The current implementation of the application contains a debug window that's
not needed any more.
Of course, the source code was lost and can not be modified.
My idea is to modify the HEX code of the instance that's opening the annoying debug window.
For that purpose, I use VB Decompiler by DotFix software, and I suppose that I found the code responsible for that instance. Unfortunately, I can't understand how it works.
Let's see the disassemble code:
loc_8F420C: var_8A = 0
loc_8F4219: If (Len(var_88) = &H30) Then
loc_8F4225: Call {3014B1BF-8A2C-23D7-B50400C24F280C20}.Method_arg_12 (var_88)
loc_8F4233: Call {3014B1BF-8A2C-23D7-B50400C24F280C20}.Method_arg_16 (var_108)
loc_8F423D: If CBool(var_108) Then
loc_8F424D: Me.Global.Unload Me
loc_8F4258: Else
loc_8F425A: var_8A = &HFF
...
loc_8F43B0: End If
loc_8F43B3: Else
At the first sight var_108 seems a bool variable that is the one setting the debug window. Can I implicitly put in loc_8F423D: If CBool(false/true) Then to stop this window from launching?
Can anyone explain to me what are those Call {#######-####-####-################}.Method_arg_## from above?
PEiD detect compiler:
Microsoft Visual Basic 5.0 / 6.0 [Overlay]
Part 2:
It took me a long time to get the new idea - the right one, possibly. Let's take a look at the assembly code:
004F420C: 70 FStI2 var_8A <- loc_8F420C: var_8A = 0
Looks like loc_8F4219: If (Len(var_88) = &H30) Then
004F420F: 6C ILdRf var_88
004F4212: 4A FnLenStr Len()
004F4213: F5 LitI4: 48 (0x30)
Let's find the next code snippets:
004F4218: C7 EqI4 =
004F4219: 1C BranchF 004F43B3
Our Call methods looks like :
004F421C: 6C ILdRf var_88 < - (var_88) from Call
004F421F: 22 ImpAdLdPr
004F4222: 58 MemLdPr
004F4225: 0D VCallHresult var_88.vtable[12] <- Method_arg_12
004F422A: 04 FLdRfVar var_108 <- (var_108) possible CALL/BACK
004F422D: 22 ImpAdLdPr
004F4230: 58 MemLdPr
004F4233: 0D VCallHresult var_108.vtable[16] <- Method_arg_16
004F4238: 6C ILdRf var_108 <- (var_108) 70% sure is RESPONSE(true/false)
And now the most interesting parts of that annoying P-Code&Assembly, we find the if instance that verifies if the Debug Windows is needed. If we look at P-Code we can see that if has the form:
loc_8F423D: If CBool(var_108) Then
loc_8F424D: Me.Global.Unload Me
loc_8F4258: Else
loc_8F425A: var_8A = &HFF
And now look at the Address - if is true execute address 00F424D / 8F424D else jump outside to 004F4258
004F423B: FC52 CBoolI4
004F423D: 1C BranchF 004F4258
004F4240: 6C ILdRf param_8
004F4243: FD9C FStAdNoPop
004F4247: 05 ImpAdLdRf
004F424A: 24 NewIfNullPr GLOBAL
004F424D: 0D VCallHresult Global._Unload(object As IDispatch)
004F4252: 1A FFree1Ad var_90
004F4255: 1E Branch 004F43B0
004F4258: loc_004F423D
004F4258: F4 LitI2_Byte: 255 (True)
Possibly, if I change the 004F423D: 1C BranchF 004F4258 so that it points to another address 004F424D, logically that might do the trick.
004F423D: 1C BranchF 004F424D
Now I'm trying to find that address with OllyDbg - to test if that helps. If I succeed I will write part 3.
Does anyone have some other ideas?
i was palying with the ruby sockets, so i ended up trying to put an IP packet togather, then i took an ip packet and try to make a new one just like it.
now my problem is: if the packet is: 45 00 00 54 00 00 40 00 40 01 06 e0 7f 00 00 01 7f 00 00 01, and this is obviously hexadecimal, so i converted it into a decimal, then into a binary data using the .pack method, and pass it up to the send method, then the Wireshark shows me a very strange different thing from what i created, i doing something wrong ???, i know that, but can't figure it out:
#packet = 0x4500005400004000400106e07f0000017f000001 #i converted each 32 bits together, not like i wrote
#data = ""
#data << #packet.to_s
#socket.send(#data.unpack(c*).to_s,#address)
and is there another way to solve the whole thing up, can i for example write directly to the socket buffer the data i want to send??
thanks in advance.
Starting with a hex Bignum is a novel idea, though I can't immediately think of a good way to exploit it.
Anyway, trouble starts with the .to_s on the Bignum, which will have the effect of creating a string with the decimal representation of your number, taking you rather further from the bits and not closer. Somehow your c* seems to have lost its quotes, also.
But putting them back, you then unpack the string, which gets you an array of integers which are the ascii values of the digits in the decimal representation of the numeric value of the original hex string, and then you .to_s that (which IO would have done anyway, so, no blame there at least) but this then results in a string with the printable representation of the ascii numbers of the unpacked string, so you are now light-years from the original intention.
>> t = 0x4500005400004000400106e07f0000017f000001
=> 393920391770565046624940774228241397739864195073
>> t.to_s
=> "393920391770565046624940774228241397739864195073"
>> t.to_s.unpack('c*')
=> [51, 57, 51, 57, 50, 48, 51, 57, 49, 55, 55, 48, 53, 54, 53, 48, 52, 54, 54, 50, 52, 57, 52, 48, 55, 55, 52, 50, 50, 56, 50, 52, 49, 51, 57, 55, 55, 51, 57, 56, 54, 52, 49, 57, 53, 48, 55, 51]
>> t.to_s.unpack('c*').to_s
=> "515751575048515749555548535453485254545052575248555552505056505249515755555157565452495753485551"
It's kind of interesting in a way. All the information is still there, sort of.
Anyway, you need to make a binary string. Either just << numbers into it:
>> s = ''; s << 1 << 2
=> "\001\002"
Or use Array#pack:
>> [1,2].pack 'c*'
=> "\001\002"
First check your host byte order because what you see in wireshark is in network byte order (BigEndian). Then in wireshark you will be seeing protocol headers (depends upon whether it is TCP socket or a UDP one) followed by data. You can not directly send IP packets. So you can see this particular data in the particular's packet's data section i.e. (data section of TCP/UDP packet).