Ollydbg快速上手视频 Ollydbg插件各类使用视频 Ollydbg高级使用视频 x32dbg/x64dbg快手上手视频 x32dbg/x6dbg插件上手攻略视频 万千软件使用技巧视频合集

test2

Index

Arrays

Binary Numbers

Boolean Constants

Boolean Operators

Commands and Functions

Comments

Comparisons

Compound Assignment Operators

Control Structures

If/ElseIf/Else Blocks

While Loops

For Loops

Foreach Loops with Lists

Foreach Loops with Arrays

Switch Statements

Dereference Operator

General Command Syntax

Heredoc and Nowdoc Syntax

Hex Numbers

Include Statement

Include_once Statement

Include Automatically

Math

Multi-line Scripts and Multi-Scripts

Nested Expressions

Operator Precedence

Quick Scripting

Remote Control

Script Files

Script Files for the Advanced

Scripting and User-Defined Commands

Scripting by Numbers

Step Mode: Stepping Through Scripts

Ternary Conditionals

User-Defined Functions

Using Quotes in Scripting

Variables

Variables Scope and Lifetime: Local, Global, and Permanent Variables

 

Introduction

XYplorer Scripting, introduced with version 7.0, can truly be seen as the ultimate in file management efficiency. Roll your own custom commands, combine them to scripts, wrap them in an XYplorer Script file (XYS), or a User-Defined Command, and trigger them by just a click or a keystroke. You may share scripts with colleagues, or download them from the internet. Just drop a script file into your app folder and fresh plug-in commands are at your finger tips.

Without doubt, scripting is an advanced feature that only pays off if you take the time to dive into it and explore the ways and possibilities. However, you will eventually find out that it ain't rocket science at all.

 

More information, downloads, and a growing pool of examples is available here:

https://www.xyplorer.com/

 

Warming Up

To get you started let's try something easy:

(1) Select menu Scripting | Run Script...

(2) Paste msg "Hello world!" into the edit box.

(3) Click OK.

You should see a "Hello world!" message box now. Well done, you just wrote your first XYplorer script!

 

Okay, now for something a little bit more interesting:

(1) Try msg %temp%. You should see a message box that displays your TEMP path. %temp% is a standard Windows environment variable.
(2) Try msg "XYplorer.exe runs from <xypath>". <xypath> is a native XYplorer variable that resolves to XYplorer's application path.
(3) Try msg "Press OK to copy the time!"; copytext "<date hh:nn:ss>". When the message box is OKed, the second command copytext is immediately executed and the current time is copied to the clipboard.
(4) Try set $a, "<curpath>"; msg $a. You should see a message box displaying the current path. First the variable $a is set to the current path, then it is used in the msg command.
(5) Try $a = "Year " . "<date yyyy>"; msg $a. You should see a message box displaying "Year 2009" (or whatever the year might be when you try this). First the variable $a is set to two strings, one literal and one variable, concatenated by a dot, then it is used in the msg command.

 

 

General Command Syntax

(1) There are commands consisting of a function name like msg or copytext, and arguments that can contain literals like "Hello!", and variables like %temp% (environment), <curpath> (XYplorer), or $a (user-defined).
(2) An argument can have more than one part. The parts are concatenated by dots ( . ).
(3) A command can have more than one argument. The arguments are separated by commas ( , ).
(4) A script can have more than one command. The commands are separated by semi-colons ( ; ).
(5) Arguments are identified either by position, or by a prefixed number denoting their position (see Numbered Arguments below).

 

Examples

This little script will rename all currently selected items by appending the current date:

rename b, "*-<datem yyyymmdd>"

This script goes to the Desktop folder (ensuring that the listing is unfiltered), sorts the list by date modified (descending), selects the first item, and moves the focus to the list:

goto "Desktop|"; sortby m, d; sel 1; focus "L"; 

 

Numbered Arguments

Instead of counting commas you now can prefix the position of the argument to the argument itself. The separator is ":=", the first position is 0 (zero).

For example, instead of this:

text popupmenu("A,B,C", , , , , , ",");

You can do this:

text popupmenu("A,B,C", 6:=",");

You can even do this (reversed or arbitrary order):

text popupmenu(6:=",", 0:="A,B,C");

Or this (processing is from left to right, the last mapping wins):

text popupmenu("a,b", 6:=";", 6:="|", 6:=",", 0:="A,B,C");

 

Concatenation

Strings and variables can be concatenated by dots. Any number of blanks surrounding the concatenator are ignored. The following scripts are identical:

msg "Hi there!"

msg "Hi "."there!"

msg "Hi " . "there!"

msg "Hi "   .  "there!"

msg "Hi"." "."there!"

 

Using Quotes in Scripting

It's strongly recommended that you (double- or single-) quote your strings! While the script engine is currently still permissive with unquoted strings (msg Hi! works) this might not be so in the future, so you better do msg "Hi!" right away!

Here's the basic laws of quoting:

(1) Everything is either in double-quotes, or in single-quotes, or outside of any quotes.
(2) To have double-quotes inside double-quotes they must be doubled.
(3) To have single-quotes inside single-quotes they must be doubled.
(4) Variables are resolved in double-quotes and outside of any quotes, but not in single-quotes.

 

Commands and Functions

There are two types of commands: commands (proper) and functions. Contrary to commands (e.g. echo), functions (e.g. quote()) return an in-place value.

In the first example, the quoting is achieved by doubled double-quotes. The only command in the statement is echo. In the second example, the quoting is achieved through the function quote():

echo """Hi!""";    //"Hi!"

echo quote("Hi!"); //"Hi!"

Remarks on Functions

(1) Function names are not case-sensitive: QUOTE() = quote().
(2) Even without any argument -- e.g. quote() -- the parentheses are mandatory, else a function is not recognized.
(3) You can call a function without caring for the return argument (but you need the parentheses!):
renameitem("John", , , "-01");
Optionally you can use the dummy command call:
call renameitem("John", , , "-01");
(4) Functions are not resolved (interpolated, see below) when inside double-quotes.

Command Prefixes

Now you can add a prefix to each command to modify its behavior. Currently one prefix is implemented:

 e = skip the big error debugging dialog

The prefix is separated from the command by | (pipe). For example, when you run this command in the drives listing:

rename , '*-<datem yyyymmdd>';      //shows error dialog

e|rename , '*-<datem yyyymmdd>';    //skips error dialog

 

 

Quick Scripting

Quick Scripting means: Scripts, when prefixed with "::" (double-colon), can be executed directly (i.e. quickly) through any interface in XYplorer that can process locations: Address Bar, Go To, Favorites, Catalog etc. This gives you a lot of choices for usage and storage of scripts.

Let's try:

Paste ::msg "Hello world!" into the Address Bar and press Enter. You should see a "Hello world!" message box.

 

Now, for mouse users, the Catalog is a very good place for scripts. Using the "::" prefix, scripts can be simply entered into the Location field of a catalog item. They are executed on a single click.

For example:

(1) Add a new category "Scripts" and add a new item to it.
(2) Set item's Location field to ::#1026 and save it. The icon turns into the script symbol.
(3) Now click the item. The Find Files tab on the Info Panel is opened, all search filters are reset, and the cursor is placed into the Name field. Nice!

But how did this work? And what is #1026? Read on...

Note: From version 9.70 onwards the "::" prefix is not necessary anymore when you end your script line with a trailing ";" (appended comments after the ";" are allowed). This behavior is enabled by the INI setting ScriptSmartDetect=1.

 

Scripting by Numbers

In XYplorer almost every function has a fixed number, the function ID, by which it can be referred to in a script. ID #1026 happens to refer to "Miscellaneous / Find Files / Open Find Files and Reset". Open the Customize Keyboard Shortcuts dialog (menu Tools) and find this function in category Miscellaneous. At the bottom of the dialog you'll see a button showing the function's ID. Clicking this button will copy the function's ID to the clipboard, making it easy to use it in a script.

You can execute almost any function in XY in a script by referring to its function ID. E.g. #230 will pop up the submenu "New" of menu Edit.

 

Step Mode: Stepping Through Scripts

Suppose you have an older script #230, and you forgot what #230 refers to. Or you downloaded a script from the internet, and don't know exactly what it does. What now? Very simple, enter Step Mode:

(1) Open the Scripting menu and select Step Mode.
(2) Now execute your mysterious script.

A small window (resizable), the Step Dialog, will pop up and tell you what is about to happen. You can now decide whether to execute the command, or skip it, or cancel the whole script. In stepping mode you are on the safe side. It is highly recommended when writing or debugging scripts!

There's also a toolbar button for toggling the stepping mode. When pressed (stepping is ON) its color changes to red to make the current state very clear.

 

Error Messaging and Risk Classes

The Step Dialog also tells you what went wrong where, and it informs you about the potential risk associated with the command to be executed. There are the following risk classes:

#3 Potentially harmful because the function ID might refer to some risky process which is unknown at this point (either an internal command or a User-Defined Command): #[function ID]
#2 Potentially harmful because files or folders are affected: backupto, copyto, delete, download, moveto, new, open, openwith, rename, rotate, run, setkey, swapnames, timestamp
#1 Potentially harmful because Step Mode is terminated: unstep
#0 Harmless: (all others)

Class #3, #2, and #1 are marked with a yellow "warning" icon, class #0 with a blue marble (think "cool") icon.

 

Script Context

The first two lines in the Step Dialog display (1) the current script resource,  and (2) the current script caption. Valuable information when writing and debugging scripts.

 

How Functions are Stepped

Functions are individually stepped. The current script line is marked green when a contained function is stepped as opposed to the main command of the line. You can even skip (button Skip) functions individually, in which case the function name is returned with the resolved arguments. For example:

msg quote(chr(64));

· If you continue both functions the result is: "@"
· If you skip chr() and continue quote() the result is: "chr(64)"
· If you continue chr() and skip quote() the result is: quote(@)
· If you skip both functions the result is: quote(chr(64))

When you "Continue without Stepping" on a function, the stepping is only suspended for all functions in the current script line / command.

 

Variables... (Button)

Click the Variables... button to display all currently assigned variables with their current values. Within the new "Variables on Stack" dialog you can double-click any listed variable to show its current value.

Right-click that button for further options:

Show User Functions will list all currently declared user functions. Within the new "User Functions" dialog you can double-click any listed function to show its code.

 

 

Scripting and User-Defined Commands

Now, for passionate keyboarders, there are User-Defined Commands (UDCs). Using the "::" prefix, scripts can be simply entered into the Location field of a UDC Go To item, which then can be assigned a keyboard shortcut to.

For example:

(1) Click menu User | Manage Commands...
(2) Select the category Go To, and click the New button.
(3) Enter ::text "<clipboard>" into the Location field.
(4) Assign a keyboard shortcut, say Ctrl+Alt+3.
(5) Click OK.

Now press Ctrl+Alt+3. You should see a small window displaying the current textual contents of the clipboard.

 

Of course, you don't have to abuse the UDC Go To for scripts. There's also the UDC Run Script which accepts scripts without a prefixed "::", e.g. text "<clipboard>".

Run Script can also handle more advanced stuff like multi-line scripts, and multi-scripts, the rules and possibilities of which will be further explained below under "XYplorer Script Files".

 

Multi-line Scripts and Multi-Scripts

A script can have more than one line (multi-line script), and a script resource can have more than one script (multi-script). There is one important formatting rule for multi-line scripts:

In a multi-line script all lines apart from the first line have to be indented by at least one space.

Each non-indented line is interpreted as the first line of a separate script, and if there are more than one scripts in a loaded script resource (i.e. a multi-script) then a menu is popped where you can select the script to run.

For example, this is a multi-script containing two multi-line scripts. In the first script, the script caption (which is used as the menu caption) forms the first line:

"Go to C:\"
 goto "C:\";
goto "%winsysdir%";
 selectitems "calc.exe";

Comments are an exception: Any number of non-indented comments can be prefixed to a multi-line script. Actually non-indented comments can be inserted anywhere. This script is functionally identical to the above one:

// comment 1
// comment 2
"Go to C:\"
// comment 3
 goto "C:\";
// comment 4
goto "%winsysdir%";
 selectitems "calc.exe";
// comment 5

 

Initialize and Terminate

You can define two special-named scripts within multi-scripts, "_Initialize" and "_Terminate". They can be placed anywhere in the multi-script, and they are not shown in the popup menu. The script called "_Initialize" will be auto-processed before the menu is popped. The script called "_Terminate" will be auto-processed after the script selected from the menu has been processed (or after the menu has been canceled).

Note: If a script within a multi-script is called directly (SCs Sub or Load), then "_Initialize"/"_Terminate" are NOT called.

For example, this multi-script defines a permanent variable (which is also global by definition), then offers various scripts in a popup menu, then finally removes the variable from memory:

"_Initialize"
 // if variable already exists it is NOT reset here but keeps it current value
 perm $p_a;
 // explicitly initialize it to zero
 $p_a = 0;
"_Terminate"
 unset $p_a;
 
"Show Variable"
 echo $p_a;
"Plus One"
 $p_a = $p_a + 1;
 echo $p_a;
"Minus One"
 $p_a = $p_a - 1;
 echo $p_a;
"Load Plus One"
 // will NOT call "_Initialize"/"_Terminate"
 Load "*", "Plus One";
 // WILL call "_Initialize"/"_Terminate"
 Load "*", "*";
"Sub Plus One"
 // will NOT call "_Initialize"/"_Terminate"
 Sub "Plus One";

 

Script Files

Here we are talking popup menus that are user-defined by a text file. Let's make one:

Create a new text file in any editor.

Paste the following multi-line script (see above):

// some little test scripts
"Go to C:\"
 goto "C:\"
"Go to System Folder"
 goto "%winsysdir%"
"Go to XYplorer Folder"
 goto "<xypath>"

 

Save the file as "test.xys" (XYplorer Script File) in XYplorer's Scripts folder. In case you don't know that path, use menu Scripting | Go to Scripts Folder to go there.

Now, in XYplorer, click menu Scripting | Load Script Files... and open "test.xys". The following menu should pop up at your mouse cursor:

Go to C:\

Go to System Folder

Go to XYplorer Folder

Now you can choose where you want to go.

 

A script file is basically a library of scripts. It is nothing more than a simple text file, which can contain one or more scripts. You will be able to either call one of those scripts directly, or simply load the entire file. In such case, XY will create a menu based on the contained scripts in that file and pop it up, allowing you to choose which script to execute.

The syntax for the scripts themselves within script files is exactly the same as for scripts anywhere else in XY since this is just another way to store and execute scripts.

 

Syntax rules for XYplorer Script Files

(1) Lines starting with // are ignored and can be used for comments.
(2) One script can run over multiple lines. Simply indent the lines after the first line using any number of space or tab characters.
(3) You can have more than one script inside a script file. In that case, loading the script file will pop up a menu presenting all scripts inside the script file by their captions.
(4) To set a script caption simply prefix the desired caption to the script, and wrap it in quotes.
(5) Within a caption you may define a label that allows you to execute a script from a file directly.
(6) Using the command sub in a script file you can execute other scripts inside the same file.
(7) You may hide scripts by prefixing an underscore (_) to their caption.

 

To Load a Script File do one of the following:

(1) Use menu Scripting | Load Script File...
(2) Use a User-Defined Command from category "Load Script File".
(3) Use the script command load [scriptfile].

The existence of a command load, of course, means that one script file can load another. You will get an idea of the potential of scripting by now...

 

Drop on a Script File

You can drop files onto XYS-files. The dropped files are referred to in the dropped-on script by <get drop>.

This can get pretty cool in Dual Pane mode. You can have a folder with assorted script files in one pane, and your working folder in the other pane. Now you just drag-and-drop files onto the scripts for automated processing.

Primitive example script in a file "drop_on_me.xys":

text <get drop>;

Even cooler: You can also drop on multi-scripts. In that case you get the usual popup menu of choices, and the <get drop> will be available in each of the scripts.

Primitive example script in file "drop_on_me_2.xys":

"Text"
 text <get drop>;
"Echo"
 echo <get drop>;

Notes:

· If more than one file is dropped <get drop> returns one per line. Alternatively you can pass a separator like this:
text <get drop |>;
· The <get drop> variable is cleared after the script is processed, so it cannot be used after the drop event is completed.
· <drop> is a synonym for <get drop>.
· If the script contains no <get drop> variable it is run nevertheless just as if you loaded the script file.
· You can as well drop files on shortcuts (LNK) to XYS-files.
· You can also drop text onto XYS-files (and LNKs to XYS-files), e.g. selected text from a webpage. Just like with dropped files, the dropped text can be referred to in the dropped-on script by <get drop>.

 

Script Files for the Advanced

Labels

By using labels you can execute a script inside a file directly, avoiding the popup menu. The label is attached to the caption, separated by " : " (space-colon-space).  For example:

// some little test scripts, using labels
"Go to C:\ : croot"
 goto "C:\"
"Go to System Folder : system"
 goto "%winsysdir%"
"Go to XYplorer Folder : xy"
 goto "<xypath>"

 

If the above is saved to a file called "test.xys" in application data path then the following command will directly bring you to the System folder: load "test.xys", "system".

You may as well specify a list of labels, by which you can easily control which scripts are displayed in the popup menu, and in which order. See load for the details.

Wildcard catch-all label: The label "*" matches all load calls if more than one label is stated. The third command will be shown on load "test.xys", "croot;system":

// some little test scripts, using labels
"Go to C:\ : croot"
 goto "C:\"
"Go to System Folder : system"
 goto "%winsysdir%"
"Go to XYplorer Folder : *"
 goto "<xypath>"

 

Hiding scripts inside a script file

Hidden scripts can be executed but are not shown in the script file's popup menu. To hide a script simply prefix an underscore to the caption or label (a hidden script does not need a caption anyway). For example, create a script file "date.xys" in application data path with the following contents:

// this is in script file "date.xys"
"_date"
 msg "<date yyyy-mm-dd>"
"_time"
 msg "<date hh:nn:ss>"
"Show Date : date"
 sub "_date";
"Show Date && Time : datetime"
 sub "_date";
 sub "_time"

 

Now execute the script load "date.xys". The popup menu will show only two of the four contained scripts. Select either and see what happens.

 

Now run the script load "date.xys", "date". The script with the label "date" will be executed directly. It has only one command: sub "_date";. The sub command is a special command to call a script inside the same script file. In this case the hidden script with the label "_date" is called and executed. Its command msg "<date yyyy-mm-dd>" produces the message box showing the current date.

Variables in Captions

The captions of scripts in multi-script resources may contain XYplorer native variables. They are resolved in the moment the menu is popped up. For example, paste this into the Try Script box:

"Go to <xypath>"
 goto "<xypath>";
"Is it <date hh:nn:ss>?"
 msg "It's <date hh:nn:ss>!";

The 2nd script will show two different times if you wait longer than a second before you click the menu item.

Also Environment Variables and Permanent Variables are supported in captions.

 

Icons, States, and Levels

You can optionally define an icon and a state for each menu item.

Syntax:

"Caption|Icon|State|Level : Label" Script
 where
State Default = 1
State Checked = 2
State Disabled = 4

Examples for States

"Go C:|C:|1" goto "C:\";  //shown bold
"Go D:|D:|2" goto "D:\";  //shown checked
"Go E:|E:|3" goto "E:\";  //shown bold and checked

 

Icon can be any file or folder, and its small system icon (the one you see in Details View) will be used for the menu, or a PNG, JPG, GIF, BMP, or TIF file. XY variables and environment variables are supported. The path defaults to the XY icon path <xyicons>.

You can as well use XYplorer's internal toolbar icons using the button key, e.g.:

"Funny Script|Icons\fun.ico" echo "Ha!";
"Say Ho!|iexplore / 12" echo "Ho!";
"Recent Locations|:mru" button "mru"
"Hotlist|:hotlist" button "hotlist"

Note that the icon specification in a multi-script resource supports permanent global variables.

You can as well use generic file icons in the multi-script menus by passing the generic extension as "*.ext":

"Megan|*.png"  echo 'hello';
"Betty|*.jpg"  echo 'hello';

You can as well pass * as placeholder to use the caption as icon pointer:

"C:\|*" goto "C:\";
"C:\Windows|*" goto "C:\Windows";

 

Levels: Multi-Scripts support nesting. The level is simply stated by the number denoting its depth, first level is 0 (zero), which is also the default, of course. Up to 256 levels are possible. For example:

"C:|*"
"Go to C:\|||1"
 goto "C:\";
"|||1" goto "%winsysdir%";
 selectitems "calc.exe";
"D:|*"
"Go to D:\|||1"
 goto "D:\";

 

Relative Levels: Multi-script nesting can be defined with relative levels. This can be useful when building menus from local resources by use of the Include statement.

Syntax: A relative level is marked by a prefixed "+" character. The number following "+" is added to the last defined absolute level.

For example, the following two code samples create identical nested multi-scripts:

"A" echo "A";
"B|||1" echo "B";
"C|||2" echo "C";
"D|||1" echo "D";
"B|||2" echo "B";
"C|||3" echo "C";

"A" echo "A";
"B|||+1" echo "B";
"C|||+2" echo "C";
"D|||1" echo "D";
"B|||+1" echo "B";
"C|||+2" echo "C";

However, the second sample uses relative levels which allows it to re-use the same part of code twice:

"B|||+1" echo "B";
"C|||+2" echo "C";

So this part of code could be outsourced to a file say "IncludedMenuBC.xys" and then be included like this:

"A" echo "A";
include "IncludedMenuBC.xys"
"D|||1" echo "D";
include "IncludedMenuBC.xys"

 

The Goto-Shorthand

In a multi-script resource you can pass a plain path/file spec as a shorthand for a well-formed goto script. Such a line will be auto-converted to a valid goto command including the appropriate icon in the generated popup menu.

Long version using well-formed goto scripts with captions:

"C:\|C:\" goto "C:\";
"C:\Windows|C:\Windows" goto "C:\Windows";
"C:\WINDOWS\SoundMan.exe|*" goto "C:\WINDOWS\SoundMan.exe";

Equivalent shorthand version:

C:\
C:\Windows
C:\WINDOWS\SoundMan.exe

The goto-shorthand additionally supports environment and native variables, Quick Searches, and visual filters. For example:

Desktop
%tmp%
<xydata>
C:\WINDOWS\system.ini
C:\WINDOWS\system32
C:\WINDOWS\system32?a*
C:\WINDOWS\system32?:a* or b*
C:\WINDOWS\system32?:a* | b*
C:\WINDOWS\system32?lbl:blue
C:\WINDOWS\system32|a*

 

 

Comments

Two types of comments are supported, line end comments, and block comments.

Line End Comments

Line end comments begin with a double-forward slash (outside of any quotes) and end at

the end of the line:

$a = "<xypath>"; assert $a=="<xypath>"; //should not fail

$a = "<xypath>";            //assign XY path
 assert $a=="<xypath>";  //should not fail

"get CountSelected" // comment
 $count = get("CountSelected");  // comment
 assert $count!=0,     // comment
 "You must select a file before running this script!"

Block Comments

Block comments (aka C-style comments) start with /* (outside of any quotes) and end with the next */ (outside of any quotes) and can span any number of lines:

/* This is
a multi-line
block comment
*/ msg "hi!";

msg /*they can be inserted anywhere!*/ "hi!" /* anytime */;

Remarks on Comments

(1) Line-end and block comments overwrite each other:

msg "Hi!"; // /*this is not a block comment starting...
msg /* //this is not a line end comment starting... */ "Hi!";

(2) Make sure you don't nest block comments. It is easy to make

this mistake if you are trying to comment out a large block of

code:

/*
msg 'This is a test'; /* Will cause a problem */
*/

This, however, will work since // overwrites the /* */ comment:

//msg 'This is a test'; /* This comment is NO problem */

 

Variables

Advancing in script writing, you will soon feel the need for variables. XYplorer allows you to define and use as many variables as you want, using a number of commands like set, input, replace, etc. The script set $a, "Hi!"; msg $a; will define a new variable $a and assign the string "Hi!" (without the quotes) to it; then a message box will display "Hi!". The same can be achieved using the assignment operator  (=):

$a = "Hi!"; msg $a;

Interpolation

Variables are resolved wherever they are found in the arguments of all subsequent commands of the script, even if they are found inside double-quoted strings (see below, Interpolation); for example:

$name = "Ted"; msg "Hi, I'm uncle $name!";

will display the message "Hi, I'm uncle Ted!".

Format and Scope

Variables have to conform to the following rules:

(1) Variables are represented by a dollar sign ($) followed by the name of the variable.
(2) Names start with a letter or underscore, followed by any number of letters, numbers, or underscores.
(3) Letters are a-z and A-Z.

Good variables: $a, $ABC, $good_variable, $a1, $a_, $_a, $_

Bad variables: a, ABC, $1, a$, $ä, $., $

Variable names are case-sensitive.

The scope and lifetime of a variable begins and ends with the script where it has been defined.

Using the equal-operator (=)

To assign a value to a variable you can simply use the following syntax (as an alternative for the set command):

$a = "b"; or $a="b"; (spaces are ignored)

For the additional "reprocess" operand see description of the set command.

Increment Syntax (++/--)

The common increment syntax using the ++ (--) operator is supported.

$i=5; $i++; msg $i; //6

$i=5; $i--; msg $i; //4

$i++; msg $i; //1

You can also use $i++/$i-- as an argument. The value is incremented/decremented after it is passed to the function*:

$i = 1; echo $i++; echo $i;     //1; 2

$i = 1; echo 1 + $i++; echo $i; //2; 2

$i = 1; echo $i++ + 1; echo $i; //2; 2

$i = 1; echo $i++ . $i++ . $i;  //123

Note in the following that the left operand is incremented before the right operand is added. Finally, after the addition, the right operand is incremented:

$i = 1; echo $i++ + $i++; echo $i; //3; 3 

* Note that before v14.30.0100 the value was incremented/decremented before it was passed to the function!

Interpolation

Interpolation means that variables that are embedded in double-quoted or unquoted strings are resolved (replaced with their corresponding value). Examples:

$name = "Ted"; msg "Hi, I'm uncle " . $name . "!";

Displays "Hi, I'm uncle Ted!". The variable is concatenated with literal strings.

$name = "Ted"; msg "Hi, I'm uncle $name!";

Displays "Hi, I'm uncle Ted". The variable is interpolated inside double-quoted literal strings.

$name = "Ted"; msg "Hi, I'm " . uncle $name!;

Displays "Hi, I'm uncle Ted". The variable is interpolated inside non-quoted literal string uncle $name!. Note that using non-quoted literal strings is not recommended and might even be deprecated in a future version!

 

You can block interpolation by using single-quotes:

$name = "Ted"; msg 'Hi, I''m uncle $name!';

Displays "Hi, I'm uncle $name!". The variable is not interpolated inside single-quoted literal strings. Note that single-quotes embedded in single-quotes have to be doubled (I''m).

msg '%TMP% = ' . %TMP%;

Displays "%TMP% = C:\Temp". The first %TMP% is blocked from interpolation by being embedded in single-quotes.

$date = "<date>"; msg '$date = ' . $date;

Displays "$date = 28.08.2008 12:23:12".

 

Variables Scope and Lifetime: Local, Global, and Permanent Variables

Local Variables

By default, all variables in XY scripting are local, i.e. they are not shared between called and calling scripts. In other words, whenever one script calls another script (e.g. using commands "sub" or "load"), a new local namespace is created by the called script and pushed on the stack.

Global Variables

Generally, global variables are shared between scripts. This can make scripts hard to maintain. However, the mechanism of "globalization" -- (almost) identical to the one used in PHP -- used by XY scripting gives you maximum control over what is shared and where. Global variables are implemented by means of the command global.

Permanent Variables

The lifetime of local and global variables ends with the current script or script stack. Permanent variables, however, stay alive in memory for the whole XYplorer session, or even across sessions if configured like this (Configuration | Refresh, Icons, History | Remember permanent variables). Hence permanent variables can be easily shared between scripts. Permanent variables are implemented by means of the command perm.

Permanent Variables created / modified in a called script are immediately visible / updated in the calling script when the called script returns.

Note the scripting commands writepv and readpv by which you can read and write permanent variables from/to file. This allows for some interesting use as portable data storage.

Permanent variables can be accessed from anywhere in the app using the <perm ...> meta variable. See Variables.

To release all permanent variables from memory use the command releaseglobals. You can as well unset them individually via menu Scripting | Permanent Variables directly from the right-click menu in the variable list.

To view and modify the current permanent variables use menu Scripting | Permanent Variables.

Initial Values

Local variables that have never been set to a value return their name as value (strictly speaking they aren't variables but normal strings). Global and permanent variables that have never been set to a value are initialized to "" when they are declared by global or perm:

msg $a;     // displays "$a" if $a is has not set to any value before, and has not been declared as global or permanent.

global $b;  // declare global variable

msg $b;     // displays "" if $b has not been set to any other value before.

perm $c;    // declare permanent variable

msg $c;     // displays "" if $c has not been set to any other value before.

 

Arrays

Two types of arrays are supported, indexed arrays and associative arrays. The syntax is similar to that used in eg C++, PHP or Java.

Here are some examples for indexed arrays:

$a[0]="pussy"; echo $a[0]; //pussy

$a[0]="pussy"; $a[1]="cat"; echo $a[0].$a[1]; //pussycat

$a[2]="cat"; $b=1; echo $a[$b+$b]; //cat

Array elements also work within quotes:

$a[0] ="cat"; echo "It is a $a[0]!";  //It is a cat!

$a[0]="pussy"; $a[1]="cat"; echo "$a[0]$a[1]"; //pussycat

Here are some examples for associative arrays (the named keys can be single- or double-quoted):

$a['pussy']="cat"; echo $a["pussy"]; //cat

$a["pussy"]="cat"; $b="pussy"; echo $a[$b]; //cat

If the index or key is invalid the variable is seen just as a bit of text:

$a[0] ="cat"; echo "It is a $a[1]!"; //It is a $a[1]!

$a["pussy"] ="cat"; echo "It is a $a['fussy']!"; //It is a $a['fussy']!

Also a missing key makes the variable invalid:

$a[0] ="cat"; echo "It is a $a[]!"; //It is a $a[]!

If you assign a non-first element in a new or smaller indexed array, all previous elements starting with [0] are automatically created (with value ""):

$a[1] ="cat"; echo $a[0]; //"" ($a[0] is implicitly created and set to "")

$a[0] ="cat"; echo $a[1]; //$a[1] ($a[1] does not exist as variable)

The index can be a complex expression:

$n = 4; $a[$n+4] = $n * 4; echo $a[$n+4]; //16

$b[0] = "pus"; $b[1] = "sy"; $a[$b[0] . $b[1]] = "cat"; echo $a[$b[0] . $b[1]]; //cat

You can copy one array to the other (appending [] to the variable name is optional):

$b[] = $a[];

$b = $a; //$a is an array variable; $b becomes an array variable

 

Some more properties of arrays:

· The global command is supported by arrays, eg: global $a[];
· The perm command is not supported by arrays but is simply ignored: Arrays cannot be permanent.
· Allowed range of elements in an indexed array: 0 to 32767.
· Maximum number of elements in and associative array: 32768.
· Various scripting functions help dealing with arrays: count() , explode(), implode().

Special Function array()

There is a special function array() to populate arrays. Non-existing arrays are created, dimensioned and populated, existing arrays are redimensioned and overwritten.

$a = array("cat", "dog"); echo $a[0]; $a = array("dog"); echo $a[0]; //cat, dog

Notes:

· You would usually pass literal strings as values, not variables. Values are separated by commas.
· You can also pass a single variable to the array() special function that resolves to a list of strings. For example:
$values = "vampire, cow"; $arr[] = array($values); echo $arr[0]; //vampire
· The values can be in double quotes (which will be removed), or also without quotes (fine if you are not using any commas or flanking spaces within the values):
$a = array(cat, dog); echo $a[0]; //cat
· The values can also be in single quotes but those will not be removed.
· If you like you can append [] to the variable, it makes no difference:
$a[] = array("cat", "dog"); echo $a[0]; //cat
· The values are added to the array in the order they are listed, starting with element [0].
· So far the indexed arrays, but you can also populate associative arrays using array():
$name = array("cat" => "pussy", "dog" => "rex"); echo $name["cat"]; //pussy
General syntax:
... = array("key1" => "value1", "key2" => "value2")
Again, you can get away with stripping the quotes and the spaces:
$name = array(cat=>pussy,dog=>rex); echo $name["dog"]; //rex
· You can use array() without any values to completely reset an array:
$a = array("cat", "dog"); $a = array(); echo $a[0]; //$a[0]
· After "$a = array();" the variable $a is an array with zero elements:
$a = array("cat", "dog"); $a = array(); echo count($a); //0

Foreach Loops with Arrays

The syntax here is a bit different from the Foreach Loops with Lists syntax.

General form:

foreach($array as $value, [flags]) {
 statement(s) using $value;
}

Example:

$a = array("cat", "dog", "bat");
 foreach($a as $value) {
   echo $value;
 }

Reversing the order (r flag) is supported:

$a = array("cat", "dog", "bat");
 foreach($a as $value, "r") {
   echo $value;
 }

Skipping empty items (e flag) is also supported:

$a = array("cat", "", "bat");
 foreach($a as $value, "re") {
   echo $value;
 }

 

The Foreach Loop also supports returning the keys in associative arrays. General form:

foreach($array as $key => $value, [flags]) {
 statement(s) using $key and $value;
}

Example:

// make associative array
 $freelancer = array(
   "name" => "Groot",
   "email" => "groot@gmail.com",
   "age" => 22,
   "gender" => "unknown"
 );
 // loop through array
 foreach($freelancer as $key => $value) {
   echo "$key: $value";
 }

 

Reversing the order (r flag) and skipping empty items (e flag) is supported.

The key variable is set to the numeric index if you do 'foreach($array as $key => $value)' on an non-associative array:

$key="FOO"; $a = array("cat", "dog", "bat");
 foreach($a as $key => $value) { //always overwrites $key
   $b[$key] = "$key=$value";
 }
 text implode($b);  //0=cat|1=dog|2=bat

 

 

Nested Expressions

You can nest expressions using parentheses, aka round brackets: ( ). There's no practical limit to nesting depth and superfluous parentheses are silently removed.

Examples where parentheses are merely decor:

msg "a" . "b";

msg ("a" . "b");

msg ("a") . ("b");

msg (("a") . ("b"));

msg ((("a") . ("b")));

msg "a" . "b" . (); //"ab"

msg "a" . ("b" . "c");

msg ("a" . "b") . "c";        //"abc"

msg "a" == "a" . "a" == "b";

msg ("a" == "a") . ("a" == "b"); //"10"

Examples where parentheses actually make a difference:

msg "a" == "a" . "a";

msg ("a" == "a") . "a";         //"1a"

msg "a" == ("a" . "a");         //"0"

Examples for nesting errors:

msg ("a" . "b"; // ')' missing! ->  ("a" . "b"

msg "a" . "b"); // '(' missing! -> = a"b")

 

Math

Scripting can do basic calculation using math operators +-*/, and also \ (integer division), % (modulo), and ^ (exponentiation). Fractions and parentheses are supported. Also unary operators + and - are supported.

Examples

echo 1 + 1;

echo 1 - 2 - 3;   // -4

echo 1 - (2 - 3); //  2

echo 1/3 + 1/3;

echo 1 + 2 * 3;

echo (1 + 2) * 3;

echo 1/0;  // ERROR: division by zero

$a=3; $b=2; echo $a / $b; // 1.5

$fraction = 1.5; echo $fraction == 3/2; // true

echo 1.2 + 2.1; // 3.3

echo 1 + --1; //2

echo --(1 * ----2); //2

echo 5 \ 2; //2 (integer division)

echo 5 / 2; //2.5

echo 5 % 2; //1 (modulo)

echo 2 ^ 3;   //8

echo 4 ^ 0.5; //2

echo 4 ^ -1;  //0.25

Remarks

(1) Strings are converted to numbers as possible (just like in comparisons).
$a=""; $b="2"; echo $a + $b; // = 2
$a="1a"; $b="2b"; echo $a + $b; // = 3
(2) The decimal separator is NOT locale specific (e.g. dot in US, comma in Germany) but hard-coded to dot (period). This way scripts are interchangeable between regions.
(3) Calculation uses 8-byte floating point numbers with the following ranges:
negative: -1.79769313486232E308   to -4.94065645841247E-324
positive:  4.94065645841247E-324  to  1.79769313486232E308
Floating point arithmetic has its natural shortcomings so don't expect too much in terms of precise accuracy down to the 12th digit. A file manager is not a scientific calculator.
(4) The operator precedence is  ^ > (*,/) > (\,%) > (+,-)  meaning that * and /,  \ and %,  + and - are of equal weight.
Processing of math terms is from left to right:
echo 36 / 4 * 3;  // 27!   (not 3)
(5) With integer division (the portion of the result after the decimal point is lost) and modulo (the remainder of integer division) the operands are rounded before the operation!
echo 5.9 \ 2.1; //3!
echo 7.9 % 2.5; //2! (8 % 3 = 2)
echo 7.9 \ 0.4; //ERROR: Division by zero.
echo 7.9 % 0.4; //ERROR: Division by zero.
(6) Fractional numbers should be stated with a dot as decimal separator, or alternatively in quotes with the local decimal separator:
echo 7.5 / 2.5;       //3 -- works under each locale
echo "7,5" / "2,5";   //3 -- works only where comma is the decimal separator
Internally decimal separator are stored and processed according to the system locale:
$n = 2.5; echo $n;    //$n is "2,5" internally where comma is the decimal separator

 

Hex Numbers

The parser recognizes the common prefix 0x (zero-x) for hexadecimal values. Supported are up to 4 bytes per number, i.e. 8 hex digits. The hex digits are case-insensitive (the prefix is not).

Here for some examples; hex values are automatically resolved to decimal values:

echo 0xa; //10

echo 0xA; //10

echo 0xFFFFFF;   //16777215

echo 0xFFFFFFFF; //-1

echo 0x7FFFFFFF; // 2147483647

echo 0x80000000; //-2147483648

echo 0xA + 0xA; //20

The following are examples for invalid hex strings; they are returned unresolved:

echo 0xG;           //0xG (invalid value)

echo 0x;            //0x  (no value)

echo 0XA;           //0XA (wrong prefix)

echo 0x123456789;   //0x123456789 (too many characters)

echo "0x12345678";  //0x12345678 (quoted)

Tip: To convert HTML #RRGGBB colors to color decimals use this formula:

0xBBGGRR

 

Binary Numbers

The parser recognizes the common prefix 0b (zero-b) for binary values. Supported are up to 4 bytes per number, i.e. 32 binary digits. Here for some examples:

echo 0b0; //0

echo 0b1; //1

echo 0b11; //3

echo 0b10000000; //128

echo 0b11111111; //255

echo 0b100000000; //256

echo 0b00000000000000000000000000000001; //1

echo 0b10000000000000000000000000000000; //-2147483648

echo 0b11111111111111111111111111111111; //-1

The following are examples for invalid binary strings; they are returned unresolved:

echo 0b2;           //0b2 (invalid value)

echo 0b;            //0b  (no value)

echo 0B1;           //0B1 (wrong prefix)

echo 0b110000000000000000000000000000000; //0b110000000000000000000000000000000 (too many characters)

echo "0b1";         //0b1 (quoted)

 

Comparisons

Comparisons of two values are evaluated in-place. The "comparison" has the general form

   "a" operator "b"

where "a" and "b" are string expressions, and "operator" can be one of the following:

   ==  Equal

   !=  Not Equal

   <   Less than

   >   Greater than

   <=  Less than or Equal to

   >=  Greater than or Equal to

 Like  Matches Pattern (case-sensitive)

LikeI  Matches Pattern (case-insensitive)

UnLike  Does not match Pattern (case-sensitive)

UnLikeI Does not match Pattern (case-insensitive)

If the comparison evaluates as True it is set to "1", else it is set to "0".

Examples

msg "a" == "a";

= shows '1'

msg ("a" == "a") . ("a" == "b");

= shows '10'

$r = ("a" == "a"); $r = ($r?"True":"False"); msg $r;

= shows 'True'

$comparison = "a == a"; assert $comparison == "a == a";

= no assertion error

$minver = "7.60.0009"; assert "<xyver>" >= $minver, "This script needs at least XY $minver!"

= no assertion error if XY version is >= 7.60.0009

Strings and Numbers

If you compare two numerical strings, they are compared as integers:

msg ("2" < "10"); // -> true! (both parts are numeric)

msg ("2" < "10a"); // -> false! (only one parts numeric)

msg ("2a" < "10a"); // -> false! (both parts are non-numeric)

 

The Like (LikeI) and UnLike (UnLikeI) operators

General form:

 String Like Pattern   (case-sensitive)

 String LikeI Pattern  (case-insensitive)

Where string is any string expression and Pattern may contain the usual wildcards and special chars used in XY patterns (*?#[]). Note that exact capitalization matters: "Unlike" or "unlike" won't work. These operators must be surrounded by spaces.

Examples:

echo "abc" Like "a*"; //1

echo "Abc" Like "a*"; //0!

echo "Abc" LikeI "a*"; //1!

echo "abc" UnLike "a*"; //0

echo "Abc" UnLike "a*"; //1!

echo "Abc" UnLikeI "a*"; //0!

echo "Abc" LikeI "abC"; //1 (no wildcard!)

echo "It's " . ("<date yyyy>" Like "20??"?:"not ") ."the 21st century";

 

Boolean Operators

Scripting supports Boolean operators in the following order of precedence (see also Operator Precedence):

!            NOT    (unary operator)

&&   AND

||   OR

and  AND    (case-insensitive: AND, And...)

xor  XOR    (case-insensitive: xOR, Xor, XOR...)

or   OR     (case-insensitive: OR, Or...)

Examples

echo not 1; // 0

echo not 0; // 1

echo ! 1; // 0

echo !1; // 0

echo !!!1; // 0

echo !(1 and 0); // 1

// parsed as: (TRUE and FALSE) or (TRUE and TRUE);
 echo TRUE and FALSE or TRUE and TRUE; //1

// will show "1", then "done"
 $i = 1;
 while ($i < 2 && $i > 0) {
   echo $i;
   $i++;
 }
 echo "done";

 

Boolean Constants

The Boolean constants TRUE and FALSE (case is ignored) are recognized if they are used unquoted.

TRUE is resolved to 1.

FALSE is resolved to 0.

Examples

echo TRUE and TRUE;   // 1

echo TRUE and FALSE;  // 0

echo TRUE and false;  // 0 (constants are case-insensitive)

echo TRUE and "false";  // 1! (quoted "false" is NOT a constant)

echo (1==1) == TRUE;  // 1

echo (0==1) == FALSE; // 1

echo (1==1) != FALSE; // 1

 

Note that in a Boolean context the values "" and "0" evaluate to 0 (FALSE). All other values evaluates to 1 (TRUE):

echo "dog" and TRUE;  // 1  (TRUE and TRUE)(Boolean context)

echo "dog" == TRUE;   // 0  ("dog" == "1") (no Boolean context)

echo "0" == FALSE;    // 1  ("0" == "0")(same strings)

echo "" == FALSE;     // 0  ("" == "0") (no Boolean context)

echo "" XOR TRUE;     // 1  (FALSE XOR TRUE)

echo "0" XOR TRUE;    // 1  (FALSE XOR TRUE)

echo "dog" XOR TRUE;  // 0  (TRUE XOR TRUE)

Note that "0" and 0 ("1" and 1) are the same in XY scripting, so:

echo 0 == FALSE;      // 1  (0 == 0)

echo 0 XOR TRUE;      // 1  (FALSE XOR TRUE)

 

Ternary Conditionals

Scripting knows so-called "ternary conditionals" as used in many other programming languages. The logic is this:

 if (condition) {

   variable = value-if-true;

 } else {

   variable = value-if-false;

 }

As ternary conditional the same can be written like follows:

 variable = (condition) ? value-if-true : value-if-false;

The parentheses and the blanks are optional, so these are identical:

 variable = (condition) ? value-if-true : value-if-false;

 variable = (condition)? value-if-true: value-if-false;

 variable = condition?value-if-true:value-if-false;

The part "condition" has the form

   "a" operator "b"

where "a" and "b" are string expressions and "operator" can be one of the following:

   ==  Equal

   !=  Not Equal

   <   Less than

   >   Greater than

   <=  Less than or Equal to

   >=  Greater than or Equal to

(none) True if expression is not 0 and not ""

The parts "value-if-true" and "value-if-false" are string expressions.

Examples

$a = "<date hh>" >= "12"? "afternoon": "morning"; msg "Good $a!";

$a = ("<date mm-dd>" == "12-24")? "": "not "; msg "It's $a"."X-mas!";

You can employ ternary conditionals in any argument or part of argument:

msg "Good " . ("<date hh>" >= "12"? "afternoon": "morning") . "!";

msg "It's " . ("<date mm-dd>" == "12-24"? "": "not") . " X-mas!";

 

Compound Assignment Operators

The Compound Assignment Operators .=, +=, -=, *=, /=, \=  can be used to shortcut operations of two variables where the result is set to one of the variables. For example, both lines below are functionally identical; the latter one uses one of the Compound Assignment Operators:

$a = $a . "b";

$a .= "b";

More examples:

$a = "a"; $a .= "b"; echo $a;   //ab

$a = 1;   $a += 1; echo $a;     //2

$a = 1;   $a -= 1; echo $a;     //0

$a = 2;   $a *= 3; echo $a;     //6

$a = 5;   $a /= 2; echo $a;     //2.5

$a = 5;   $a \= 2; echo $a;     //2

 

 

Control Structures

Scripting offers various Control Structures by which you can control the order in which the individual statements are executed. Within these structures blocks of statements are grouped by encapsulating them with curly braces.

 

If/ElseIf/Else Blocks

General syntax:

if (expression) {
 statement;
}
elseif (expression) {
 statement;
}
else {
 statement;
}

If expression evaluates to TRUE, the following statement block is executed and the other blocks are ignored. If expression evaluates to FALSE the following statement block is ignored and processing continues with the next Elseif or Else block.

Remarks

· Parentheses around the expression are mandatory.
· Curly braces around the statement block are mandatory (even if there is only one statement).
· The Elseif block(s) and Else block are optional. There can be only one Else block and it must be the last block in the whole control structure.

Examples

if (1 == 1) {echo "Hi!"}

// shows "Relax."
 if (1 == 2) {
   echo "Help!";
 }
 else {
   echo "Relax.";
 }

// shows "else", "elseif", "if"
 $i = 1;
 while ($i) {
   if ($i == 3) {
     echo "if";
     break 2;
   }
   elseif ($i == 2) {
     echo "elseif";
   }
   else {
     echo "else";
   }
   $i++;
 }

 

While Loops

General syntax:

while (expression) {
 statement;
}

The nested statement(s) are executed repeatedly, as long as the while expression evaluates to TRUE. The value of the expression is checked each time at the beginning of the loop. If the while expression evaluates to FALSE from the very beginning, the nested statement(s) won't even be run once.

Remarks

· Parentheses around the expression are mandatory.
· Curly braces around the statement block are mandatory (even if there is only one statement).

Examples

// will show 1, then 2, then terminate the script
 while ($i < 2) {$i++; echo $i;};

// will show 1, 2, 3, then terminate the script
 $x = 3;
 $i = 1;
 while ($i <= $x) {
   echo $i;
   $i++;
 }

// nested while blocks are okay
 $x = 3;
 $i = 1;
 while ($i <= $x) {
   $w = "Word";
   while ($w != "") {
     echo "$w No. $i";
     $w = "";
   }
   $i++;
}

// expression is FALSE, message will never show
 while (1 == 2) {echo "Help!"};

 

For Loops

General syntax:

for (expression1; expression2; expression3) {
 statement(s);
}

The expression1 is executed once unconditionally at the beginning of the loop. In the beginning of each iteration, expression2 is evaluated. If it evaluates to true, the loop continues and the nested statement(s) are executed. If it evaluates to false, the execution of the loop ends. At the end of each iteration, expression3 is executed.

Remarks

· Parentheses around the expressions are mandatory.
· Curly braces around the statement block are mandatory (even if there is only one statement).

Internal Processing

For loops can be thought of as shorthand for While loops, and that's how they're supported now: For loops are internally converted to While loops. If you step through your scripts, you'll see that.

For example, this For loop:

for ($i = 1; $i <= 3; $i++) {
 echo $i;
}

... is internally converted to this While loop:

$i = 1;
while ($i <= 3) {
 echo $i;
 $i++;
}

 

 

Foreach Loops with Lists

General syntax:

foreach($variable, ListOfTokens, [separator="|"], [flags], [MsgOnEmpty]) {
 statement(s);
}

Remarks

· $variable is the variable which receives the value of the next token in each round of the loop. You can use a new variable or an already used one, it does not matter.
· The last value of $variable remains even after the foreach loop.
· ListOfTokens is a string of tokens, separated by a separator.
· The separator defaults to "|" (pipe), but can be set to anything, also multi-character strings.
Passing an empty separator will tokenize the ListOfTokens by letter.
· Surrounding spaces are not trimmed off on each side of the tokens.
· flags can be either empty (default) or set to "r" for "reverse direction", or "e" to skip empty items in the list of tokens.
· In MsgOnEmpty you can state an error message for the case that ListOfTokens is empty. If MsgOnEmpty is given (even as empty string "") the loop will not be executed at all.
· SC break and SC continue are supported.

Examples

// returns 3 strings (moon, sun, venus):
 foreach($token, "moon,sun,venus", ",") {
   echo $token;
 }

// flag r: returns 3 strings in reversed order (venus, sun, moon):
 foreach($token, "moon,sun,venus", ",", "r") {
   echo $token;
 }

// flag e: returns 2 strings ("moon", "venus"); empty items are skipped:
 foreach($token, "moon,,venus,", ",", "e") {
   echo $token;
 }

// nested foreach loops
 foreach($token, "a|b|c") {
   foreach($token2, "1,2,3", ",") {
     echo $token . $token2;
   }
 }

// selected list items
 foreach($token, <get selecteditemspathnames |>) {
   echo $token;
 }

// shows "No files selected!" if no files are selected, and skips the loop
 foreach($item, <get selecteditemspathnames>, <crlf>, , "No files selected!") {
   echo $item;
 }

// passing an empty separator = tokenize by letter
 $string = 'string';
 foreach($letter, $string, '') {
   echo $letter;
 }

 

Switch Statements

The switch statement is similar to a series of IF statements on the same expression. In many occasions, you may want to compare the same variable (or expression) with many different values, and execute a different piece of code depending on which value it equals to. This is exactly what the switch statement is for.

In a switch statement, the condition is evaluated only once and the result is compared to each case statement. In an elseif statement, the condition is evaluated again. If your condition is more complicated than a simple compare and/or is in a tight loop, a switch may be faster.

General syntax:

switch (n) {
   case label1:
      code to be executed if n=label1;
       break;
   case label2:
      code to be executed if n=label2;
       break;
   case label3:
      code to be executed if n=label3;
       break;
   ...
   default:
      code to be executed if n is different from all labels;
}

Remarks

· The case statements are checked from top to bottom until a match is found.
· Each case should be closed by a break statement.
· It's possible to use a semicolon instead of a colon after a case.
· A special case is the default case. This case matches anything that wasn't matched by the other cases.

Examples

// switch
 $favcolor = "blue";
 switch ($favcolor) {
   case "red":
       echo "Your favorite color is red!";
       break;
   case "blue":
       echo "Your favorite color is blue!";
       break;
   default:
       echo "Your favorite color is neither red nor blue but $favcolor!";
 }
 echo "Switch done!";

 

The switch and case arguments can also be more complex expressions:

 

$a = 3; $b = 7; $c = 10.5; $d = 2;
 switch ($a * $b) {
   case $c * $d:
       echo "The result equals $c * $d = " . $c * $d;
       break;
   default:
       echo "The result is something else.";
 }

 

Usually each case should be closed by a break statement. Else processing continues with the next case (sometimes though this can be desired). Here is an example where omitting break statements makes sense. Also shows that the default case also accepts a break statement (although is totally superfluous here). Also shows that semicolons after the cases are an acceptable alternative to colons:

$beer = 'Kirin';
 switch($beer) {
     case 'Asahi';
     case 'Kirin';
     case 'Sapporo';
         echo 'Good choice';
         break;
     default;
         echo 'Please make a new selection...';
         break;
 }

 

The case statements don't have to be in their own line. This example also shows that using the return command within a function you can spare the break command:

function getChineseZodiac($year){
     switch ($year % 12) {
         case  0: return 'Monkey';  // Years 0, 12, 1200, 2004...
         case  1: return 'Rooster';
         case  2: return 'Dog';
         case  3: return 'Boar';
         case  4: return 'Rat';
         case  5: return 'Ox';
         case  6: return 'Tiger';
         case  7: return 'Rabbit';
         case  8: return 'Dragon';
         case  9: return 'Snake';
         case 10: return 'Horse';
         case 11: return 'Lamb';
     }
 }
 echo getChineseZodiac(2016);
 
 // BTW, user functions work in switch and in case:
 switch (getChineseZodiac(2016)) {
   case getChineseZodiac(2015): echo "2015"; break;
   case getChineseZodiac(2016): echo "2016"; break;
   case getChineseZodiac(2017): echo "2017"; break;
 }

 

Also note this somehow perverted use of a switch:

$a = "Kirin";
 switch (true){
   case $a=="Kirin":   echo "first choice"; break;
   case $a=="Sapporo": echo "second choice"; break;
 }

 

 

 

Heredoc and Nowdoc Syntax

Heredoc, using the <<< operator, is a way to define multi-line strings "as is" without the need to escape quotes etc.

The rules follow the PHP rules for Heredoc:

(1) After the <<< operator, an identifier (your free choice) is provided, then a new line. The string itself follows, and then the same identifier again to close the quotation. The closing identifier must begin in the *first* column of the line (no indent!). The line with the closing identifier must contain no other characters, except possibly a semicolon (;) directly after the identifier.
(2) Heredocs overwrite comments, and comments overwrite heredocs, depending on who comes first.

Within the Heredoc section:

(3) Line feeds, empty lines, and all kinds of comments survive.
(4) Lines are not trimmed (leading and trailing spaces are preserved).
(5) Quoting is handled automatically (no need to add outer quotes or to double inner quotes).
(6) Variables are resolved.

Example

A multiline script using Heredoc. Note that the Heredoc block is not indented, that comments are not removed, that quotes are not doubled, and that the variables are resolved (the only difference to Nowdoc), even within comments.

Basic example:

$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
 echo $str;

 

More complex example, with variables and comments:

$name = "Bond";
 text <<<FOO
My name is $name, "James $name". // line end comment: $name
 
Follow /* note: there's one space after me, */ me,
FOO
 ."please!";

Output:

My name is Bond, "James Bond". // line end comment: Bond
 
Follow /* note: there's one space after me, */ me, please!

Alternative Heredoc Syntax

A more radical parsing where the ending identifier can be anywhere is enabled when the identifier starts with a "#". These examples show two ways to code the same script.

$isOk = Confirm (<<<#FOO
Blah
BlahFOO#FOO); echo $isOk;

With the old-school parsing the ending identifier must be on its own line:

$isOk = Confirm (<<<FOO
Blah
BlahFOO
FOO
 ); echo $isOk;

Nowdoc Syntax

A special variety of Heredoc is the Nowdoc, that is a Heredoc without interpolation. Quoting from PHP Documentation:

"Nowdocs are to single-quoted strings what heredocs are to double-quoted strings. A nowdoc is specified similarly to a heredoc, but no parsing is done inside a nowdoc. The construct is ideal for embedding PHP code or other large blocks of text without the need for escaping. It shares some features in common with the SGML <![CDATA[ ]]> construct, in that it declares a block of text which is not for parsing.

A nowdoc is identified with the same <<< sequence used for heredocs, but the identifier which follows is enclosed in single quotes, e.g. <<<'EOT'. All the rules for heredoc identifiers also apply to nowdoc identifiers, especially those regarding the appearance of the closing identifier."

Example:

$var = "syntax";
 $str = <<<'EOD'
Example of string
spanning multiple lines
using nowdoc $var.
EOD;
 echo $str;

Output (note that $var has not been resolved):

Example of string
spanning multiple lines
using nowdoc $var.

 

Nowdoc also accepts the alternative radical option (see above) enabled by prefixing the identifier with '#' (within the quotes).

 

Dereference Operator

You can use the dereference operator * (asterisk) with all variables. Usage: Helpful when dynamically creating variables.

Examples

$var = '$a';        *$var = "TEST"; echo $a;  //TEST

$var = '$a';   perm *$var = "TEST"; echo $a;  //TEST

$var = '$a'; global *$var = "TEST"; echo $a;  //TEST

$var = '$a'; *$var = "TEST"; echo "*$var, $a!";  //TEST, TEST!

 

If the dereferenced variable is not defined, then the variable itself is used (as if there was no dereference operator):

*$undefined = "TEST"; echo $undefined; //TEST

 

Note that also unset and incr support the dereference operator:

$var = '$a';  *$var = "TEST"; unset *$var; echo $a; //$a

$var = '$a';  *$var = 1; incr *$var; echo $a; //2

$var = '$a';  *$var = 1; *$var++; echo $a; //2

$var = '$a';  *$var = 1; *$var--; echo $a; //0

$var = '$a'; *$var = 1; echo 1 + *$var++; echo *$var; //2; 2

 

Note that dereferencing is also supported in interpolation (including HEREDOC) if you explicitly allow it with the aid command.

 

 

Operator Precedence

The precedence of an operator specifies how "tightly" it is connected to its surrounding operands. For example, in the expression 1 + 2 * 3, the answer is 7 and not 9 because the multiplication ("*") operator has a higher precedence than the addition ("+") operator. Parentheses may be used to force precedence, if necessary. For instance: (1 + 2) * 3 evaluates to 9.

The following table lists the precedence of operators with the highest-precedence operators listed at the top of the table. Operators on the same line are evaluated from left to right (3 - 2 + 1 evaluates to 2, not 0):

 

Operators     Additional Information

-------------------------------------------

++ --         Math: Increment, Decrement

! Not         Boolean: NOT

+ -           Math: Unary Plus, Unary Minus (operator is prefixed to a number)

* / *= /=     Math: Multiply, Divide

%             Math: Modulo

\ \=          Math: Integer division

+ - += -=     Math: Add, Subtract

. .=          String concatenator

< <= > >= == !=             Comparison

Like LikeI UnLike UnLikeI   Comparison

&&            Boolean: AND

||            Boolean: OR

And           Boolean: AND

Xor           Boolean: XOR

Or            Boolean: OR

? :           Ternary

=             Set

 

Remote Control

*** For software developers only ***

You can run an XYplorer script from an external program using the WM_COPYDATA command with XYplorer's hWnd. This means if you are a programmer you can fully remote control XYplorer.

· cds.dwData: 4194305 (0x00400001)
· cds.lpData: The syntax is identical to the one of the command line switch /script=<script resource>, so you can either pass the path to a script file (commonly called *.xys), or pass the script directly (must be preceded by ::).

 

User-Defined Functions

Like other aspects of XYplorer scripting also user-defined functions are closely modeled after PHP.

A user-defined function (or simply "user function") is a block of statements that can be used repeatedly in a program. It can return a value (using the command "return"). The function declaration starts with the word "function", then a space, then the name of the function:

General form:

function functionName() {
 code to be executed;
}

Alternative formatting:

function functionName() { code to be executed; }

Example with 2 arguments and a return value:

function sum($x, $y) {
 $z = $x + $y;
 return $z;
}

· User function names can only consist of letters (a-z, A-Z), numbers, and underscores, and must not start with a number.
· User function names are NOT case-sensitive.
· The first line of user function declarations can be left-bound or indented. It does not matter.
· User functions can be defined anywhere in a script resource, before or after the main script, and as many as you want.
· A user function will not execute immediately when a script is loaded. It has to be called just like native functions.
· All user functions have global scope.
· User functions overwrite native functions of the same name.
· If two or more user functions share the same name, the *first* one declared will be used, all other ones ignored.
· User functions do not support function overloading, nor is it possible to undefine or redefine previously-declared functions.
· User functions can call each other.
· It is possible to call recursive user functions, but be aware that too many recursions can smash the stack and cause a termination of the current script.
· Variables are by default passed by value, not by reference (so the function cannot modify the variables in the caller's scope).
· To pass variables by reference (so the function can modify the variables in the caller's scope) prefix them with & in the function declaration.
· All arguments are optional. Default values for missing arguments can be set. If no default value is set a missing argument is initialized to "".
· XYplorer native variables (e.g. <crlf>) and environment variables (e.g. %tmp%) are allowed in function argument default parameters. They are resolved if they are unquoted or double-quoted. They are NOT resolved if they are single-quoted.

 

Example 1: Arguments and Returns

echo multiply(3, 4) . <crlf> . sum(11,12);
function multiply($x, $y) { return $x * $y; }
function sum($x, $y) {
 $z = $x + $y;
 return $z;
}

 

Example 2: Argument by Value

$a = 1; add_one($a); echo $a; //1
function add_one($a) {
 $a++;
}

 

Example 3: Argument by Reference

$a = 1; add_one($a); echo $a; //2
function add_one(&$a) {
 $a++;
}

 

Example 4: Argument with Default Value

echo multiplyDefaults(2); //8 (2 * 4)
function multiplyDefaults($x = 3, $y = 4) {
 return $x * $y;
}

 

 

Include Statement

The "include" statement lets you include the content of a file at the place where the "include" statement was found. That way you can include e.g. function libraries into your script resources.

Note that the "include" statement is evaluated unconditionally when a script resource is loaded and before anything else is done.

Syntax

include file;

  file: Path, if not fully stated, is resolved relative to <xyscripts>.

         Extension defaults to ".xys".

         Quotes are optional (they are totally function-less here, but might look better to some folks including me).

         Note that you cannot use any script variables for file. However, XYplorer variables and environment variables are supported.

Remarks

You may end any include statement line with the usual instruction terminator ";". However, you must not append other instructions in the same line. The include statement needs to have its own line.

Include statements can be nested (included files can themselves include other files). The maximum nesting level for Include statements is 100 (one hundred). You will get an error if you go beyond. Beware of recursion: A file must not include itself or any file by which it has been included, else you will reach the maximum nesting level within the next millisecond...

Include statements can be indented. Included stuff will inherit the indent of the include statement.

 

Example (loaded script)

"Test 1"
 echo multiply(3, 4);
"Test 2"
 echo divide(10, 3);
include "math.inc"

Example (included library):

// math.inc
function sum($x, $y) { return $x + $y; }
function diff($x, $y) { return $x - $y; }
function multiply($x, $y) { return $x * $y; }
function divide($x, $y) { return $x / $y; }

 

Include_once Statement

The "include_once" statement is identical to the "include" statement, with the only difference being that if the code from a file has already been included, it will not be included again. There are no errors or messages. Trying to include_once an already included file will simply ignore the statement and continue.

 

Include Automatically

There is auto-include for scripts that are run directly from the address bar (and only from there). This way you can also use user functions from the address bar (which doesn't allow a proper include statement). It works like this:

· Create a file named "xy-autoinclude.xys" in path <xyscripts>.
· Fill it with the user functions you intend to use. For example:

   function half($a) {return $a/2}
   function sum($x, $y) {
     $z = $x + $y;
     return "$x + $y = $z";
   }        

· Now you can run these commands right from the address bar:

  echo half(7); //returns 3.5

  echo sum(172, 428); //returns "172 + 428 = 600"

Note: If "xy-autoinclude.xys" is not found when running a script from the address bar, XYplorer will not try again during that session. Saves speed, energy and material.

 

posted @   汇编工具视频笔记教程  阅读(4)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
反汇编(第一点睛组)
OllyDBG看雪论坛免配版 由看雪论坛出品的版本,该版本无视路径配置,解包即用。
AoRE版本Ollydbg 该版由老外制作,集成了不少汇编破解工具
R4ndom版Ollydbg 这是R4ndom入门系列中修改过的OD
残影版OllyICE 顶部集成了一组硬件断点工具栏,下断脚本工具栏和很多的插件
吾爱扣扣专用Ollydbg 由52破解论坛52QQ同学研制,内置了不少工具和插件
吾爱破解Ollydbg 这个版本网友使用者也是不少的
Ollydbg2.01 这是2.0版OD,集成了不少新的插件
内存版OD 这个版本由看雪论坛内部出品,可以为内存中设置条件断点
小生我怕怕Ollydbg 该版本由小生我怕怕同学研制,内置了很多工具和插件
BambooQJ修改版Ollydbg BambooQJ修改后的版本,集成了不少的工具箱
OllyDbg1.10_Sound 论坛Sound牛出品,口味独特,欢迎使用
OllyICE这个不错 OllyICE是ollydbg的变种

原版odbg110
OllyDBG_Original_Version

这是德国原版的Ollydbg
R4ndom版Ollydbg R4ndom版主要是学习OD中提到的那个版本中老外研制
半斤八兩VIP专用Ollydbg 由前退役明星半斤八两同学生产,其实老大依旧活在我们心中
嫖怪专属OD 由论坛白嫖怪大侠打造Ollydbg内置不少实用插件可以过VMP等强壳检测
吾爱破解专用版OD 作者不详,传闻是汇编得道先人。
零日论坛OD 这个版本由零日论坛出品
条件内存访问断版OllyDBG  
PYG论坛OD  
Smile110涅磐版OD  
   
Ollydbg插件和使用视频教程(点睛第2组)
多功能Ollydbg插件目录伴侣使用视频  
给Ollydbg设置书签的插件ImmLabel和使用视频  
破解delphi程序的插件Code(Delphi) Helper  
破解游戏利器CheatUtility  
序列号计数器插件  
易语言花指令去除插件E Junk Code视频  
Anti-Anti Hardware Breakpoint v0.1  
编写汇编代码的插件和使用  
ollydbg插件Bookmark使用视频  
ollydbg的ArmaDetach分离器插件使用视频  
X_CRYPTO编码转换插件  
ollydbg热补丁F9插件和使用视频  
ollydbg自动转换代码插件Code Ripper使用视频  
OllyFlow流程图插件使用  
OllyMemScan内存扫描插件的使用  
OllyMoreMenu为OD增强更多的菜单项  
OllyPad记笔记的插件使用视频  
窗口控制型插件Window Juggler  
创建签名插件  
改变数据格式的插件的使用视频  
可导入导出标签的插件Labelmaster视频演示  
可导入断点注释书签的插件LCB和使用视频  
去除花指令的插件DeJunk视频使用教程  
调试delphi程序专用的插件和使用视频  
修复条件断点bug的插件  
Olly Machine脱壳脚本的使用  
OllyBone自动OEP定位和脱壳插件的使用  
ollydbg插件Asprotect_1.2x使用视频  
Ollydbg插件不知如何目标如何帮你断Catcha使用教学  
Ollydbg插件之断点在载入时和使用视频  
ollydbg数据转换插件和使用视频  
OllySocketTrace插件的使用视频  
seh模块异常扫描器的使用视频  
SND算法扫描Ollydbg插件和使用视频  
StollyStruct标记数据结构在dump窗口插件的使用  
剥离调试插件使用视频  
多功能反调试的Ollydbg插件AutoPath和使用视频  
过反调试驱动的插件  
可附加调戏游戏的Ollydbg插件  
AttachExtended v0.1  
内核汇编插件Kernel Disassembler使用视频  
去除Ollydbg附加崩溃bug的插件AttachHelper使用视频  
设置delphi程序为unicode型插件  
显示汇编指令含义的插件使用视频  
修复bug插件使用视频  
修复Ollydbg可执行断点时不被断下问题的插件和视频  
CopyHexCode使用视频  
ollydbg插件API Helper v1.0.0.1使用视频  
ollydbg插件ApiBreak Nonameo使用视频  
olly查看pe头的插件使用视频  
Oreans.UnVirtualizer插件脱Themida专用  
Point E(破解Delphi事件)插件和视频  
SehSpy插件的使用  
SkyPatch写补丁插件详解视频  
Sleepp转换查看代码的插件  
把dll作为系统的插件  
窗口式插件管理器与视频  
多功能汇编器插件的使用视频  
反附加的插件ICanAttach和视频教学  
可定义启动程序的插件和使用视频  
可以备份内存的插件使用视频  
可以附加运行的Ollydbg插件Attach Anyway和使用视频  
脱离调试器运行的插件DetachMe使用视频  
增强OD功能的插件使用视频  
中断在dll插件和使用视频  
md5嗅探器插件使用视频  
ollydbg插件Hash Sniffer使用视频  
ollydbg的Asm2Clipboard插件使用视频  
加载IDA地址的插件Load Map和使用视频  
Ollydbg的python使用视频  
Ollydbg反调试器补丁  
AntiDetectOlly_v2.2.4使用详解  
Ollydbg之给多个插件分目录的插件的使用视频  
OllySafe病毒分析插件的使用教程  
OllySymbolServer调试微软符号的插件  
olly多态断点管理器反断点插件  
去除花指令的插件DeJunk视频使用教程  
Universal Hooker一款python监听网包数据插件和视频  
VEHWalk插件  
捕获TLS回调的插件  
插件加载器插件  
抗击打调试插件  
反调试插件DebugPrivilege  
可编辑eip寄存器的插件  
虚拟转物理地址插件  
追踪可疑调用堆栈的插件  
aadp4olly反调试插件  
BlkLabel批量打书签插件  
OD内存防护插件用法  
AdvancedOlly使用视频  
Ollydbg插件Anti-Anti v0.11  
Ollydbg反调试插件VMSweeper  
ollydbg附加进程插件AttachTo和使用视频  
PhantOm反调试和Flash动画  
PuntosMagicos插件和使用视频  
OD按键加强的插件和视频  
快速控制OD增强的插件和使用视频  
多功能复制与转换插件使用视频  
条件断点增强插件CLBPlus视频教程  
一款运行.net程序的插件和视频  
异常计数器ExCounter插件使用视频  
影响标志位跳转的插件使用视频  
转换地图信息的插件MapConv和视频  
自动化修复导入表的插件  
mapimp可导入多种地图文件和控制选项的插件和使用视频  
ollydbg插件Anti-Anti v0.11使用视频教程  
ollydbg插件API Break下断点插件使用视频  
ollydbg插件apifinder使用视频  
ollydbg代码医生转换跳过某些代码的插件CodeDoctor视频教程  
Ollydbg的Ariadne Optimizer v0.1使用视频  
多功能监视内存寄存器的插件MemoryWatch用法视频  
自动生成补丁列表的插件和视频教学HzorInline Helper Plugin  
Ollydbg的VMSweeper插件使用视频教程  
ollydbg插件API Break下断点插件v0.2  
ollydbg插件API断点查找  
Ollydbg反调试器补丁  
AntiDetectOlly_v2.2.4  
Poison反调试插件  
PuntoH反反硬件断点插件  
RemoveCriticality移除垃圾代码插件  
robin反调试器插件  
Scripad一款OD脚本编辑器插件  
VB程序下断插件  
VB语言类插件  
OllyDBG v2.01 Final_Plugins  
   
   
IDA插件及视频
IDA7.0汉化版  
IDA7.2杂交插件浓缩版  
   
   
   
   
x32dbg/x64dbg/插件/教程视频
x64dbg_utf-8的QT插件汉化视频  
   
   
   
   
编译器
   
Hopper  
   
   
   
PE工具
   
   
   
   
编辑器
   
   
   
   
   
加密工具
   
   
   
   
   
加壳工具
   
   
   
   
   
脱壳工具
   
   
   
打包工具
   
   
   
补丁工具
   
   
   
   
   
监视软件
   
   
   
   
代码计算
   
   
   
   
   
   
密码学
   
   
   
   
   
.net平台
   
   
   
   
   
漏洞分析
   
   
   
web安全
   
   
   
   
   
   
   
   
网络分析
   
   
   
   
   
   
   
安卓工具
   
   
   
   
   
加密狗
   
   
   
密码学
   
   
   
   
   
   
其他工具
   
   
   
   
   
   
单文件便携版
金杏电子教鞭-单文件便携版  
屏幕万能抓单文件版  
讯飞文字转语音_单文件版  
讯飞语音_单文件便携版  
Yu Writer_单文件便携版  
孩子提思维单文件版  
SpeedPanX单文件便携版  
ebhRecorder_单文件便携版  
Cok Free MP3 Recorder_单文件便携版  
awksed_单文件便携版  
Bandizip32_单文件便携版  
PPointer_单文件便携版  
Qt Linguist 5.5单文件版  
Recuva去更新提示_单文件便携版  
万能五笔豪华单文件版9.9.3.10908  
金山打字通2013去广告去升级单文件便携版  
AceTrans16.3单文件版  
StellarDataRecovery12[单文件]  
AllMyNotes3.3.3单文件版  
Bandicam单文件版  
Charles单文件版  
EditPlus经典单文件版  
EnigmaVirtualBox9.4单文件版  
FlashBack Recorder单文件版  
FoxitPhantom单文件版  
FSCapture9.3单文件版  
Alcohol4.0.3单文件版  
HprSnap8_单文件便携版  
KenPlayer单文件版  
RevoUninPro4.23_单文件便携版  
Listary单文件版  
Movavi Video Editor Plus 2020单文件版  
MyNotesKeeper3.93-2198单文件版  
everything标题修改版_单文件便携版  
notepad__超级便携单文件版  
FileLocatorPro_单文件便携版  
oCam4.62单文件版  
MindGenius Business6.03.3305单文件版  
Poedit单文件版  
myBase7.3.5_单文件便携版  
PotPlayerMini单文件版  
QQ播放器单文件版本  
QTranslate单文件版  
tim单文件便携版  
QVE视频压缩_单文件版  
SimpleMind Pro 1.20.2单文件版  
RegexBuddy4.10.0单文件版  
SCIENCEWORD_单文件便携版  
TidyTabs.Daemon_单文件便携版  
ScreenScraperStudio_单文件便携版  
TOTALCMD_EZ修改版_单文件便携版  
Sisulizer单文件版  
WinRAR_单文件便携版  
Xmanager Enterprise 5_单文件便携版  
Sublime Text Build 3143 x64单文件版  
XMind_单文件便携版  
Teleport VLX单文件版  
友益文书软件_单文件便携版  
TextMaker_单文件便携版  
7zip19.0_单文件便携版  
Thunder单文件版  
ComfyPartitionRecovery2.8[单文件]  
WINWORD单文件便携版  
Presentation高级版单文件便携版  
OSFMount3.0.1005单文件版  
UltraISO_9600单文件版  
超好用的笔记工具AM-Notebook单文件版  
OSForensics_单文件便携版  
DTLite_单文件便携版  
全网蹭  
虚拟文件打包工具(Enigma Virtual Box)9.50汉化去广告版  
完美PDF转换成Word转换器  
虚拟打印机novaPDF  
影子卫士套装系列  
awk  
DiskGenius正版的  
EaseUS Data Recovery Wizard Technician 11.8 技术员版已激活绿色版  
MiniToolPowerDataRecovery  
PartitionGuru_Pro_v4.9.5.508_x86_CN  
PartitionGuru4.95.528x64  
PartitionGuru英文5.2.0.884绿色版本  
PartitionGuru英文5.2.0.884绿色版本-初步测试破解成功  
万能五笔超级绿色版  
   
ReneeUndeleterCN_Latest  
rescuepro deluxe  
R-STUDIO Network 8.12.175481(不错值得用  
Wondershare Recoverit 7.1.5.20  
CHM Editor.cameyo  
HprSnap7经典版  
ClipMate7  
Loxclip_1.1  
MyDraw18.32.12  
PCHunter32  
PYArk系统底层分析工具  
sed命令行工具  
TIM_v3.0.021315_20200401  
SouGouWB31去广告版安装包  
Carnac显示屏幕按键用于录制  
SpeedPanX最新上帝版  
SumatraPDF-可复制加密文本图片和打印  
火绒剑  
一键去重定向工具  
XYplorer19.50  
Sandboxie  
EasyRecovery  
wps便携版  
Setup  
超级数据恢复2.7.1.5  
Vmware过虚拟机检测  
都叫兽数据恢复解压版2018  
Spyshelter  
金山数据恢复2.0  
vim_Ez定制版  
DiskGenius  
Universal  
DiskGenius  
EmEditor17.1.2.x86  
DiskGenius  
Directory  
DiskGenius  
屏幕画笔  
DiskGenius_V5.2.0.884  
金杏电子教鞭  
OSFMount  
正则三剑客最新零售版  
正则三剑客最新零售版  
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   

 

点击右上角即可分享
微信分享提示