How to use and execute a script ?

Discuss and share scripts and script files...
Post Reply
Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

How to use and execute a script ?

Post by Stefan »

Hold this thread clean PLEASE, no questions, no answers. Use an other thread to discuss things. Thanks.

If you want to ask something or just give some feedback, you can use the Thanks to Stefan for the Scripting How-to - >thread<

- - -

This is an new thread with stuff from the collection thread How did you start scripting?, but with better layout i hope.

Tip: there is an another scripting tutorial made by user TheQwerty >here<

An good start to learn XYplorer in general is to take the official >Tour<

Here is an "Overview of existing scripts" > click




Let's start:

How to execute a script ?


An warning first:

Please note that you should test new scripts always with an backup of your real files, just to take care.

But since an script can switch to an other path and delete for example files,
you should execute only scripts you are sure what they do exactly.

Attention: if an script have no error-handling to prevent users from mistakes,
you should use an script only for the exact purpose it was indented, other-wise the script could make unexpected actions.

If an script does nothing for you you maybe have to select an file first?

Best test new scripts always via "Scripting > Try Script.." first, to learn what it do.




An example one-liner script would just be

Code: Select all

openwith Notepad, (m);
to open one or more selected file(s) with notepad.
Or

Code: Select all

text "FILE: <curname><crlf>BASE: <curbase><crlf>EXT: <curext><crlf>FOLDER: <curfolder><crlf>DATE: <date>";

An "Multi-line" Script could be for example:

Code: Select all

$var_file = "<curname>";
   $var_User = "%USERNAME%";
   $var_DATE = "<date>";
   msg " $var_User has selected <crlf 2>$var_file<crlf 2>at $var_DATE";
A "Multi-Script" would be e.g. like:

Code: Select all

"Multi-Script: Script 1"
   echo "Hello";
"Multi-Script: Script Two"
   text "Hello World";
"Multi-Script: Script number 3"
   msg "Hi %USERNAME% on %COMPUTERNAME%";
A "Multi-Script" with Multi-Lines would be e.g. like:

Code: Select all

"Multi-Script: Script 1"
   $var = input("What's your name?");
   msg "Hello $var ( or %USERNAME% ?)";
   msg "Hello World";
   msg "Finshed";
"Multi-Script: Script Two"
   $var_file = "<curname>";
   $var_User = "%USERNAME%";
   $var_DATE = "<date>";
   msg " $var_User has selected <crlf 2>$var_file<crlf 2>at $var_DATE";
Note the indention !!!
For more read the help > Advanced Topics > Scripting




Here is an short collection of possibilities to execute an XYplorer script file (xys)

There are two main ways:
    A: execute an script on the fly without saving it first to an file.
    B: first save the script to an file and then execute that script by using command "load"

Quick Explanation:
    If you find an script in the forum the easiest way to use this
    is to utilize "Scripting > Try Script.." which enables the debugger and you see step-for-step what happens.
    Use "Scripting > Run Script.." if you know what you do because here is no debugger involved. The script just runs.

    "One-liner" scripts can be just pasted into the address bar (maybe with leading '::')
        ::openwith Notepad, (m);

    If you want to keep an script for ever i would find it handy to paste the script to an plain text file and then "load" it.
    With a script in a separate file you can "load" it from everywhere but you have to modify it at an single place only.
    Also it is easier to backup and exchange scripts if saved to a text file.
    For example a text file "\Data\Scripts\OpenWithNotepad.xys" which contains the script can be
    execute by utilizing "load OpenWithNotepad;" (no path needed for that folder, no extension needed).
    (Tip: to find your "\Data\" folder utilize "Go" menu and "Go to Application Data Folder")



See below for more explanations.



A
A) How to execute a script without saving the code to an file first


To execute an script without creating an script file first you have for example this seven possibilities.

Chose one of this:

Code: Select all

1.) Use XYplorer menu "Scripting > Try Script.."

    Paste or type in the script 

    Example: 
            msg "<xypath>";

    and press OK. 

    "Try Script" always starts with stepping enabled. 
    Note that the debug window appears; try an right click on the [Continue] button and spot the additional options.

   There is also the command "Scripting > Run Script..". which executes an script without calling the debugger.

    Note that you can reuse this script till you overwrite it. XYplorer even remember it after an reboot.

   Tip: you can disable code with 
       /*....*/ block comment 
      and // line comment signs.

Code: Select all

2.) Use the XYplorer address bar for an one-liner script with "Quick scripting"

    - "Quick scripting" (Extended Scripting)
       Enable entering scripts through location interfaces (Address Bar, Go To, Catalog, Favorites).
       Such scripts must be additionally prefixed with a double-colon (::) to distinguish them from normal locations.
       Note that that script is stored from XYplorer internally and you can reuse it e.g. from the address bar history.
    
    Examples:
    ::msg "Hello World!"; 
    ::$temp = "<curitem>";   msg $temp;   $new = replace($temp, "\", "_");   msg $new;


    Only true for older XYplorer versions:
    Note that you have to enable "Quick scripting"  via "Tools > Configuration... > Advanced" (F9 key)

Code: Select all

3.) Use User-Defined Commands (UDC) for an one-liner script

    UDC are user defined menu commands, you may also assign keyboard shortcuts to them.

    How-to:
    XYplorer menu "User > Manage Commands..." 
    "Run Script" section
    New... > Add New Command
    Caption: [    just an short description]
    Script:   [          add your code here;]

    Note that that script is saved from XYplorer internally for later reuse.

Tip: click the [Assign Keyboard Shortcut] button and choose a Keyboard Shortcut to your new UDC. 
Read for more info: http://www.xyplorer.com/tour/index.php?page=udc
See examples: http://www.xyplorer.com/xyfc/viewtopic.php?f=3&t=3146

Code: Select all

4.) Use Custom Toolbar Buttons (CTB) for an one-liner script

      How-to:
       XYplorer menu "Tools > Customize Toolbar..."
       Add an "User Button #1"  and click [OK]

       Right click this new User-Button and customize it:
        - Name:  optional, this is not really needed
        - Icon:   optional, this is not really needed
        - On click:         [                           add your code here;]
        - On right-click:  [ optional script for right clicking this CTB]

    Note that that script is saved from XYplorer internally for later reuse.

Tip: 
    To assign a Keyboard Shortcut to an button, utilize 'User-Defined Commands' (see above) 
    and use command "button ctb23;" as script (if you work on CTB number "23").

See introducing of Custom Toolbar Buttons at
http://www.xyplorer.com/release_8.40.htm
http://www.xyplorer.com/release_8.50.htm
See an example: http://www.xyplorer.com/xyfc/viewtopic.php?p=40908

Code: Select all

5.) Use Portable Openwith Menu (POM) for an one-liner script

    XYplorer menu "Tools > Customize Files Associations... > New"

    Example:
        |"My Description" \;*>your code here;"

    Later The Portable Openwith Menu (POM) is opened via menu "File | Open With... (Ctrl+Alt+Enter)".

    Note that that script is saved from XYplorer internally for later reuse.
See introduce of Portable Openwith Menu at http://www.xyplorer.com/release_7.10.htm
Read more about here: http://www.xyplorer.com/tour/index.php?page=pom
Examples: http://www.xyplorer.com/xyfc/viewtopic.php?p=28660
Examples: http://www.xyplorer.com/xyfc/viewtopic.php?p=42122

Code: Select all

6.) Use Custom Keyboard Shortcuts (CKS) for an one-liner script

  How-to:
    Define an "User-Defined Command" (UDC, point 3. above) and add an keyboard shortcut

Code: Select all

7.) Use Custom Event Actions (CEA) for an one-liner script

    E.g. from an custom right click context menu:

    Sorry, CEA are not implemented right now.


B
B.) How to execute an script by loading it from an file

Code: Select all

First save the script to an plain text file, best (for easy access) in XYplorers Scripts folder.

    How-to:
    - select and copy the whole script to the clipboard
    - in XYplorer go to the script folder (using menu "Go > Go to Scripts Folder")
    - right click there on the number column or on an empty space below of any file
        and chose "Paste Special > Paste Text Into New File" from context menu.
    
        Give that file an nice name and use XYS as extension.
        E.g.: "X:\Tools\XYplorer\Scripts\scriptname.xys"
Next you can call that script from several places as shown below.

Use one of this:

Code: Select all


1.) XYplorer menu "Scripting > Load Script File..." 

    to load an saved script file from XYplorers script folder (or browse to your script)

Code: Select all

2.) Use the XYplorer address bar "Quick scripting" -feature to load an saved script file

    Example: 
       ::load "scriptname";

     Note that the extension ".xys" is not needed to include here.
     Note that the script path for scripts in "XYplorer\Scripts folder" is not needed here. 
     For script located other where you can use absolute or relative paths, like:
     "::load "C:\Temp\myScript"; (to load an script from "C:\Temp\")
     "::load "tests\test01"; (if you have an sub-folder "tests" in your XYplorer script folder)

   Info:
    - "Quick scripting" (Extended Scripting)
    Enable entering scripts through location interfaces (Address Bar, Go To, Catalog, Favorites).
    Such scripts must be additionally prefixed with a double-colon (::) to distinguish them from normal locations.

Code: Select all

3.) Use User-Defined Commands (UDC) to load an saved script file

    How-to:
    XYplorer menu "User > Manage Commands..."
    "Load Script File" section
    New... > Add New Command
    Caption:      [                     just an short description]
    Script File:   [             myScript   or    path\to\script]
    Label:         [     optional: label inside the script file   ]

Tip: click the [Assign Keyboard Shortcut] button and choose a Keyboard Shortcut to your new UDC. 
Read more about: http://www.xyplorer.com/tour/index.php?page=udc
See examples: http://www.xyplorer.com/xyfc/viewtopic.php?f=3&t=3146

Code: Select all

4.) Use Custom Toolbar Buttons (CTB) to load an saved script file

      How-to:
       XYplorer menu "Tools > Customize Toolbar..."
       Add an "User Button #1"  and click [OK]

       Right click this new User-Button and customize it:
        - Name:  optional, this is not really needed
        - Icon:   optional, this is not really needed
        - On click:         [           myScript;    or    path\to\script;]
        - On right-click:  [ optional script for right clicking this CTB]

    Note that that script is saved from XYplorer internally for later reuse.

Tip: 
    To assign a Keyboard Shortcut to an button, utilize 'User-Defined Commands' (see above) 
    and use command "button ctb23;" as script (if you work on CTB number "23").
See introducing of Custom Toolbar Buttons at
http://www.xyplorer.com/release_8.40.htm
http://www.xyplorer.com/release_8.50.htm
See an example: http://www.xyplorer.com/xyfc/viewtopic.php?p=40908
or: http://www.xyplorer.com/xyfc/viewtopic.php?f=7&t=653

Code: Select all

5.) Use Portable Openwith Menu (POM) to load an saved script file

    XYplorer menu "Tools > Customize Files Associations... > New"

    Example:
       |"My Description" \;*>::load scriptname;

    Explanation:
       An leading '|' -symbol means "don't act/execute on double click or enter, just show it in POM"
       "*;\" means to which file types this POM should be associated. Here to all file types "*" and to all folders "\".
      But you can chose single extensions also: txt;log;pas;cpp;html>::load textparserscript;

    Later The Portable Openwith Menu (POM) is opened via menu "File | Open With... (Ctrl+Alt+Enter)".
See introduction of POM at http://www.xyplorer.com/release_7.10.htm
Examples: http://www.xyplorer.com/xyfc/viewtopic.php?p=39914

Note that POM are an extension of "Portable File Associations" (PFA)
Read more about PFA at http://www.xyplorer.com/tour/index.php?page=portable

Code: Select all

6.) Use Custom Keyboard Shortcuts (CKS) to load an saved script file

    Define an "User-Defined Command" (UDC, point 3. above) and add an keyboard shortcut

Code: Select all

7.) Use Custom Event Actions (CEA) to load an saved script file

    E.g. from an custom right click context menu:

    Sorry, CEA are not implemented right now.

Code: Select all

Hint about Script warning about Recursion:

        Example:
        the "Scripting Error" ('Step through scripts') box appears:
            The current script appears to be recursive.
            The stack depth is 3.


Regarding the recursion-warning, you need to turn the recursion checker off if an script uses recursion on purpose:

      Switch Recursion Checker Off
      When writing your scripts, you might want to have one script call itself (using command load or sub).
      Of course, if you don't take care, you could end up in an infinite loop which would result in some problems...
      Trying to prevent such an issue, XY comes with a recursion checker that will pop up a warning message
      when a recursion is spotted and gives you the opportunity to cancel the script execution.
      
      If you do not want these warnings and are confident that you won't create an endless loop,
      you can switch off the recursion checker by setting this entry to a value of 1 :
      
            [Settings]
            ScriptRecursionWarningOff=0




You can also use this setting per script.

      Example:
            Setting("AllowRecursion", 1);

     Explanation:
          + Scripting commands enhanced:
            - setting, settingp
              New named argument "allowrecursion"
                0 = show warning on recursions
                1 = simply go on and hope that the script writer knows what he's doing
              Example:
                ::setting "allowrecursion", 1;
      
              Note: This command is just using a simpler name for the already
              existing INI tweak "ScriptRecursionWarningOff".

              ; Tweak: set to 1 to turn off the recursion checker
              ScriptRecursionWarningOff=1

Code: Select all

Hint about path to script file and script extension .xys
    If the script file is located in the XYplorer script folder "\Scripts" (see menu "Go > Go to scripts folder")
    then you don't need to include the path to execute the script.
    Otherwise call the script with an path, full or relative. 
    You can also use the var "<xyscripts>" to refer to XYplorers script folder. (load "<xyscripts>\sub-folder\testscript")
    Note that you don't need to include the ".xys" extension while executing an script.

Code: Select all

Hint about debug window:
   Enable "Scripting > Step Mode" to see the debug window for every script execution.

   Note: do an right click on the [Continue] button to see some options.

   You can also call the debugger from an script.
   Example:
         step;

Code: Select all

Hint about " " quotes:
    If something doesn't works please try to add or remove quotes from commands.
    Because here for this examples ""-quotes are used often for explanations to show you an start and end point,
    and should NOT be used in real life. On the other hand quotes ARE needed if your commands, names or paths contain spaces.
    You may want to read section about Quotes too?

Find me:
How to launch a script? , Howto start a script? , How-to run an script? , execute a script file , use a script , run this script
Last edited by Stefan on 14 Jun 2013 09:08, edited 10 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: How to use and execute an Script ?

Post by Stefan »

Common questions, mistakes and pitfalls



Syntax changes from time to time!

The syntax of scripting commands changes from time to time as we grow with this scripting language and see some things works better an other way.
So if an found script doesn't works it could be your newer XYplorer.exe uses an other syntax then the older one used to write that script.


For example >> Warning: Deprecated pre-function commands "broken"
> Scripting: The following commands that have been deprecated on 20090917
and all have been replace by functions of the same name:
strlen, strpos, substr, replace, regexreplace, getkey, readurl
They are not supported any more since 20130414.

> Scripting: The following commands that have been deprecated on 20090921
and all have been replace by functions of the same name:
self, input, inputfile, inputfolder
They are not supported any more since 20130417.
Explanation:
OLD command: RegexReplace $result, $haystack, $needle, $replacement;
is replaced by
NEW function: $result = RegexReplace($haystack, $needle, $replacement);



Another change was:
v9.70.0017 - 2010-11-15 15:18
! Scripting: Unary operators + and - were not always parsed
correctly. Fixed. Now stuff like this works:
::echo 1 + --1; //2
::echo --(1 * ----2); //2
Since then (IIRC) we have to use:
sel "+1";
instead of:
sel +1;


There could be more of this (send me a PM and I will add them here)


To make an old script working again you can:
- run that script in debugger
- note which command fails
- refer to XYplorer help file how the syntax has changed
- try to modify the script
If you not succeed post an follow-up in the thread you have found that script so the community can aid you.




Indent your code!
Note that for each script only the first line must/should start at column position 1!
All other following lines MUST be indented by at least one space/blank.

Code: Select all

Exceptions from this rule:

A.) If the first line of your script is an caption in quotes then THIS has to start at pos1.
    Then the first line with code and all following has then to be indented.


B.) You can have more than one script inside a script file.
    The first script may have, the second and following scripts must have an caption
    wrapped in quotes to identify (or say: separate)  each script. You will be prompted with an menu.
    This caption line(s) MUST start at pos1 too. The code has too be indent in that case.


C.) Comment lines starting with // are ignored and may be at pos 1 too, but don't have to.



Examples: - Right script usage:

Code: Select all

$a = "Hello";
  msg $a;
or

Code: Select all

$a = "Hello";
        msg $a;
or

Code: Select all

"This is the CAPTION"
   $a = "Hello";
   msg $a;
or

Code: Select all

"This is the CAPTION"
//here with comment lines

//settings:
  //init the var $a with string "Hello":
   $a = "Hello";

//output:
   //prompt the user by an message box:
   msg $a;

or

Code: Select all

"This is the caption of script No. 1"
   //with comment line
   $a = "Hello";
   msg $a;

"This is the caption of the second script"
   $a = "How are you?";
   msg $a;
   sub "_Third script (hidden)";

"_Third script (hidden)"
/*
Multi-line comment:
You may hide scripts by prefixing an underscore (_) to their caption.
Hidden scripts can be executed but are not shown in the script file's popup menu.
*/
    $B = "I am fine too!";
    msg $B;

Code: Select all

// And here only the second script (here used as function) has an caption.
// At the first script the code line starts at pos 1, the rest code is indented.
// For the second script the caption starts at pos 1, the code is indented:


global $count;
  $a = "How are you?";
  msg $a;
  $count = 3;
  sub "_Second script (hidden)";

"_Second script (hidden)"
  global $count;
  $Loop=1;
  while( $Loop < $count )
  {
    msg "No. $Loop out of $count",1;
    $Loop++;
  }
Right code layout - indent the lines
Right code layout - indent the lines
Indent-your-Code_001_RightUsage.PNG (18.13 KiB) Viewed 49478 times





Examples: - Wrong script usage:

Code: Select all

$a = "Hello";
msg $a;
//not indented at all, you will be prompted with an wired menu showing you all lines starting at pos. 1.
or

Code: Select all

"This is an script"
  $a = "Hello";
  msg $a;
  "This is an second script"
     $a = "How are you?";
     msg $a;
//caption of second script must NOT be indented but start at position 1!
But the only "problem" will be that you will be surprised once you execute
such an wrong indented script by an unexpected dialog shown you ;-)

Indent space is missed - wrong code layout.
Indent space is missed - wrong code layout.
Indent-your-Code_002_WrongUsage.PNG (24.84 KiB) Viewed 49478 times



Note that there is an another exception of this rule:
See XYplorer help "Advanced Topics > Scripting > Heredoc Syntax" for more.


Summarized:
Only the first line of an script are allowed to (and should) start at position 1.
Script "Caption"-lines MUST start at position 1.
   Following lines MUST be indented.

Comment line could start at position 1 since the are ignored.
An exception is the "Heredoc Syntax".
See XYplorer help "Advanced Topics > Scripting" for more.

- - -


Go to an sub-script by taking the value of an variable:

Code: Select all


"Main"
  $UserInput = input("Go to sub-script test","Go to sub: one OR two OR three", "two");
  sub "_sub_$UserInput";

// sub scripts:
"_sub_one"
  msg "This is just sub script one ;-)";

"_sub_two"
  msg "You are in sub two now, welcome !!!";

"_sub_three"
  msg "Did you entered three ????";

See Help > Scripting > Multi-line Scripts and Multi-Scripts
"... a script resource can have more than one script (multi-script). "

See Help > Scripting > 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)."


- - -

Using global variables

global
Define one or more variables as global.

Usage
By default, all variables in XY scripting are local, i.e. they are not shared between scripts.
The command "global" can be applied to share a variable between all scripts that used "global" on that variable.



Examples
Define $foo and $bar as global variables:
global $foo, $bar;


To use variable contents from the main script in the sub scripts too, use the "global" scripting command.

Example:

Code: Select all


"Main"
  //Make an variable global to all sub-scripts:
  global $myVAR;
  $myVAR = "STE fan";

  //Prompt user to enter an option:
  $SUB = input("Global vars test", "Go to sub: one OR two OR three", "one");
  sub "_$SUB";



// === The Subs / Functions ===  //
"_one"
  global $myVAR;
  msg "This is sub one. 'myVAR' contains: $myVAR ('global' was used here and in main also)";


"_two"
  //here, the global command is missed!!!
  msg "This is sub two. 'myVAR' contains: $myVAR  ('global' was NOT used in this sub, but in main only)";


"_three"
  msg "This is sub three. 'SUB' contains: $SUB  ( $SUB is NOT 'global')";


Another example to use common settings on an whole script
by PeterH at http://www.xyplorer.com/xyfc/viewtopic. ... 444#p80444

Code: Select all

"_INIT"
   //Common settings for all scripts below:
   global $var, $VAR;
   $var = "This value is set globally";
   $VAR = "2013";

//============================

"Script ONE"
   load "*", "_INIT"; // <<< execute "_INIT"
   global $var;       // <<< get access to the global var
   msg "$var";       // <<< your own code here

"Script TWO"
   load "*", "_INIT"; 
   global $var, $VAR;
   msg "$var  $VAR";

Please note that there are perm vars now too:

perm
Define one or more variables as permanent

Usage
Permanent Variables stay alive in memory during the whole XYplorer session,
and hence can be easily shared between scripts.

Remarks
· Permanent Variables are always also global. However, contrary to normal globals,
they don't need to be initialized to the current scope in order to be accessed.

Read more in the help.




- - -

Comments:

To comment-out an line or the rest of an line, use two slashes:

Code: Select all

//this is an comment
msg "Hi you!"; //this is an comment
//msg "Hi you!"; this is an disabled command
To comment out an block of lines use:

Code: Select all

/*
line of code
line of comment
line of description
*/


Concatenate strings

Code: Select all

The dot is used for concatenation like with PHP:

   Example:
    $TEST = "File name";

    various test:
    msg $TEST.ext;      //===> results in 'File nameext'
    msg $TEST."ext";    //===> results in 'File nameext'
    msg $TEST.".ext";   //===> results in 'File name.ext'
    msg "$TEST.ext";    //===> results in 'File name.ext'

Tip, so always use quotes "...". 

EDIT:
add picures
Last edited by Stefan on 09 May 2013 20:38, edited 6 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Quotes for command lines and parameters

Post by Stefan »

Quotes for command lines and parameters


Quotes for command lines and parameters

If you launch an application by using the run or open command
and if the path to this app, or the file name of the executable contains spaces,
you have to proper quote the command line (further referred to as 'string')
and maybe also the command line parameters (arguments) too.


This could be a little tricky since the script engine itself removes the outer quotes.
That has to be done because the engine have to know where the string starts and ends,
so the string is enclosed between quotes for the engine, like:

    "C:\Program Files\AutoHotkey\AutoHotkey.exe"



So, if you want that your string is processed include quotes, you have to double the outer double quotes, like:

    ""C:\Program Files\AutoHotkey\AutoHotkey.exe""



But this doesn't works as expected either because it is read as:

    "EmptyString"C:\Program Files\AutoHotkey\AutoHotkey.exe"EmptyString"




That's why you have to use triple double quotes: """String""", like:

    """C:\Program Files\AutoHotkey\AutoHotkey.exe"""

The construct """ simply means: give me an string which contains just one single "-sign

As result you get
    "C:\Program Files\AutoHotkey\AutoHotkey.exe"


Alternatives for """:
    quote("C:\Program Files\AutoHotkey\AutoHotkey.exe")
    chr(34) . "C:\Program Files\AutoHotkey\AutoHotkey.exe" . chr(34)
    '"C:\Program Files\AutoHotkey\AutoHotkey.exe"' //(that are single quote ' + double quote ")
    '"' . "C:\Program Files\AutoHotkey\AutoHotkey.exe" . '"' //(that are single quote ' + double quote " + single ' quote)
    """" . "C:\Program Files\AutoHotkey\AutoHotkey.exe" . """" //(that are four double quotes)


- - -




It's strongly recommended that you (double- or single-) quote your strings!

Even if they doesn't contains spaces. This is just your script works in future script versions too.

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) <xy> Variables are resolved in double-quotes and outside of any quotes, but not in single-quotes

Examples for selfilter():

Code: Select all

selfilter "readme";      // Selects all items whose name contains "readme" (eg: readme, readme.txt, !readme.now)
selfilter """readme""";  // Selects item named "readme" and only that one item
selfilter "foobar";       // pattern is foobar
selfilter '"foobar"';      // pattern is "foobar"


Use quotes when strings contain "special characters"
such as the XY-script parameter separator ( , ),
the XY-script command separator ( ; )
or the XY-script concatenation operator ( . )
among others -- and in future such characters could be added at any time.


Use quotes when you want to use quotes within your parameters, which may be required on occasion (as part of the command's syntax).
In such a case, to use a quote within quotes you need to escape it by another quote.
In other words, you need to "double-quote" your quotes, specified within quotes.

Code: Select all

Examples:
msg This works but is dangerous (read: not future-proof); 
msg "This is correct and recommended"; 
msg "This is correct, too, and of course you can use separators , ; . '  ""  and ""quotes"" as you wish."; 
msg """This is correct too and quotes ("") will be shown as they're part of your parameters."""; 

msg '"This is "correct" too"';   //(That's: ' " string with quotes " ' )



Single Quotes vs Double Quotes
Whenever you can use strings, you can (and should) put them in quotes.
XY supports two kinds of quotes : single-quotes ( ' ) and double-quotes ( " )

Single-quotes ( ' ) : any string in single quotes will be used as-is by XY without further processing.
Double-quotes ( " ) : any string in double quotes will be processed by XY and any contained variable will be resolved to its current value at the time.
For example, the following script will show two popups, both saying "$hi=Hello World!".

::set $hi, "Hello World!"; msg '$hi' . " = $hi";
::set $hi, "Hello World!"; msg '$' . "hi = $hi";

Code: Select all

Note: single quotes '...' return the string unresolved.
Test:

::msg "This is <curfolder>";         //This is PROGRAM FILES
::msg '"This is <curfolder>"';        //"This is <curfolder>"  //(That's: ' " string with quotes " ' )

::msg '<curfolder>' . "  shows you <curfolder>";      // <curfolder>  shows you PROGRAM FILES
::msg '<curfolder>' . "  shows you ""<curfolder>""";  // <curfolder>  shows you "PROGRAM FILES"




More examples collected from the forum:

Code: Select all

run """C:\Program Files\AutoHotkey\AutoHotkey.exe""";

run '"C:\Program Files\AutoHotkey\AutoHotkey.exe"';

run quote("C:\Program Files\AutoHotkey\AutoHotkey.exe");

run("""C:\hasher.exe"" sha256 ""<curitem>"" > ""<curitem>.sha256""");

run """cmd"" /k ""D:\Portable Programs\XYplorer\wget\wget"" --help";

run '"cmd" /k "D:\Portable Programs\XYplorer\wget\wget" --help';

run "cmd /k ""%tmp%\xyMapShares.cmd""";

open quote("notepad")." ".quote(<curitem>);



- - -



Do some tests yourself:
go to C:\Program files

Test:

Code: Select all

::msg "<curpath>";                               // C:\PROGRAM FILES
::msg ""<curpath>"";                             // ""C:\PROGRAM FILES""
::msg """<curpath>""";                           // "C:\PROGRAM FILES"
::msg quote("<curpath>");                     // "C:\PROGRAM FILES"
::msg chr(34) .  "<curpath>" . chr(34);    // "C:\PROGRAM FILES"


::msg "I am in folder <curpath>";                // I am in folder C:\PROGRAM FILES
::msg "I am in folder "<curpath>"";              // "I am in folder "C:\PROGRAM FILES""
::msg "I am in folder ""<curpath>""";            // I am in folder "C:\PROGRAM FILES"
::msg "I am in folder " . quote("<curpath>"); // I am in folder "C:\PROGRAM FILES"  //note the dot to bind two strings


::msg "I am in ""Program Folder"" folder ""<curpath>"""; // I am in "Program Folder" folder "C:\PROGRAM FILES"



There are other threads about quoting too:

From TheQwerty > http://www.xyplorer.com/xyfc/viewtopic. ... 874#p62874



.
Last edited by Stefan on 22 Aug 2011 16:24, edited 4 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Scripting for beginners - how to start scripting?

Post by Stefan »

Scripting for beginners

Start:

See Donalds introducing into scripting: http://www.xyplorer.com/tour/index.php?page=scripting

In XYplorer help (press F1-button) you find under "Advanced Topics" something about scripting basics.
Find all scripting commands unter "Advanced Topics" in section "Scripting Command Reference".
Also take an look into "Variables" where you find an list of <XY Vars> (<curpath>, <curitem>, <date>,...)
You can do more automations by reading "Portable Openwith Menu (POM)" and "User-Defined Commands"

To start scripting think about an task you want to automate, then write it down in plain english, step-by-step
what is to do, then search for the right scripting command in help or forum and create your own script.

It's also good to search the script forum for an interesting script and try to modify them.
But be warned that the scripting syntax has changed over time.

At the first days of learning don't try too long at your own to solve an problem to not become frustrated,
just search the forum for an hint (especially the right ""quoting"" can be horror). Later on you should use the "Step Mode"
and double checking your code to track down your problem. Good is to let it be for an day or two and then come back to
your script and solve it.



Common questions:


To comment out an line or the rest of an line, use two slashes
//comment


To comment out an block of lines use
/*
lines of disabled code,
or description and comments
*/

- - -

The dot is used for concatenation like with PHP:

Code: Select all

"<curfile>" . "ext"    //==> fileext
"<curfile>" . ".ext"   //==> file.ext
- - -

The Debug window appears always if you use menu "Scripting > Try Script..." (no matter if "Scripting > Step Mode" is set or not)

- - -

Variables
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.
Read more about in XYplorer help (press F1-button) under "Advanced Topics > Scripting > Variables"

User variables are case-sensitive!

Code: Select all

$ITEM = "Do you see this?";
  msg "1: $item";   //1:
  msg "2: $Item";   //2:
  msg "3: $ITEM";  //3: Do you see this?

- - -

XYplorer scripting commands are often lower-case only.

Code: Select all

  $a ="a";

  if ("$a" like "A"){ msg "1: Yes, $a is like A<crlf>Wrong! but always TRUE because
           of wrong spelled parameter 'Like' as 'like'"; }
           else{ msg "1: No, $a is not like A"; }

  if ("$a" Like "A"){ msg "2: Yes, $a is like A"; }
           else{ msg "2: No, $a is not like A.<crlf>Note the correct spelled 'Like'"; }


- - -

Using internal command IDs (for commands found in the menu)


To execute an command found in the menu you have to cal the intern "Command ID"

To get an list of XYplorer intern "Command IDs" like #123; click on XYplorer menu "Help > Make List of Commands...

You will be prompted by an dialog:

Code: Select all

---------------------------------------------------------------------------------
                                        XYplorer
---------------------------------------------------------------------------------
Click OK to create a list of all commands, with IDs (used in Scripting)
and currently assigned keyboard shortcuts.

Format: Command Name [TAB] Command ID [TAB] Keyboard Shortcut

The list will be placed in the clipboard.
---------------------------------------------------------------------------------
                          OK                         Cancel
---------------------------------------------------------------------------------
Pressing [OK] will put this list into the clipboard and you can paste it to an plain text file.

This result will looks like:
File / To Clipboard / Item Name(s) #102 Ctrl+Shift+P
File / Rename Special / Batch Rename... #121 Shift+F2
File / Move/Copy/Backup To #150
View / Tab / Sort By / Size #323
Search for the command in question and use the number as command, like: #102;

This ID you can use like an script command,
just use #102;
as User Defined Command (UDC)
or with an Custom Toolbar Button (CTB)
or from XY address bar like ::#102;


- - -


Some scripting basics:


If/ElseIf/Else Blocks

Code: Select all

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

Code: Select all

// reality check
if (1 == 2) {
    echo "Help!";
    } else {
    echo "Relax.";
    }
See help "Advanced Topics > Scripting > If/ElseIf/Else Blocks" for more.


Statements

While Loops / While statement

Code: Select all

while (expression) {
    statement(s);
    }

Code: Select all

$count = 1;
  while($count < 4){
     msg "iteration no " . $count . " of three";
     incr $count;
   }
//Do-While loop

Code: Select all

$count = 1;
 while(true){
    msg "Hi you!";
    incr $count;
    if($count > 4){break;}
  }
See help "Advanced Topics > Scripting > While Loops" for more.




For Loop / For statement

For x = 1 To 10

Code: Select all

$Count = 1;
  while($Count <= 10)
  {
     //your code here
     incr $Count;
    //or $Count++;
  }


For x = 1 To 6 step 2

Code: Select all

$Count = 1;
  while($Count < 7){
     //your code here
     msg "Iteration No. $Count out of six (or of three only?)";
     incr $Count,,2;
  }


For x = 10 To 0

Code: Select all

$Count = 10;

  while($Count > 0){
     //your code here
     msg "Count down " . $Count;
     incr $Count,,-1;
  }else{
      msg "0, GO!";
  }

Code: Select all

// loop through the whole list
   //sel 1;  //means: go to first item in list
   while ( "<curitem>" != "" )
   {
     msg "<curitem>",1;
     sel "+1";
    }

For Each Item In ItemS Do
For Each File In FileS Do

Code: Select all

$ITEMS = "Eins, Zwei, Drei";

  foreach($item, $ITEMS, ",")
  {
    msg $item, 1;
  }

Code: Select all

$Array="";
   $Files = get("SelectedItemsPathNames", "|");

   foreach($file , $Files)
   {
     $Array = $Array . $file<crlf>;
   }

   text $Array;
- - -


Ask the user to continue

Code: Select all

  //ask the user to continue:
  $continue = confirm("Continue?");
  if ($continue==0){msg "Cancel pressed, will quit whole script."; end(1);}
  if ($continue==1){msg "OK pressed, will continue.";}
  msg "You will see this if you pressed OK";

Code: Select all

  //ask the user to continue:
  $continue = confirm("Continue?");
  if ($continue==0){
     //"Will do nothing and skip.";
     msg "Canceled by user";
  }else{
     msg "OK, we continue...";
     //your code here...
  }

Code: Select all

  //ask the user to continue:
  $continue = confirm("Continue?");
  if ($continue==1){
     msg "OK, we continue...";
     //your code here...
  }

Code: Select all

  //ask the user to continue:
  $continue = confirm("Continue or end the whole script?");
  if ($continue==0){ end(1)};
  msg "You will see this if you pressed OK";

Code: Select all

  //ask the user to continue:
  msg "Press OK to continue or Cancel to quit", 1;
  //if the user press the cancel button the script will end. Note the "1" parameter from the msg command.

  msg "You will see this if you pressed OK";
- - -

wait msec //sleep pause
wait 1000; //sleep for an second
wait 60000; //sleep for an minute

- - -


INI file handling

Code: Select all

$a='"test2"';
  echo $a;

  setkey quote($a),test,test,"%temp%\test.ini";

  getkey $b,test,test,"%temp%\test.ini";

  echo "$a<crlf>$b";
- - -

Is it a file or an folder?

Code: Select all

$IsFile = report ("{Dir False|True|Drive}",1); 
  msg $IsFile;  
  If ($IsFile=="True") {msg "It is a file"}else{ msg "no file"};

Code: Select all

$IsFolder = report ("{Dir Yes|No|Drive}",1);

Code: Select all

if (exists($curitem)==1)                    //==> check if this is an file (and NOT an dir/folder)
if (exists("<curpath>\sub-folder")==2) //==> check if an folder with this name already exists

- - -


How to Stop an script, exit an loop, end if condition:

Press the ESC-key
You can abort script execution at any time (if it is not an infinity loop) in XYplorer simply by pressing ESC
IF you have programmed an infinity loop, close XYplorer by using the windowsTM task manager

Code: Select all

//Break an while loop

while(1) //infinity loop
  {
     break;  //exit loop, see help to exit nested loops

     //example:
     if ($var == "") {break;}
  }

Code: Select all

//Break from an If statement

If ($x==$y)
  {
     end(1) //end the whole script
  }

Code: Select all

//Break from an If statement

If ($x==$y)
  {
     //do nothing
  }

Code: Select all

//Break from an If statement

If ($x==$y)
  {
     //do nothing
  }else{
    //do this
  }

Code: Select all

//end condition, [message], [scope=0]

end (getinfo("CountSelected")<1), "Nothing selected. Script quits.";
   msg "Do you see this dialog?<crlf>Then you had at least one item selected.";
See XYplorer help "Advanced Topics > Scripting Commands Reference > break" for more.
See XYplorer help "Advanced Topics > Scripting Commands Reference > end()" for more.




- - -

To watch the value of an variable while the script is running you may use the status() command.

Example:

Code: Select all

$a = 1;
  msg "Press OK and take an look on the status bar below.";
  while ($a <= 500)
  {
    status 'Var $a is now: ' . "$a    -  Press ESC to stop.";
    wait 100;
    $a++;
  }
  status "Script done!";
See XYplorer help "Advanced Topics > Scripting Commands Reference > status()" for more.
See XYplorer help "Advanced Topics > Scripting Commands Reference > assert()" for how to interrupts processing on certain conditions.

- - -

To see if/how an process is going on (and to take the load from the thread, so you see it still works)
you can use code like this below:


Like:
Downloading data.
Downloading data..
Downloading data...
Downloading data....
Use:

Code: Select all

 $s="";
 $Loop=0;
 $amount=30;

 while($Loop < $amount)
 {
 
    //your code here...

         //the trick:
         $s = $s . "."; if (strlen($s)>9){$s="";}
	 status "In process " . $s; wait 500;

    $Loop++;
 }
 status "Done.";

Like:
Downloading data |
Downloading data /
Downloading data -
Downloading data \
Use:

Code: Select all

 $Loop=0;
 $amount=30;
 while($Loop < $amount)
 {

   //your code here...


      //the trick:
      $SBT="/"; if($SBL >4){$SBL=1;}
      if($SBL==1){$SBT="/"}; if($SBL==2){$SBT="-"};
      if($SBL==3){$SBT="\"}; if($SBL==4){$SBT="|"};
      status "In process $SBT"; wait 100; incr $SBL;

  $Loop++;
 }
 status "Done.";

Like
T
T h
Th i
Thi s
This i
This i s
This is
Use this from serendipity at
http://www.xyplorer.com/xyfc/viewtopic. ... 5775:[code]
setting "AutoRefresh", 0; //don't disturb my status message during this script run

$ms= 400;
$str=1;
$text= "This is plain sample message";
$len= strlen ($text);
while ($len>0){
$newtext = substr ($text, 0,$str) . ' ' . substr ($text, $str, 1);
status $newtext;

wait ($ms);
$str++;
$len--;
}

wait 2000; //show it a little bit longer
[/code]
Last edited by Stefan on 08 Dec 2011 12:35, edited 9 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: How to use and execute an Script ?

Post by Stefan »

Some basic script as framework for your own script

Note that this are only short examples of the script commands to give you an helping hand.
Take an look into the excellent help file of XYplorer to read about more commands and also all possible parameters.



Get selected files

Get amount of all files in list:

Code: Select all

get("CountItems");
Get amount of selected files:

Code: Select all

msg get("CountSelected");
Check if at least one file is selected:
If no file is selected count is 0, so $Amount is 0 and less than 1,
so the IF statement is true and the end; command is executed.

Code: Select all

$Amount = get("CountSelected");
   if ($Amount < 1)  {  msg "Please select at least one file";    end 1;      }
Hint:
the command "end 1" is an trick.
The command end terminates a running script and the syntax is like end condition
Well, since 1 is true by definition the condition is true and end is executed. Voila.


Or select all files for the user if no file is selected:

Code: Select all

//If nothing is selected, select all first:
  $CountSelected = getinfo("CountSelected");
  IF ($CountSelected<1){sel a;} //Select all.
- - -

Get path\name of all selected files:

Code: Select all

$FILES = get("SelectedItemsPathNames");
   msg $FILES; 
Get names only of all selected files:

Code: Select all

$FILES = get("SelectedItemsNames");
   msg $FILES; 
Default separator parameter is an line break:
"SelectedItemsNames", [separator=CRLF]
so each file has an trailing linebreak.
Result:
file1.ext
file2.ext
file3.ext

You can overwrite this default by using your own separator like:

Code: Select all

$FILES = get("SelectedItemsNames", "|");   msg $FILES; 
Result: file1.ext|file2.ext|file3.ext|

$FILES = get("SelectedItemsNames", ", ");   msg $FILES; 
Result: file1.ext, file2.ext, file3.ext, 
To enclose each file in quotes use:

Code: Select all

$FILES = get("SelectedItemsNames", """ """);   msg $FILES;
Result: file1.ext" "file2.ext" "file3.ext

but add leading and trailing quote signs also like:
$FILES = """" . get("SelectedItemsPathNames", """ """) . """";
or
$FILES = chr(34) . get("SelectedItemsPathNames", """ """) . chr(34);
or
$FILES = quote(get("SelectedItemsPathNames", """ """));
Result: "file1.ext" "file2.ext" "file3.ext"

And quotes and coma in combination:
$FILES = quote(get("SelectedItemsPathNames", """, """));
Result: "file1.ext", "file2.ext", "file3.ext"
- - -

An other powerful command to get an list of files is report()
report([template], [itemlist], [header], [footer])

template
Defines the layout of one line (file record); for each reported file one line is created based on this template.
If missing or empty: Take the current list data as is.
Template tokens are for example: {Name}, {Basename}, {Ext}, {Size}, {Created}, {Modified}, ...

itemlist
What to report on:
0: [default] all current list items
1: all currently selected list items
[else]: items in a pipe(|)-separated list of items (full path)
Examples

Code: Select all

text report();
Displays the current file list "as is" in a multiline textbox.

text report(,1);
Displays the selected file only due parameter 1.

text report("{Fullpath}",1);
Result: D:\rive\to

text report("{Fullname}",1);
Result: D:\rive\to\file1.ext

text report("{name}",1);
Result: file1.ext

text report("{basename}_backup.{ext}",1);
Result: file1_backup.ext
You can also quote each single file by adding the quotes to the template:
Note that the quotes are escaped by doubling them.

Code: Select all

text report("""{name}""",1);
Result: "file1.ext""file2.ext""file3.ext"
Furthermore you can add signs and even linebreaks after each file:

Code: Select all

text report("""{name}""|",1);
Result: "file1.ext"|"file2.ext"|"file3.ext"|

text report("""{name}"", ",1);
Result: "file1.ext", "file2.ext", "file3.ext",

text report("""{name}"",<crlf>",1);
Result: 
"file1.ext", 
"file2.ext", 
"file3.ext",


text report("""{name}.bak"", ",1);
Result: "file1.ext.bak", "file2.ext.bak", "file3.ext.bak",

or even:
(using the full syntax: report([template], [itemlist], [header], [footer]) )

Code: Select all

text report("COPY ""{fullname}"" ""{fullname}.bak""<crlf>",1,"@ECHO OFF<crlf>", "<crlf>ECHO done!");

Result: 
@ECHO OFF
COPY "D:\rive\to\file1.ext" "D:\rive\to\file1.ext.bak"
COPY "D:\rive\to\file2.ext" "D:\rive\to\file2.ext.bak"
COPY "D:\rive\to\file3.ext" "D:\rive\to\file3.ext.bak"
ECHO done!

as base for an DOS batch file.

- - -

Hint:
to get rid of the last delimiter you can use substr() command.
substr(string, [start], [length])

start: Start of returned part; defaults to 0, first position is 0.
length: Length of returned part. If length is negative, then that many characters will be omitted from the end of string.

Code: Select all

$files =  report("""{name}"", ",1);
  $files = substr($files, 0, -2);
  //Result: "file1.ext", "file2.ext", "file3.ext"
Note that the amount of the length parameter depends how many
signs you want to remove from the end. Here two: coma and space.

You could also use RegExReplace() command, but regular expressions are by nature much slower:

Code: Select all

$files =  report("""{name}"", ",1);
  $files = regexreplace($files, "(.+)..", "$1");
  //Result: "file1.ext", "file2.ext", "file3.ext"

- - -

Get the BASE of the file name only.


The base is the part of the file name without the extension only.

For example: "D:\rive\path\to\base.ext"


If you use

::msg get("SelectedItemsPathNames");
or
::msg get("SelectedItemsNames");

you have to write code to extract the wanted parts from that full strings.
(see two post below: "Split file name into base and extension")





To just get the base of the selected items use

$myBaseNames = report("{basename}"|,1);
text $myBaseNames;

Here each item is separated by an '|' to fit the standard of the foreach loop.
The '1' indicates to report only the SELECTED items.



You could also use for example something like:

Code: Select all

 $array="";
 while(true){
  if ("<curbase>"==""){break;}
  $array = $array . "<curbase>|";
  //msg "<curbase>",1;
  sel "+1";
 }
 text $array;
 //foreach($item, $array){ ...here do something for each item from the array }
"<curbase>" gets you just the base name of the selected item.
The while() loop loops endless till there is no item anymore to report and store each base into an var, separated by an '|'.
The 'text' command shows you an message box to provide you the content of the $array.

See the help > "Advanced Topics > Variables" for more of that "<curbase>" - XYplorer Native Variables

- - -

Code: Select all

v11.40.0202 - 2012-08-17 20:58
    + Scripting got a new function.
      Name:   getPathComponent
      Action: Returns the specified component of a path.
Example:

Code: Select all

foreach($ITEM, get("SelectedItemsNames", "|") ){
    msg getpathcomponent($ITEM, "base"),1;
  }
- - -
Last edited by Stefan on 12 Sep 2012 09:35, edited 8 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: How to use and execute an Script ?

Post by Stefan »

Do something for each item

For Each Item In Items Do


For each item in list view do:

Code: Select all

   //first select first item in list:
   //sel 1;
   
   //or ask the user to select one:
   if (get("CountSelected")<1){end 1, "Please select one file first!<crlf>Script quits.";}

  //Loop:
   while ( <curitem> != '' )
   {
       msg "<curitem>",1;
       sel "+ 1";
    }

- - -

By collecting the files in an var first


For each file in filelist do:

Code: Select all

if (get("CountSelected")<1){end 1, "Please select at least one file first!<crlf>Script quits.";}

  //"SelectedItemsNames", [separator=CRLF], [pane=a]
  $filelist = get("SelectedItemsNames");

  //foreach($variable, listoftokens, [separator=|]) 
  foreach($MyNewVariable, $filelist, "<crlf>")
  {
     msg $MyNewVariable,1;
  }
pitfall:

Code: Select all

Please note the the default separator parameter for
get("SelectedItemsNames") is "<crlf>"
and for foreach() it is "|"

So take care to use 
get("SelectedItemsNames") 
foreach($var1, $var2, "<crlf>")

or use
get("SelectedItemsNames", "|") 
foreach($var1, $var2)

or even use something like:
get("SelectedItemsNames", "?") 
foreach($var1, $var2, "?")

or
get("SelectedItemsNames", "<crlf>") 
foreach($var1, $var2, "<crlf>")
or
get("SelectedItemsNames", "|") 
foreach($var1, $var2, "|")

it only matters that the delimiter is the same for all commands.
- - -

$Array="";
$FileS = get("SelectedItemsPathNames", "|");

foreach($file , $FileS)
{
$Array = $Array . $file<crlf>;
}
text $Array;

- - -

For Each Item In Items Do

Code: Select all

  $ITEMS = "Eins, Zwei, Drei";
  foreach($item, $ITEMS, ",")
  {
    msg $item,1;
  }
- - -

For Each Char In Chars Do

Code: Select all

   $STRING = "XYplorer";
   $LOOPs = strlen($STRING);
   $ITERATION=0;
   $OUTPUT="";
   
   while($ITERATION <= $LOOPs)
   {
      $Token = substr($STRING, $ITERATION, 1);
      if ($Token==""){break;}
      msg $Token,1;
      incr $ITERATION;
   }

- - -

For Each Line In LineS Do

I read a file in a variable.
Now I would like to scan over the lines and, based on the line contents, include or exclude a line
from being copied into another variable (which I will later save into another file).

Code: Select all

//For Each Line In LineS Do

  //collect a file content into a variable:
  $INPUT = readfile("<xydata>\xyplorer.ini");  // or nowadays just "<xyini>"
  text $INPUT;

  //initialize the $OUT var or you get "$OUT" as literal text into the output too:
  //(this could also be used to write a header line for example)
  $OUT = "";

  //for each part (put into "$myVar") from big content (parts are separate here by line break, means "for each line"):
  foreach( $LINE , $INPUT , "<crlf>" ){

         //search for a pattern:
         //regexmatches( string, pattern, [separator=|], [matchcase=0])
    $TMP = regexmatches( $LINE , "backup"                             );

    //if pattern matched, collect the current processed line into a new variable $OUT:
    if( $TMP !=  "" ){ $OUT = $OUT . $LINE . "<crlf>"; }

   }
   //test to see what we have collected:
   text $OUT;
 
  //write collection from $OUT to a new text file:
  //writefile(filename, data, [on_exist], [mode])
  //writefile( "%temp%\filename.txt", $OUT) ;


Maybe regexmatches() was not the best example command to explain the foreach() loop,
since regexmatches() can do my example on its own:

Code: Select all

  $INPUT   = readfile("<xydata>\xyplorer.ini");
  $Matches = regexmatches( $INPUT , "^.+tweak.+$" , "<crlf>");
  text $Matches;


But with foreach() you can do more different things.

For example you can add an alternative ELSE part:

Code: Select all

  $INPUT = readfile("<xydata>\xyplorer.ini"); 
  $OUT   = "";
  $BAD   = "";

  foreach($LINE,$INPUT,"<crlf>"){
       
       $FirstSign = substr( $LINE , 0 , 1 );
         
       if( $FirstSign Like ";" ){ 
             $OUT = $OUT.$LINE."<crlf>"; 
       }else{
             $BAD = $BAD.$LINE."<crlf>";
       }
  }
         
  text $OUT;
  text $BAD;

Another example, collecting three more lines after each match:
(Example POC code only. Needs to be rewritten with more seriousness)

Code: Select all

$INPUT = readfile("<xydata>\xyplorer.ini"); 

  $OUT=""; $counter=0; $continue=false;

  foreach($LINE,$INPUT,"<crlf>"){

      $TMP = regexmatches($LINE, "tweak");

      //If regex matched, set $continue to true,
      //IF $continue equals true, collect the next line too,
      //untill $counter is greater 2, then stop collecting additional lines.
      if ($continue == true){
            $OUT = $OUT.$LINE."<crlf>"; 
            $counter++;
            if($counter > 2){$counter=0; $continue = false;}
      }

      if($TMP!=""){ 
             $OUT = $OUT.$LINE."<crlf>"; 
             $continue = true;
      }
  }
  text $OUT;  

Or a more simple script:

Code: Select all

  $INPUT = get("SelectedItemsNames"); 
  $count = 1;

  foreach( $Item , $INPUT , "<crlf>" ){
     msg "$count:<tab>$Item",1;
     $count++;
 }
Note:
get("SelectedItemsNames"); has on default CRLF as separator:
"SelectedItemsNames", [separator=CRLF], [pane=a]

Whereas foreach() has on default the pipe symbol "|" as separator:
foreach($variable, ListOfTokens, [separator=|], [flags], [MsgOnEmpty]) {
statement(s);
}


So always take care to use one and the same separator on both commands.
Either leave the default "<crlf>" separator on get() and explicit set "<crlf>" for foreach(),
OR use "|" with get() as an own set separator, and you don't have to add an separator to foreach() as this is the default there.


- - -

For Each Folder In Sub Folders Do (recursive sub-folders)

One way would be to utilize folderreport() to get a list of sub folders.
And then use foreach() to iterate across each folder.

Example:

Code: Select all

   $ListOfFolders = folderreport("dirs", "r", , "r" );

   $OUT = "";
   foreach($Folder, $ListOfFolders, "<crlf>"){

        //Example use: do something for each sub-folder recursive:
        $TMP = listfolder($Folder, , , "<crlf>");
        if($TMP!=""){$OUT = $OUT . $TMP .  "<crlf>";}

   }
   text $OUT;
Note that using listfolder() here is a bad example as folderreport() can get the same output alone.
But it is used as an example only. You may find better use for recursively sub folder walk.



- - -
Last edited by Stefan on 28 Jun 2013 15:53, edited 4 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Split path parent folder file name base extension

Post by Stefan »

Theme:
Split path into folders
Split file name into base and extension


Note: on top you will find older ways of doing this. Scroll to the end of this post to see how to do it today.

- - -

Code: Select all

Q: How can i get the parent folder?

A: There is no script command to just get the parent folder.
    You have to use e.g. <curpath> and split them by using gettoken()

    $path = "<curpath>";
    $ParentFolder = gettoken($path, -1, "\");

   msg $ParentFolder;

- - -

Code: Select all

/*
Q: How can i split base name and extension?
A: Here is one way (note this is an old way, see below for the new one)
*/

global $FileName, $InStrRev, $Sign;
   
    $FileName = "This is No. 1 of my File name.ext"
   
    //split extension:
    $Sign = "."; sub "_InStrRev";
    $Base = substr($FileName, 0, $InStrRev -1);
    $Exte = substr($FileName, $InStrRev);
   
   
"_InStrRev" //Function
/*
  "_InStrRev" gives last possition of $Sign in $FileName
  Syntax: $Sign = ".";  sub "_InStrRev";
  Return: last pos of $Sign in $FileName
*/
global $FileName, $InStrRev, $Sign;
   $Index=0;
   while($Index < strlen($FileName))
   {
     If ($FileName==""){break;}
     $check = strpos( $FileName, "$Sign", strlen($FileName) - $Index );
     If ($check > -1){$InStrRev = $check +1; break;}
     $Index++;
   }

- - -

Code: Select all

/*
Split path file name into parts to an base extension array (note that this is an older way to do this
Here with some error handling
*/


//set array  to test string:
$ARRAY = "C:\Documents and Settings\Administrador\Meus documentos\XYplorer\Contas a receber.docx.bak";
   
  //split the string into parts
  //assign array elements to $Vars:
  $DRIVE             = gettoken( $ARRAY,   1, "\");
  $TopFolder         = gettoken( $ARRAY,   2, "\");
  $SubFolder         = gettoken( $ARRAY,   3, "\");
  $GrantParentFolder = gettoken( $ARRAY, - 2, "\");
  $ParentFolder      = gettoken( $ARRAY, - 1, "\");
  $UBound            = gettoken( $ARRAY,   "count" , "\");
  $FILE              = gettoken( $ARRAY,   $UBound , "\");
   
   //split FileName into base and extension:
   $Base = "not an file";
   $Exte = "not an file",
   If ($FILE != "")
    {
     If (strpos($FILE, ".") > 0)
     {
      while($Index < strlen($FILE))
       {
         $check = strpos( $FILE, ".", strlen($FILE) - $Index );
         If ($check > -1){$InStrRev = $check +1; break;}
         $Index++;
       }
     $Base = substr($FILE, 0, $InStrRev -1);
     $Exte = substr($FILE, $InStrRev);
     }
    }
   
   
  //test output:
  text Drive: <tab 2> $DRIVE<crlf>
       TopFolder: <tab> $TopFolder<crlf>
       GrantParent: <tab> $GrantParentFolder<crlf>
       ParentFolder: <tab> $ParentFolder<crlf>
       File: <tab 2> $FILE<crlf>
       Base: <tab 2> $Base<crlf>
       Ext: <tab 2> $Exte;

/*
Test Output for "C:\Documents and Settings\Administrador\Meus documentos\XYplorer\Contas a receber.docx.bak"
Code:
Drive:          C:
TopFolder:      Documents and Settings
GrantParent:    Meus documentos
ParentFolder:   XYplorer
File:           Contas a receber.docx.bak
Base:           Contas a receber.docx
Ext:            bak
*/


- - -

Split path into folders
Split file name into base and extension
An newer way

Note:

Code: Select all

This needs v10.60.0120 - 2011-12-06 13:42
    + SC strpos enhanced: Now negative start positions are supported to begin searching from the start position leftwards.

Code: Select all

//input:
$a = "<curitem>";

  //get drive letter and top main folder:
  $Drive        = gettoken($a, 1, "\");
  $TopFolder    = gettoken($a, 2, "\");
   
  //get the path only:
  $LastBS       = strpos($a, "\", -1);
  $path         = substr($a,     0     , $LastBS +1);
  $file         = substr($a, $LastBS +1,           );
   
  //split file name into base name and extension:
  $LastDot      = strpos($file, ".", -1);
  $base         = substr($file,   0        , $LastDot);
  $ext          = substr($file, $LastDot +1,         );
   
  //get the parent folder name, and the grandparent too:
  $ParentFolder = gettoken($a, -2,"\");
  $SecondParent = gettoken($a, -3,"\");
    
     
//debug output:
  msg Orig: $a    <crlf>
      Drive: $Drive <crlf>
      Top: $TopFolder <crlf>
      Path: $path <crlf>
      File: $file <crlf>
      Base: $base <crlf>
      Ext: $ext <crlf>
      Parent: $ParentFolder <crlf>
      Second: $SecondParent;

Code: Select all

/* an slightly  other way to split file name into base name and extension      */
/* Note: This strpos() syntax needs XYplorer v10.60.0120 - 2011-12-06 or above */

$selFiles = get("SelectedItemsNames", "|");

  foreach($file, $selFiles){

         $base = substr($file, 0, strpos($file, ".", -1) ); 
         msg $base,1;

         $ext = gettoken($file, -1, "."); 
         msg $ext,1;

   }
- - -
See History.txt

Code: Select all

v11.40.0202 - 2012-08-17 20:58
    + Scripting got a new function.
      Name:   getPathComponent
      Action: Returns the specified component of a path.
      Syntax: getpathcomponent([path], [component])
        path:     The path to parse; can be a folder or a file.
                  Defaults to the current folder or file.
        component: The component to return; can be any of the following:
          drive:  the drive or share
          path:   [default] the path without any file
          parent: the parent folder
          file:   the file without path
          base:   the file without path and without extension
          ext:    the extension
      Notes:
        Paths are returned unslashed.
      Examples:
        echo getpathcomponent(, "file"); //current item without path
        echo getpathcomponent("E:\x\y.txt", "ext");   // txt
        echo getpathcomponent("E:\x\y.txt", "base");  // y
        echo getpathcomponent("E:\x\y.txt", "file");  // y.txt
        echo getpathcomponent("E:\x\y.txt", "parent");// x
        echo getpathcomponent("E:\x\y.txt", "path");  // E:\x
        echo getpathcomponent("E:\x\y.txt", "drive"); // E:


v11.40.0204 - 2012-08-18 21:11
    + SC getPathComponent enhanced: Now you can return components by 
      their position index. Negative indices can be used to refer to the 
      position from the right end.
      Syntax: getpathcomponent([path], [component], [index=1])
        component: The component to return:
          component: The component referred to by index.
        index:  The index of the component to return. Only used if 
                component is "component". The first component is 1, the 
                last component is -1.
                Invalid indices or index 0 (zero) return nothing.
      Notes:
        UNC paths are stripped off the leading "\\" before applying the 
        index.
      Examples:
        echo getpathcomponent("E:\x\y.txt", "component");     // E:
        echo getpathcomponent("E:\x\y.txt", "component", 1);  // E:
        echo getpathcomponent("E:\x\y.txt", "component", 2);  // x
        echo getpathcomponent("E:\x\y.txt", "component", 3);  // y.txt
        echo getpathcomponent("E:\x\y.txt", "component", 4);  // <nothing>
        echo getpathcomponent("E:\x\y.txt", "component", -1); // y.txt
        echo getpathcomponent("E:\x\y.txt", "component", -2); // x
        echo getpathcomponent("E:\x\y.txt", "component", -3); // E:
        echo getpathcomponent("E:\x\y.txt", "component", -4); // <nothing>
        echo getpathcomponent("\\Mars\Venus", "component");   // Mars


v11.40.0205 - 2012-08-19 12:52
    * SC getPathComponent: Now any trailing colon (:) is removed from the
      returns, so "drive" will now return the drive letter alone: "E" 
      instead of "E:".
      Also now "/" is supported as component separator.

v11.40.0206 - 2012-08-20 12:07
    + SC getPathComponent enhanced: Added two further values for the 
      "component" parameter.
      Syntax: getpathcomponent([path], [component], [index=1])
        component:
          count:    The count of components.
          server:   The server in case of an UNC path, else the drive.
      Examples:    
        echo getpathcomponent("\\Mars\Venus", "count");   // 2
        echo getpathcomponent("\\Mars\Venus", "server");  // Mars

Example:

Code: Select all

foreach($ITEM, get("SelectedItemsNames", "|") ){
    $B = getpathcomponent($ITEM, "base");
    $E = getpathcomponent($ITEM, "ext");
    msg "You could e.g. rename $ITEM<crlf>to $B.bak.$E",1;
  }
- - -
Last edited by Stefan on 12 Sep 2012 09:42, edited 5 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Acronyms and RegEx Hints

Post by Stefan »

For Acronyms see The XYplorer Roadmap
or the History.txt from License Lounge or direct link
Acronyms

4KN 4 Key Navigation
6KN 6 Key Navigation
AB Address Bar
AC Access Control
ADP Application Data Path
AL Action Log
BC Breadcrumbs
BV Branch View
CAS Click and Search
CAT Click and Tag
CC Custom Columns
CEA Custom Event Actions
CFA Custom File Associations
CFI Custom File Icons
CKS Custom Keyboard Shortcuts
CLI Command Line Interpreter
CTB Custom Toolbar Buttons
DFF Duplicate File Finder
DP Dual Pane
DUB Droppable User Buttons
FP Floating Preview
FSP Full Screen Preview
FV Flat View
FVS Folder View Settings
FVSVF Folder View Settings with Visual Filters
HPT History per Tab
ICF Instant Color Filters
IP Info Panel
ITT Interface Translation Tool
KS Keyboard Shortcut
LFB Live Filter Box
LBM Loose Boolean Match
MBV Multi Branch View
MCN Mouse Click Navigation
MFS Multi Field Search
MDBU Mouse Down Blow Up
MOBU Mouse Over Blow Up
MLS Multilingual Support
MRU Most Recently Used
MSR Multi Script Resource
MT Mini Tree
NP Navigation Panel
PCSO Permanent Custom Sort Order
PAF Paste and Find
PF Paper Folder
PFA Portable File Associations
PFI Portable File Icons
PML Portable Metadata Layouts
POM Portable Openwith Menu
PV Permanent Variable
QNS Quick Name Search
QS Quick Search
QSB Quick Search Bar
RB Recycle Bin
RFO Rich File Operation
SB Status Bar
SC Scripting Command
SRC Search Results Caching
TAF Type Ahead Find, Find As You Type
TB Toolbar
TNC Tree Node Crumbs
TPT Tree Path Tracing
TSF Type Stats and Filter
UB User Button
UDC User-Defined Commands
VF Visual Filter
VFO Virtual Folder
VLP Volume Label Paths
Time: v14.50.0300 - 2014-11-10 12:00


My little RegEx Hints:

Code: Select all


Expression:
. (a dot)		- one any single character (char, digit, sign, blank)
a 		- the char "a", abc - the string "abc"  literally
(aa|bb)		- one of the alternatives "aa" or "bb"
[ab3-] 		- one from list ("a" or "b" or "3" or "-")
[^ab3-] 	- one sign but none from the list
[a-z] 		- one from the range "a", "b" till "z"
3 		- the digit "3", 2013 - the number "2013" literally
[6-9] 		- one any digit from the range "6", "7" till "9"
\w 		- one any letter, digit or underscore
\d 		- one any digit from "0", "1" till "9"
\s		- one blank, -	- one hyphen literally
_		- one underscore, \.	- one dot literally
(...) 		- group an expression to apply operators or for backreference
\W \D \S	- the opposite of lower case \w \d \s 
Quantifier:
* 		- match greedy zero or more times the previous expression
+ 		- match greedy one or more times the previous expression
{3} 		- match exactly 3 times the previous expression
{3,} 		- match greedy but at least 3 times the previous expression
{3,5} 		- match greedy 5, or 4, or 3 times the previous expression
? 		- behind * or + or {,} will limit the match to as few as possible (non-greedy)
? 		- behind an expression matches on zero or one occurrence
Bounderies:
\b 		- match at word boundary, \A or ^ - at start, \Z or $ - at end of file name
Meta signs:
\ 		- use the escape character "\" to match an meta sign itself
Meta signs are: ., \, (, ), [, {, }, +, *, ?, |, ^, $


backreference replacement:
$1 		- insert here what was matched by first (...)-group from left
$2 		- insert here what was matched by second (...)-group
$3 ... $9 	- insert what was matched by third, fourth, fifth,... till ninth group
Groups could be nested: ($1) ($2) ($3($4($5...))) ($6)
(Note: some flavors use \1 syntax instead of $1)

Find more information:
http://www.regular-expressions.info/reference.html

Find me: Regular Expressions RE RegEx RegExp Rex gerippe barebone




.
Last edited by Stefan on 01 Apr 2013 00:45, edited 2 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: How to use and execute a script ?

Post by Stefan »

Hold this thread clean, no questions, no answers. Use an other thread to discuss things. Thanks.

XYplorer files, location and other information

This post is based on another thread over there > http://www.xyplorer.com/xyfc/viewtopic. ... 913#p51913


For reference, here the start of an wiki article i want to do for an long time,
so all the cluttered info are collected at one single place :


(Sorry, there are more and more infos but no really structured written. :oops:
I will collect here all details and once, maybe even in this life, i will made an real how-to post :whistle: )




Generally XYplorer have two main folders:
1. "Application Path" - aka "Program Folder", the directory with the application exe --- For scripting usage: <xypath>
2. "Application Data Path" - aka "Data Folder", the directory with the application (configuration) data --- For scripting usage: <xydata>

The "Application Data Path" is always there where the "XYplorer.ini" is found first.
So to prevent yourself from mistakes be sure to have only one file named "XYplorer.ini" in the folders mentioned below.

For No-Install portable-use the "Application Data Path" is an sub-folder "Data" in the XYplorer program folder.
(In the past it was by default the same main "XYplorer"-folder where the XYplorer.exe was located too, but this is undesirably this days)
For an Installation the "Application Data Path" is an "XYplorer"-named folder located at your Windows default %appdata% folder.


By the way,
you can setup XYplorer to use two other folders too:
"Scripts Path" (see: XYplorer.ini >> ; Tweak: absolute or relative to app path >> ScriptsPath= )
and "Thumbs Cache Path" (see: Tools > Configuration > Thumbnails)
At default they are both in the "Application Data Path" too.


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

There are two different download packages for your selection


http://www.xyplorer.com/download.php


Installer Package (ZIP archive, 2,308 KB)
Recommended for most users.
Includes installer and uninstaller.


If you prefer to extract the program files manually choose one of the following packages:
No-Install Package (ZIP archive, 2,711 KB)
Extract to any folder and run the application.



Please note that both packages contain the same.
Both are "portable" ("green") application and works exactly the same.

The difference of the "Installer Package" is the presence
of startup.ini which has become necessary due to UAC.
The setup copies the XYplorer Data Folder to your user profil
and the startup.ini points to that data folder. This refer is relative to the user,
so each logged in user will get his own XYplorer Data Folder in his profil.
Also the installer helps you on creating the XYplorer Application Folder
and an start menu entry for you. Also it provides an uninstaller.
Please note that the nature of an installer is to leave tracks behind on an PC.
Refer to this FAQ entry to switch your installed to an portable version.

The "No-Install Package" is portable per se anyway.
The XYplorer Data Folder is here created on first launch as an sub folder "Data".
There is nothing changed to your files or registry by using this version.
You have to remember on which place you have un-packed it yourself.
Refer to this FAQ entry to switch your portable to an installed version.



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

Some deeper background informations


Portable setup:

Code: Select all

v8.80.0060 - 2010-01-27 22:50
    * Startup, App Data Path: Now, if
      - no app data path is set by command line
      - AND (no startup.ini is found in app path OR startup.ini contains no app data path)
      - AND no XYplorer.ini is found in app path
      then the app data path is auto-set to <xypath>\Data.
      Reason: Keeping the variable user data together in one place is a
      good idea. Even in portable installations which is the typical
      context for this scenario.
So we should have this folder structure:

Drv:\path to\XYplorer\Data\
Drv:\path to\XYplorer\RECYCLER\
Drv:\path to\XYplorer\CatalogDefault.dat
Drv:\path to\XYplorer\LicenseXY.txt
Drv:\path to\XYplorer\ReadmeXY.txt
Drv:\path to\XYplorer\TipOfTheDay.htm
Drv:\path to\XYplorer\XYplorer.chm
Drv:\path to\XYplorer\XYplorer.exe
Drv:\path to\XYplorer\XYplorer.url

Drv:\path to\XYplorer\Data\FindTemplates\
Drv:\path to\XYplorer\Data\NewItems\
Drv:\path to\XYplorer\Data\Panes\
Drv:\path to\XYplorer\Data\Scripts\
Drv:\path to\XYplorer\Data\action.dat
Drv:\path to\XYplorer\Data\catalog.dat
Drv:\path to\XYplorer\Data\fvs.dat
Drv:\path to\XYplorer\Data\ks.dat
Drv:\path to\XYplorer\Data\lastini.dat
Drv:\path to\XYplorer\Data\tag.dat
Drv:\path to\XYplorer\Data\udc.dat
Drv:\path to\XYplorer\Data\XYplorer.ini

(Note: you may have not all of that *.dat files, depending on your use of XYplorer)

Example Info from "Help > Various Information"
App: X:\xyplorer\XYplorer.exe
Ini File: X:\xyplorer\Data\XYplorer.ini
App Data Path: X:\xyplorer\Data\
Scripts Path: X:\xyplorer\Data\Scripts\
Thumbs Cache Path: X:\xyplorer\Data\Thumbnails\

- - - - -

"old portable setup"

Before v8.80.0060 - 2010-01-27,
all sub-folders and files of
"Drv:\path to\XYplorer\Data\"
was stored in the
"Drv:\path to\XYplorer\"-main folder too:

Drv:\path to\XYplorer\FindTemplates\
Drv:\path to\XYplorer\NewItems\
Drv:\path to\XYplorer\RECYCLER\
Drv:\path to\XYplorer\Scripts\
Drv:\path to\XYplorer\action.dat
Drv:\path to\XYplorer\catalog.dat
Drv:\path to\XYplorer\CatalogDefault.dat
Drv:\path to\XYplorer\fvs.dat
Drv:\path to\XYplorer\ks.dat
Drv:\path to\XYplorer\lastini.dat
Drv:\path to\XYplorer\LicenseXY.txt
Drv:\path to\XYplorer\ReadmeXY.txt
Drv:\path to\XYplorer\tag.dat
Drv:\path to\XYplorer\TipOfTheDay.htm
Drv:\path to\XYplorer\udc.dat
Drv:\path to\XYplorer\XYplorer.chm
Drv:\path to\XYplorer\XYplorer.exe
Drv:\path to\XYplorer\XYplorer.ini
Drv:\path to\XYplorer\XYplorer.url


But this is not recommended and supported anymore.

To went from "old portable setup" to the "new portable setup" you may do this:
- use menu "Go > Go to Application folder"
- create an new folder "Data"
- right click on the Data-folder and chose Explorer to start WinExplorer
- close XYplorer
- in WinExplorer, go one hierarchy up
--- and move the above mentioned files and folders to "Data"
- start XYplorer
- check XYplorer menu "Help > Various Information" if "Ini file" and "App Data Path" points to the right folder


--- --- ---


Non-Portable / Installation / Multi user mode:
grindax wrote:For Windows XP it was OK to have everything in one folder. But for Windows Vista and Windows 7, because of UAC and security permissions trickiness involved in writing to the 'Program Files' folder, the preferred location for settings and configurations is the user's own profile directory.

Thus in XYplorer you have the Application Folder, which houses the XYplorer program files (and which gets written to following a UAC prompt when installing the software), and the Application Data Folder which houses everything configuration-related.
If you Install XYplorer by using the setup, you will be asked: "for anyone" or "just for me".
The difference is the start menu used; that for "All Users" or just your own start menu only.
If you chose "for anyone" and IF an second user would use XYplorer on your PC too, and the startup.ini is present,
this user will get his own "Data" folder, because the Windows var "%appdata%" is relative to different users.


Warning about Installer:
if you later de-install XYplorer again, all your own folder and files in data-folder are deleted too!
(The own files in program folder seams to remain)
So make an backup before de-installing IF you want to keep some own files (or at least your register details in the XYplorer.ini)



The program file XYplorer.exe is stored in the path you selected from the install dialog.
On default to "C:\Program Files\XYplorer" (Vista/Win7 UAC will ask you to allow this creation)

Installer package will create an startup.ini next to the XYplorer.exe.
((The portable package have this not (but one could create them on there own)))

If you have an startup.ini next to the XYplorer.exe good changes are
(If the startup.ini contains an valid path to an other dir) that your "Data"-subfolder
is not in the same folder as the XYplorer.exe
but in your Windows AppData-folder for example on default setup.


So we should have this folder structure:

Drv:\path to\XYplorer\RECYCLER\
Drv:\path to\XYplorer\CatalogDefault.dat
Drv:\path to\XYplorer\LicenseXY.txt
Drv:\path to\XYplorer\ReadmeXY.txt
Drv:\path to\XYplorer\startup.ini (which points to: Path=%appdata%\XYplorer )
Drv:\path to\XYplorer\TipOfTheDay.htm
Drv:\path to\XYplorer\XYplorer.chm
Drv:\path to\XYplorer\XYplorer.exe
Drv:\path to\XYplorer\XYplorer.url


%AppData%\XYplorer\FindTemplates\
%AppData%\XYplorer\NewItems\
%AppData%\XYplorer\Panes\
%AppData%\XYplorer\Scripts\
%AppData%\XYplorer\action.dat
%AppData%\XYplorer\catalog.dat
%AppData%\XYplorer\fvs.dat
%AppData%\XYplorer\ks.dat
%AppData%\XYplorer\lastini.dat
%AppData%\XYplorer\tag.dat
%AppData%\XYplorer\udc.dat
%AppData%\XYplorer\XYplorer.ini


(Note: you may have not all of that *.dat files, depending on your use of XYplorer)



The size of an empty "startup.ini" is 18 byte only,
and should be 34 byte if it would contain the following usually standard:
[Appdata]
Path=%appdata%\XYplorer


%appdata% BTW is a system environment variable and points too:
On Vista/Win7: C:Users\<your name>\AppData\Roaming\
On Win2000/XP: C:\Documents and Settings\<UserName>\Application Data\

So you should have one of this folders:
On Vista/Win7: C:Users\<your name>\AppData\Roaming\XYplorer\
On Win2000/XP: C:\Documents and Settings\<UserName>\Application Data\XYplorer\

((Where here "XYplorer" contains the same folders and files as the "Data"-folder does as shown above at portable mode))


Tip: open a command line window (DOS-Box) and type 'set <enter>' to see all system environment variables.
C:\>SET
ALLUSERSPROFILE
APPDATA
CommonProgramFiles
CommonProgramFiles(x86)
CommonProgramW6432
COMPUTERNAME
HOMEDRIVE
HOMEPATH
ProgramData
ProgramFiles
ProgramFiles(x86)
ProgramW6432
SystemDrive
SystemRoot
TEMP
TMP
USERNAME
USERPROFILE
windir
and some more...




Note:
If you are on Vista/Win7
AND your "Data" folder is by "mistake" under "Program Files" too
but there you have no write access to on default,
then Windows will redirect your writings silently to
"C:\Users\<username>\AppData\Local\VirtualStore\Program Files\XYplorer\"
or
"C:\Users\<username>\AppData\Local\VirtualStore\Program Files (x86)\XYplorer\"
(see Upgraded ... and all configuration lost)

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


Tips:

You can use XYplorer help menu to see where your folders are located:

XYplorer menu "Help > Various Information" will show you where XY settings are stored.


Example Info from "Help > Various Information" (on Win2000/XP)
App: C:\Program Files\Xyplorer\XYplorer.exe
Ini File: C:\Dokumente und Einstellungen\<username>\Anwendungsdaten\Xyplorer\XYplorer.ini
App Data Path: C:\Dokumente und Einstellungen\<username>\Anwendungsdaten\Xyplorer\
Scripts Path: C:\Dokumente und Einstellungen\<username>\Anwendungsdaten\Xyplorer\Scripts\
Thumbs Cache Path: C:\Dokumente und Einstellungen\<username>\Anwendungsdaten\Xyplorer\Thumbnails\


Example Info from "Help > Various Information" (on Vista/Win7)
App: C:\Program Files\Xyplorer\XYplorer.exe
Ini File: C:Users\<your name>\AppData\Roaming\XYplorer\XYplorer.ini
App Data Path: C:Users\<your name>\AppData\Roaming\XYplorer\
Scripts Path: C:Users\<your name>\AppData\Roaming\XYplorer\Scripts\
Thumbs Cache Path: C:Users\<your name>\AppData\Roaming\XYplorer\Thumbnails\



XYplorer menu "Go > Go to xxxx" will bring you to the folders where XY stuff are stored.



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


Registry-Entries (if you use the installer)

ToDo: how looks the registry entries

HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\XYplorer.exe\="C:\Programme\XYplorer\XYplorer.exe"
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\XYplorer





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




What is what for?

Please note that the XY-settings are stored in different files:

Startup.ini - (if exist) points to an folder containing the following files and folders:
(If startup.ini not exists {to test: or point to an non-valid dir} the following are located in an sub-folder next to the XYplorer.exe)

catalog.dat - XYplorer Catalog on the left at the navigation pane
CatalogDefault.dat - just factory defaults. Not needed to backup.
fvs.dat - XYplorer Folder View Settings
ks.dat - XYplorer Keyboard Shortcuts
lastini.dat - Remembers last used ini
tag.dat - XYplorer File Tags and Comments
udc.dat - XYplorer User-Defined Commands
XYplorer.ini - Holding your license and settings like main XY config and tweaks, CustomToolbarButtons, MRUs, Favorites, PFA FileAssoc,

If you have modified the content of this folders, you may backup them too:
NewItems folder
Scripts folder



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



ToDo, i want to add this infos too:


- what are "non-valid dir's" ?
- how to change from installed/Multi user to portable or vise versa?
- how to modify the permissions so you can have all files in XYs app folder, UAC or not (see http://www.xyplorer.com/xyfc/viewtopic. ... 386#p45386)
- or install to an other folder then "C:\Program files\" where you may have more rights

- I don't have a xyplorer.ini in either folder and each launches successfully.
-----You can start XYplorer without an ini.
-----But your configurations (and your registration details) are saved to such file
-----once you use the related menu item or close XYplorer.

- howto start with an fresh xyplorer.ini?

- add this http://www.xyplorer.com/xyfc/viewtopic. ... 756#p44756
----I rather think the data are buried here:
----C:\Users\<username>\AppData\Local\VirtualStore\Program Files (x86)\XYplorer\
----This happened to a couple of users where the auto-upgrading did not work out for them.
----The reason is, IF you are on Vista/W7, Vista/W7's file system virtualization.


---



-ToDo:
use startup.ini for portable use to get different "Data"-folder per different PC,
like:
[AppData]
Path=%ComputerName%

or perhaps
[AppData]
Path=%UserName%

---


Corrections and additions are welcome. Don, you may edit my post if i wrote nonsenses!

Based on this posts at least:
http://www.xyplorer.com/xyfc/viewtopic. ... 756#p44756
http://www.xyplorer.com/xyfc/viewtopic. ... 386#p50386
http://www.xyplorer.com/xyfc/viewtopic. ... 393#p50393
http://www.xyplorer.com/xyfc/viewtopic. ... 210#p52210
http://www.xyplorer.com/xyfc/viewtopic. ... 298#p72298


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














Backup or transfer settings to an other pc


aurumdigitus wrote:Given this discussion of the different XY install packages what is the best and safest
method to migrate all of a carefully honed working version several years in the making to a new computer? :veryconfused:
If you have all stored in your "Application Data Folder", (use menu "Go > Go To Application Data Folder" to see)
it is enough to execute menu "File > Settings > Backup Application Data Folder..." and store it on your USB-Drive.

If you have something in your "Application Folder" other then the default files (see >here< for an list)
then you may copy this files too. Use menu "Go > Go To Application Folder" to see.
Maybe the file "Startup.ini" is from interest here to copy too.

On your other pc, install XYplorer, start it, use the links in the GO-menu to go to the XYplorer folders
and copy your saved files back. Be sure to not overwrite newer executables with older ones.




admin wrote:
aurumdigitus wrote:Given this discussion of the different XY install packages what is the best and safest method to migrate all of a carefully honed working version several years in the making to a new computer? :veryconfused:
FAQ #4:
http://www.xyplorer.com/faq-topic.php?id=migrate
A Frequently Asked Question
How do I migrate XYplorer to another computer / OS?

It's very easy. Since XYplorer is a portable application you don't need to do any uninstalling or installing.
Simply copy XYplorer's application folder and application data folder with all contents to a USB-stick and transfer them to the corresponding locations in the target system. Your complete configuration including registration is now migrated.

Remarks

The application folder is typically C:\Program Files\XYplorer, and the application data folder typically %appdata%\XYplorer. The easiest way to go to those folders is by menu Go | Go to Application Folder
and Go | Go to Application Data Folder inside XYplorer. Note that in older setups both folders can be identical.

The application data folder is typically defined by an entry in the file Startup.ini located in the application folder.
It will probably look like this:

Code: Select all

[Appdata]
Path=%appdata%\XYplorer



aurumdigitus wrote:So the next computer gets a brand new Installer Package first and then gets started. Then using the nascent XY the files get copied to it. Yes?
Yes. Just start your new fresh XYplorer and use the Go -menu
to go to the two XYplorer folders and copy your old files back.
But you may want to keep the newer EXE files (XYplorer.exe is protected anyway if XYplorer is running)
At what point does the fresh software learn of the registration number?
Your license is store in your current ini-file, XYplorer.ini on default.
You should keep your registered name and the key on an save place.
You can also enter this two details in an dialog via help-menu .
This arises over the question of just how portable is portable.
Thought maybe it was simply enough to copy C:\Program Files\XYplorer and that would do it.
In the old pre-Vista/UAC days yes.
But since XYplorer behaves to the standard installation path C:\Program Files\
and since the UAC of Vista/Win7 doesn't allow write access on default to that path (even for admins)
the XYplorer data folder has to be at an writeable path,... your user profile and there to AppData\XYplorer.

If you don't need the help of the installer (creating folders, startup.ini, start menu entries,...) you can just use the non-installer package.
You just have to remember where you have un-packt the archive and have to create an start menu entry yourself. Do-able?


Other possibles are to NOT install to C:\Program Files\ but to an place you have write access to (e.g. to "C:\myApps")
or, to give your self write access to C:\Program Files\XYplorer (i think i have posted this how-to too?)

To both ways you have to copy (*1) the content of your "%appdat%\xyplorer" folder
to an "Data" sub folder of your XYplorer installations folder,
and to disable the startup.ini by renaming them to startup_ini

(*1)
if you need them, read: if you have made any changes.
If not, the Data sub folder is created fresh anyway on first XYplorer start if you have disabled the startup.ini
But you may want to copy your XYplorer.ini, or enter the registration again via help-menu.


j_c_hallgren wrote:
Stefan wrote:
At what point does the fresh software learn of the registration number?
Your license is store in your current ini-file, XYplorer.ini on default.
The only exception to this (I believe) is the GOTD vers (Giveaway Of The Day) which appears to have a special vers of EXE (from other posts here) and thus doesn't use this same method.
Absolutely right.

For the GOTD version the XYplorer.exe is the important part to keep your license.
XYplorer.exe, v10.80.0.200, 4.861.952 Bytes, 03.02.2012 15:21 , MD5 fc1f1d91fd8c89c754f989a0daa37f2c

Here the XYplorer.ini holds only the made settings but no license info.
(Note: That's different from an purchased version, where the ini with your license is the important part.)

If you have overwritten this exe file by an update you have dropped your giveaway license.
Terms and conditions

Please note that the software you download and install during
the Giveaway period comes with the following important limitations:
1) No free technical support
2) No free upgrades to future versions
3) Strictly non-commercial usage
So better keep the v10.80.0.200 exe in an save place. The better thing to do would be buying
the full lifetime version, as you may have seen that it is worth the price and you will get all new features :wink:

Related post: Welcome to GOTD (GiveawayOfTheDay) users & notice to others


admin wrote:
Stefan wrote:
So you should have one of this folders:
C:Users\<your name>\AppData\Roaming\XYplorer\Data\
C:\Documents and Settings\<UserName>\Application Data\XYplorer\Data\
<Where "Data" contains the same folders and files as shown above at portable>

---

Corrections and additions are welcome. Don, you may edit my post if i wrote nonsenses!
Long post. :) The part above is wrong: the Data folder is only created below app path, not below app data path. The Data folder IS app data path.

The conditions I gave can be improved as such:
If
- no app data path is set by command line
- AND (no startup.ini is found in app path OR startup.ini contains no app data path)
- AND no XYplorer.ini is found in app path
then the app data path is auto-set to <xypath>\Data.

Conc. the wiki: jacky told me the wiki server is gone forever.
he kindly gave me the wiki backups, and I'm still making up my mind about whether to put it up again or not.
.
Last edited by Stefan on 17 May 2013 08:15, edited 2 times in total.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

Re: How to use and execute a script ?

Post by Stefan »

reserved for further use

Hold this thread clean, no questions, no answers. Use an other thread to discuss things. Thanks.

Stefan
Posts: 1360
Joined: 18 Nov 2008 21:47
Location: Europe

How to add an Custom Toolbar Button / Use internal ID and Ic

Post by Stefan »

Hold this thread clean, no questions, no answers. Use an other thread to discuss things. Thanks.


How to add an Custom Toolbar Button (CTB)

You can add an own toolbar button to execute an script or an command found in the menu.
See introduce of CTB at http://www.xyplorer.com/release_8.40.htm

You can use internal command found in the menu from an button
and you can use the internal icons as button icon for the toolbar.



To add you own button...

1.) right click an existing button (see picture below)
or use menu "Tools > Customize Toolbar (Ctrl+Shift+F9)"

2.) on the right side go to those button where the new button should be added
and click on this existing button to select them.
Scroll in the left down to an available "User Button #X" and click on it to select them.
Use the "Add ->" button to add your new button to the current buttons.
(you can use Up/Down-buttons for reorder the list)
Click at [OK]

3.) left click this new button at the toolbar (if it is an freshly new added one, or right click and chose "Edit")

4.) Edit User Button:

Name: the tool tip, just an name or an description for this button. (like 'User Button #26' above)

Icon: path to an ICO file, or an EXE file, or an ICL file, or use an intern icon.

Examples:
"path\icon.ico"
"..\path\icon.ico"
"<xydata>\icons\icon.ico"
"X:\path\to\icon.ico"
or "..\Beyond Compare 3\BCompare.exe"
or use XY intern icons like ":favs" or ":myco" (see below)

Tip: use nonofficial /n syntax to access an Icon other then the first from an EXE or from the Icon Library.
Examples:
"path\ICONS\smily.icl /53" to use icon number 53 from smily.icl
or "xyplorer.exe /2" to use icon no. 2 from XYplorer.exe
(nonofficial = not supported by developer. If it doesn't works, use an other icon)



On Click: add an on-liner script, or click [Edit…] to write multi-line script, or LOAD to call an *.xys script file.

On right-click: load an *.xys script file to show an context menu.


If you are finished click at [OK]

5.) that's how it could look.

Step by Step HowTo add an button
Step by Step HowTo add an button
XYplorer Add CTB_65p_grey.png (43.57 KiB) Viewed 50187 times




- - -

How to use one of the XY internal icons for a button?

You have to use the internal name of the build-in buttons to get his icon.
For example the internal name for "MyComputer" is ":myco", the one of "Favorites" is ":favs".

You can use the internal icon by using something like :myco
That's an colon : followed by the internal name.




How to get this internal names of the build-in button?

The internal names for the current toolbar you can get with the following script:
text toolbar();



You can get an list of all the buttons following this steps:
(see XYplorer help file too: Scripting Commands Reference > button and toolbar)


1.)First save all XYplorer setting > menu "File > Settings > Save all settings"
(or use an other non-install XY version just temporary for this issue)


2.) now save your current toolbar just to be sure:
$CurrentToolbar = toolbar();
writefile("<xydata>\CurrentToolbar.txt" , $CurrentToolbar);



3.) now add all (or the one you are interested in) buttons to the toolbar.


4.) then execute again an script to get this internal names too:
$CompleteToolbar = toolbar();
writefile("<xydata>\CompleteToolbar.txt" , $CompleteToolbar);



That will get you an list like this:

(CompleteToolbar.txt from v9.70.0000 - 2010-11-03)
CompleteToolbar.txt wrote: back,fore,up,mru,-,myco,newfolder,find,openwith,-,copy,go,hotlist,drives,browsenetwork,refresh,
autorefresh,refreshsus,stop,props,copypath,previewfull,qfv,favs,favfiles,tags,findtag,cut,clip,
moveto,copyto,backupto,lasttarget,goprev,rename,nuke,queue,netmap,netunmap,dosbox,hidenav,
treeshow,syncscroll,hightree,panellast,panelmax,sort,views,viewdetails,viewlist,viewthumbs,
zoomin,zoomout,exitnosave,udc,cks,fvs,lstmgmt,calcfosi,home,newtab,closetab,locktab,tablist,
showhidden,showsystem,showfolders,visualfilter,sticky,steps,paste,del,-,undo,redo,-,minitree,dp,
dp12,panelshow,cat,preview,-,conf,ctb1,ctb2,ctb3,savesett
Maybe read this too > viewtopic.php?p=38002#p38002



5.) Now for restore load your old toolbar from CurrentToolbar.txt,
$CurrentToolbar = readfile("<xydata>\CurrentToolbar.txt");
toolbar("$CurrentToolbar");


Or just restart XYplorer without saving.






Tip: Here is an script to save and load toolbars:

Code: Select all

"Save current toolbar to file"
   $CurrentToolbar = toolbar();
   $File = inputfile("<xydata>", ,"Chose or create file to save toolbar");
   writefile("$File" , $CurrentToolbar); //CurrentToolbar.txt
   msg "Done.<crlf>$File";

"Load toolbar from file"
   $File = inputfile("<xydata>", ,"Chose file to load toolbar");
   $CurrentToolbar = readfile("$File"); //CurrentToolbar.txt");
   toolbar("$CurrentToolbar");
- - -

Execute an build-in button by an script or from catalog

Maybe you are interested to know how to open/use/execute an build-in button by an script or from catalog?

Just use the XY script command "button <buttonname>"

See "Help > Scripting Commands Reference > button" for more:

Code: Select all

button
    Emulates a click on a toolbar button.

Syntax 
    button key, [action=1]

key [required] Key that identifies the button.
     You can retrieve the existing keys using the SC toolbar, or using the Customize Toolbar 
     command from a user button's context menu. 

action [optional] e.g.: 2 = right-click

Examples
     button "mru";         //pops MRU menu at key
See above "How to get this internal names of the build-in button?" to get an list of button names.

You can test this in the address bar:

button "drives";
or
::button "drives";

More example:
::button "mru";
::button "mru",2;
::button "hotlist";
::button "hotlist",2;
::button "drives";
::button "hightree";
::button "panelmax";
::button "dosbox";

See the help for more tips.

- - -



How to use XY internal commands to use as script or as command for an button

To execute an command found in the menu you have to call the intern "Command ID"

1.) To get an list of XYplorer intern "Command IDs" like #102; click on XYplorer menu "Help > Make List of Commands..."

2.) You will be prompted by an dialog where you have to click at [OK] to copy the list into the clipboard.

3.) Then you can paste it to an plain text file.
(Tip: use right mouse click context menu at an free area in the list, or over the numbers column, then chose "Paste Special > Paste Text Into File)
Or just open your text editor as e.g. notepad and use "Paste".



This result will looks like this short "pullout" of ~600 lines:
File / To Clipboard / Item Name(s) #102 Ctrl+Shift+P
File / Rename Special / Batch Rename... #121 Shift+F2
File / Move/Copy/Backup To #150
View / Tab / Sort By / Size #323
... 594 more lines...
4.) Search for the command in question and use the number as command, like here: #102; for example.




An example of an use of internal build-in commands
is to use such an ID to get the list of that IDs.

:shock:

Don't be afraid, I will show you :lol:

Type this commands in the address bar of XYplorer (don't try this with Win Explorer)
::#705; text "<clipboard>";

Explanation:
- :: is to tell XYplorer that the following is an command, not an address to go to
- #705 is the internal command ID to invoke the "Help > Make List of Commands..." command.
- text is an command to display an text in an little window.
- "<clipboard>" is an build-in variable to access the clipboard content, which is our 'text' to display.
- ; the semicolon is the XYplorer script command terminator


So what we doing is:
- invoking the "Help > Make List of Commands..." command by using #705; (you are prompted twice, just click on [OK])
- launching the text command with "<clipboard>" as parameter to show what the #705; has put onto the clipboard for us

All clear?

To open that list in Notepad instead use something like:

Code: Select all

::#705;    $tmpfile="%temp%\XYComandIDs.txt";    writefile($tmpfile, "<clipboard>");    run notepad $tmpfile;
-


An other way to get this IDs is

1.) to take an look into "Tools > Customize Keyboard Shortcuts"

2.) Select here the category corresponding to the menu in question where you have found "your" command,
and then find the command at the same position/order as in the menu here too.

3.) Click at this commands and you see the ID at an button below.
That is the command ID for that internal function.
(note that such an command ID need an leading hash '#' and an trailing semicolon ';', so use it like #306;)
(Hint: use "[Options...] > Copy Cheat Sheet" for an print-out of all IDs)


-


However you get it, this command #102; you can use e.g.
- inside an script
- from an CTB button (see picture below)
- from UDC (User Defined Commands) (see "How to execute an script" above)
- from XY address bar as ::#102; (see "How to execute an script" above)
Use internal command IDs with CTB button
Use internal command IDs with CTB button
XYplorer_CTB_internalCMD_c16.png (9.2 KiB) Viewed 49977 times


Hold this thread clean, no questions, no answers. Use an other thread to discuss things. Thanks.
If you want to ask something or just give some feedback, you can use that other Thanks to Stefan for the Scripting How-to (click) thread.

Post Reply