commit f7546d43cc7c3c489ee6fa42540cc30c53edc4a2 Author: wehub-resource-sync Date: Mon Jul 13 12:28:17 2026 +0800 chore: import upstream snapshot with attribution diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..7f90a76 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +github: moudey +patreon: moudey +custom: ['https://www.buymeacoffee.com/moudey','https://paypal.me/nilesoft'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..a3fe9ec --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,57 @@ +name: Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +permissions: + contents: read + +jobs: + build: + + strategy: + matrix: + # configuration: [debug, release] + configuration: [release] + platform: [x64, x86, arm64] + fail-fast: false + + env: + SOLUTION_FILE_PATH: src/Shell.sln + BUILD_CONFIGURATION: ${{matrix.configuration}} + BUILD_PLATFORM: ${{matrix.platform}} + BIN_PATH: D:\a\Shell\Shell\src\bin + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v2 + + - name: Restore NuGet packages + working-directory: ${{env.GITHUB_WORKSPACE}} + run: nuget restore ${{env.SOLUTION_FILE_PATH}} + + - name: Build + working-directory: ${{env.GITHUB_WORKSPACE}} + run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} ${{env.SOLUTION_FILE_PATH}} + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + with: + name: shell-${{matrix.platform}} + path: | + ${{env.BIN_PATH}}\* + !${{env.BIN_PATH}}\*.lib + !${{env.BIN_PATH}}\*.exp + !${{env.BIN_PATH}}\*.wixpdb + !${{env.BIN_PATH}}\ca.dll + if-no-files-found: warn + retention-days: 0 + compression-level: 6 + overwrite: false + include-hidden-files: false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83cb75c --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a + +# Executables +*.exe +*.out +*.app + +# Other junk +.DS_Store + +src/.vs/ +src/exe/obj/ +src/dll/obj/ +src/setup/ca/obj/ +src/setup/wix/obj/ +src/packages/ +#src/bin/*.exe \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..27c2ddc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "src/lib/plutosvg"] + path = src/lib/plutosvg + url = https://github.com/sammycage/plutosvg.git +[submodule "src/lib/detours"] + path = src/lib/detours + url = https://github.com/microsoft/Detours.git diff --git a/Issue700-Fix.md b/Issue700-Fix.md new file mode 100644 index 0000000..5cfa107 --- /dev/null +++ b/Issue700-Fix.md @@ -0,0 +1,87 @@ +# Windows 11 Canary Build Fix (Issue #700) + +## Problem Description +In Windows 11 Canary builds, the color auto setting for Nilesoft Shell was broken. This resulted in incorrect theme colors being applied to context menus, particularly affecting users on the Windows Insider program using Canary channel builds. + +## Root Cause Analysis +The issue was caused by changes in how Windows 11 Canary builds handle theme data. Specifically: + +1. The Windows API functions for retrieving theme colors (`GetThemeColor` and `DrawThemeBackground`) behave differently in Canary builds. +2. The detection mechanism for Windows 11 builds didn't specifically identify Canary/Dev channel builds, which require special handling. + +## Changes Made + +### 1. Enhanced Windows Version Detection +Updated the `Windows.h` file to detect Windows 11 Insider builds: + +```cpp +bool IsCanaryBuild = false; +bool IsDevBuild = false; +bool IsBetaBuild = false; +bool IsPreviewBuild = false; +``` + +Added code to detect the Insider channel by reading the `FlightRing` registry value: + +```cpp +string flightRing = key.GetString(L"FlightRing").move(); +if(!flightRing.empty()) +{ + if(flightRing.iequals(L"Canary")) + IsCanaryBuild = true; + else if(flightRing.iequals(L"Dev")) + IsDevBuild = true; + else if(flightRing.iequals(L"Beta")) + IsBetaBuild = true; + else if(flightRing.iequals(L"ReleasePreview")) + IsPreviewBuild = true; +} +``` + +Added a new helper function to identify Canary/Dev builds: + +```cpp +bool IsWindows11CanaryOrDev() const +{ + return IsWindows11OrGreater() && (IsCanaryBuild || IsDevBuild); +} +``` + +### 2. Modified Theme Color Detection +Updated the `ContextMenu.cpp` file to handle Canary builds differently: + +1. Added special handling for Windows 11 Canary and Dev builds +2. Implemented fallback mechanisms using system colors when theme APIs fail +3. Added more robust error checking for theme color retrieval + +Key changes include: + +```cpp +// Special handling for Windows 11 Canary and Dev builds +bool isCanaryOrDev = ver->IsWindows11CanaryOrDev(); + +// Use more reliable theme color detection for Canary builds +if (isCanaryOrDev) +{ + // Get text colors with fallbacks to system colors + if (!get_clr(nor, MENU_POPUPITEM, MPI_NORMAL, TMT_TEXTCOLOR)) + { + nor.from(::GetSysColor(COLOR_MENUTEXT), 100); + } + + // ... similar fallbacks for other colors +} +``` + +## Testing +The fix has been tested on: +- Windows 11 Canary Build 26100 +- Windows 11 Dev Build 26085 +- Windows 11 Release Build 22631 + +All builds now correctly detect and apply theme colors in both light and dark modes. + +## Future Improvements +1. Consider adding more robust detection for future Windows builds +2. Implement a configuration option to override theme detection for specific builds +3. Add telemetry to detect and report theme detection failures \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bfac5f5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Nilesoft + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/PR-Description.md b/PR-Description.md new file mode 100644 index 0000000..47543a0 --- /dev/null +++ b/PR-Description.md @@ -0,0 +1,40 @@ +# Fix Windows 11 Canary Build Theme Detection (Issue #700) + +This pull request addresses the issue with color auto setting being broken on Windows 11 Canary builds. + +## Changes + +### Enhanced Windows Version Detection +- Added detection for Windows 11 Insider channels (Canary, Dev, Beta, Release Preview) +- Added a new `IsWindows11CanaryOrDev()` helper function +- Improved version detection by checking the `FlightRing` registry value + +### Improved Theme Color Detection +- Added special handling for Windows 11 Canary and Dev builds +- Implemented fallback mechanisms using system colors when theme APIs fail +- Added more robust error checking for theme color retrieval + +## Testing +The fix has been tested on: +- Windows 11 Canary Build 26100 +- Windows 11 Dev Build 26085 +- Windows 11 Release Build 22631 + +All builds now correctly detect and apply theme colors in both light and dark modes. + +## Documentation +Added detailed documentation in `Issue700-Fix.md` explaining: +- The root cause of the issue +- Changes made to fix the problem +- Testing performed +- Future improvement suggestions + +## Related Issues +Fixes #700 + +## Screenshots +Before: +[Insert screenshot of broken theme detection] + +After: +[Insert screenshot of fixed theme detection] \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9369869 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +[![Ceasefire Now](https://badge.techforpalestine.org/default)](https://techforpalestine.org/learn-more) + +[![Build](../../actions/workflows/build.yml/badge.svg)](../../actions/workflows/build.yml) +[![Nightly](https://img.shields.io/badge/Nightly-nightly.link-purple)](https://nightly.link/moudey/Shell/workflows/build/main) + +# [Shell](https://nilesoft.org) +Powerful manager for Windows File Explorer context menu. +
+ +

+ +
+
+

+ +## Details +

+Shell is a context menu extender that lets you handpick the items to integrate into the Windows File Explorer context menu, create custom commands to access all your favorite web pages, files, and folders, and launch any application directly from the context menu.
+It also provides you a convenient solution to modify or remove any context menu item added by the system or third-party software. +

+ +Features +------------------ +* Lightweight, portable, and relatively easy to use. +* Fully customize the appearance. +* Adding new custom items such as (sub-menu, menu-items, and separator). +* Modify or remove items that already exist. +* Support all file system objects, including files, folders, desktop, and the taskbar. +* Support expressions syntax. with built-in functions and predefined variables. +* Support colors, glyphs, SVG, embedded icons, and image files such as .ico, .png or .bmp. +* Support search and filter. +* Support for complex nested menus. +* Support multiple columns. +* Quickly and easily configure file in plain text. +* Minimal resource usage. +* No limitations. + + +Requirements +------------------ + * Microsoft Windows 7/8/10/11 + + +Documentation +------------------ +Browse the [online documentation here.](https://nilesoft.org/docs) + +[Ask DeepWiki.com](https://deepwiki.com/moudey/Shell) + +Download +------------------ +Download the latest version: +https://nilesoft.org/download + +Screenshots +------------------ +

+
+
+
+
+
+ +
+
+

+ +Donate +------------------ +If you really love Shell and would like to see it continue to improve. + +[![Paypal](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.me/nilesoft) +[![BuyMeACoffee](https://img.shields.io/badge/Donate-BuyMeACoffee-yellow.svg)](https://www.buymeacoffee.com/moudey) + + diff --git a/README.wehub.md b/README.wehub.md new file mode 100644 index 0000000..3df79de --- /dev/null +++ b/README.wehub.md @@ -0,0 +1,7 @@ +# WeHub 来源说明 + +- 原始项目:`moudey/Shell` +- 原始仓库:https://github.com/moudey/Shell +- 导入方式:上游默认分支的最新快照 +- 原作者、版权和许可证信息以原始仓库及本仓库 LICENSE 为准 +- 本文件仅用于记录来源,不代表 WeHub 是原项目作者 diff --git a/docs/configuration/index.html b/docs/configuration/index.html new file mode 100644 index 0000000..a30e5d6 --- /dev/null +++ b/docs/configuration/index.html @@ -0,0 +1,202 @@ +

Syntax Rules for Configuration Files

+
+

This chapter describes the syntax rules for the configuration files.

+

The main configuration file shell.nss is located in the installation directory of + Shell, depending on your installation method. +

+ +
General rules
+ + +
+ Tip: When there is an error, it is recorded in the log file (shell.log, which is also located in + your installation directory.). +
+ +
shell.nss structure
+

The global section shell{} may have the following subsections:

+ +
Example
+
// variable declaration
+$variable-name = variable-value
+
+//image declaration
+@image-id = image-value
+	
+settings
+{
+	key-name = key-value
+	key-name = [key-value, key-value, ...]
+	...
+}
+
+theme
+{
+	key-name = key-value
+	...
+}
+
+// modify items
+modify ( property-name = property-value   ... )
+remove ( property-name = property-value   ... )
+
+// new items
+
+item ( property-name = property-value   ... )
+
+separator [( property-name = property-value   ... )]
+
+menu ( property-name = property-value   ... )
+{
+	$variable-name = variable-value
+	
+	item ( property-name = property-value   ... )
+	...
+}
+
+ +

Breaking Long Lines

+

For best readability, users often like to avoid lines longer than 80 characters. single + quotes also allow break up a line.

+
item(title='Command prompt'
+	cmd='cmd.exe')
+
+
+ +

Import tag

+

To better organise the configuration file, parts of the configuration can be saved in separate files. These are then + imported using the import tag. With this method, it is also possible to import the same file as a sort of "module" + into different parts of the configuration. A convenient way to include the same sub-menu in different + locations..

+
Syntax
+

The general syntax is as follows:

+
import %path%
+

Where

+ + +

There are effectively two different ways this tag is applied, depending on whether the optional + %section% is given:

+ + +
Import an entire section
+
// import an entire section
+import %path%
+
+In this case, the content of the file found at %path% will be imported into a newly + created section{}. +The result would then look like so: +
// import an entire section
+section {
+	/* content of the imported file goes here! Do not include
+	 *
+	 * section {
+	 * }
+	 *
+	 * in your imported file!
+	 */
+}
+

This syntax may be used only in the following places:

+ +
Import as a partial
+
section {
+	// some code might go here. Optional.
+
+	// import of a partial section
+	import %path%
+
+	// some more content might go here. Optional.
+}
+In this case, the content of the file found at %path% will be imported into the already + existing section{}. +The result would then look like so: +
section {
+	// some code might go here. Optional.
+
+	// import of a partial section
+	/* content of the imported file goes here! Do not include
+	 *
+	 * section {
+	 * }
+	 *
+	 * in your imported file!
+	 */
+
+	// some more content might go here. Optional.
+}
+

This syntax may be used nearly anywhere:

+ diff --git a/docs/configuration/modify-items.html b/docs/configuration/modify-items.html new file mode 100644 index 0000000..7ec4a04 --- /dev/null +++ b/docs/configuration/modify-items.html @@ -0,0 +1,62 @@ +

Modify Items

+
+

The optional modify section contains entries to modify existing context menu items, + added by the system or by a third party.

+ +
Sub-items
+

The section can have the following entry types, all of which are optional:

+ +
Example
+

In the following example, two instructions are defined:

+
modify(find = 'copy' image = #00ff00)
+modify(find = 'paste' image = #0000ff)
+remove(find = '"format"')
+
+

Item Entries

+

item entries contain the instructions on how to identify existing menuitems (also referred to as Target), and when and what changes should be applied + to them.

This is done by matching an existing menuitem's title property against the modify item's mandatory find property. If a match is found, the other properties of the modify + item are applied to the appropriate menuitem, such as changing their properties (e.g. title, icon, visibility), or moving them to another location.

+ +
Syntax
+
modify( find = value [property = value [...] ])
+
+
Properties
+

item entries can define three different sets of properties:

+
+
Validation Properties
+
Determine if a given item entry should be processed when a context menu is displayed. Optional. +
+
Filter Properties:
+
Determine if a given menuitem is a valid target + for the process instructions +
    +
  • find (mandatory)
    + Pattern used to identify targets by matching against their title property. +
  • +
  • in
    + Used to identify targets by specifying the submenu in which they are located. +
  • +
+
+
Process Instructions
+
Define what to do with the target. Optional. However, if there are no process instruction specified, the entry is of no practical use. For + further details refer to its separate section + below. +
+
+

For a complete overview and further details regarding applicable properties, please refer to the properties page.

+

Item Target

+

Item targets are menuitems of an existing context menu. Their properties or location can + be changed by applying the process instructions defined in a modify item.

+
Process instructions
+

Instructions that should be applied to the Target. Basically they consist of properties from the two property + classes menuitem properties and command properties.

+

Once a item is validated and a target identified, then these values are applied to the targeted + menuitem.

diff --git a/docs/configuration/new-items.html b/docs/configuration/new-items.html new file mode 100644 index 0000000..350cf5e --- /dev/null +++ b/docs/configuration/new-items.html @@ -0,0 +1,105 @@ +

New Items

+
+

Add new items to the context menu.

+
Sub-items
+

The section can have the following entry types, all of which are optional:

+ + +
Example
+

In the following example, one top-level item is created, that is + separated with a horizontal line from an adjacent sub-menu, which in turn has one sub-item + on its own:

+
item(title = 'Hello, World!')
+separator
+menu(title = 'sub menu' image = #0000ff)
+{
+	item(title = 'test sub-item')
+}
+
+ + + +

menuitem is an umbrella term for those entry types, that may appear in a + menu. These simply include the following:

+ + +
+

Items

+

items create a single menu entry.

+ +
Properties
+

Either a title or a image property is mandatory (set to a non-null value). For further details, + please refer to the properties page.

+ +
Syntax
+
item( title = value [property = value [...] ])
+
+ + + +

menu entries create a new sub-menu. They have properties + and sub-entries.

+ + +

Either a title or a image property is mandatory (set to a non-null value). For further details, + please refer to the properties page.

+ + +

menus can have the following entry types, all of which are + optional:

+ + + +
menu( title = value [property = value [...] ])
+{
+	[ item() [...] ]
+	[ menu(){} [...] ]
+	[ separator [...] ]
+	[ import 'path/to/import.nss' [...] ]
+}
+
+ +

Separators

+ +

separators create a horizontal line.

+ +
Properties
+

separators do not have any mandatory properties. Please refer to the properties page for further details.

+ +
Syntax
+
separator
+separator( property = value [property = value [...] ])
diff --git a/docs/configuration/properties.html b/docs/configuration/properties.html new file mode 100644 index 0000000..9a76a48 --- /dev/null +++ b/docs/configuration/properties.html @@ -0,0 +1,967 @@ +

Properties

+ +Shell supports the following properties classes: + +

Please also see the full index of available properties below.

+
Index
+ + +

Syntax

+
Entry types
+

In the following tables, the Types column shows to which entry types the + property applies to.

+

The following abbreviations are used (if set in bold, then the property is mandatory for the given type): +

+
+
mi
+
modify item, i.e. the + item + entry itself. Is basically required to evaluate if the process instructions are applied to any given target. +
+
mt
+
modify target, i.e. + the menuitem of the existing menu to which the process instructions are applied +
+
nm
+
new menu type
+
ni
+
new item type
+
ns
+
new separator type. +
+
+ + +
Validation Properties
+

Determine if a given Modify items + or New items entry should be + processed when a context menu is displayed.

+ +
+ +
+
+
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Wheremi, nm, ni, nsProcess given menuitem if true is returned. Allows the evaluation of arbitrary + expressions, e.g. if().
+ Default = true +
Modemi, nm, ni, nsDisplay menuitem by type of selection. The value has one of the following + parameters + (of type string): + + + + + + + + + + + + + + + + + + + + + +
noneDisplay menuitem when there is no selection.
singleDisplay menuitem when there is a single object selected.
multi_uniqueDisplay menuitem when multiple objects of the same type are selected. +
multi_singleDisplay menuitem when multiple files with a single file extension are selected.
multipleDisplay any type of selection, unless there is none.
+ Default = single +
Typemi, nm, ni, nsSpecifies the types of objects for which the menuitem will be displayed.
+ Possible values are shown below. Separate multiple types with the pipe character (|), + in + which case the menuitem is displayed if any of the given types is matched.
+ To exclude a given type, prefix its value with the tilde character (~). +

Expressions are not supported with this property.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
*Display menuitem when any type is selected.
FileDisplay menuitem when files are selected.
Directory(Dir)Display menuitem when directories are selected.
DriveDisplay menuitem when drives are selected.
USBDisplay menuitem when USB flash-drives are selected.
DVDDisplay menuitem when DVD-ROM drives are selected.
FixedDisplay menuitem when fixed drives are selected. Such drives have a fixed media; for + example, a hard disk drive or flash drive. +
VHDDisplay menuitem when Virtual Hard Disks are selected.
RemovableDisplay menuitem when the selected drives have removable media; for example, a floppy drive, + thumb drive, or flash card + reader. +
RemoteDisplay menuitem when the selected remote (network) drives are selected.
BackDisplay menuitem when the background of all types are selected (back). Or + specify one of + the following more granular types for the background: +
    +
  • + back.directory +
  • +
  • + back.drive, including +
      +
    • back.fixed
    • +
    • back.usb
    • +
    • back.dvd
    • +
    • back.vhd
    • +
    • back.Removable
    • +
    +
  • +
  • + back.namespace, including +
      +
    • back.computer
    • +
    • back.recyclebin
    • +
    +
  • +
+
DesktopDisplay menuitem when the Desktop is selected.
NamespaceDisplay menuitem when Namespaces are selected. Can be virtual objects such as My Network Places and Recycle Bin. +
ComputerDisplay menuitem when My Computer is selected.
RecyclebinDisplay menuitem when the Recycle bin is selected. +
TaskbarDisplay menuitem when the Taskbar is selected. +
+ Default = Accepts all types, except for the Taskbar. +
+
+ +
Filter Properties
+

For Modify items entries only, + filter properties determine if a given menuitem is a valid target for the process instructions

+ + + +
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Findnm, ni, ns +
+
For modify items (required)
+
Apply the current item's process instructions to any existing menuitem if their title property matches the + pattern of the current item's find property. +
+
For dynamic items (optional)
+

Display the current menuitem if the pattern of its find property matches the + path name or path extension + of the selected files.

+

Default = null, which means any string is "matched". +

+
+ +
Syntax
+
+
find = '%pattern%'
+find = '%pattern%|%pattern%[...]'
+

where %pattern% can be one or + more + matching instructions (see Examples below). The + following characters do have special meaning:

+
    +
  • | Use to separate patterns. If any one pattern + matches, + the property yields + true. +
  • +
  • * Matches any number of characters. Is used as a + wildcard + to + match only the beginning or the end of the entire string (or word, if used in + combination with the exclamation mark !). +
  • +
  • ! Negates the match of the current pattern, or + limits + the wildcard (*) to one word only. +
  • +
  • "" the enclosed string is treated as a word. +
  • +
+

A word is a sequence of + alphanumerical characters that is confined to the left and to the right by either a + space + , a non-word character (e.g. / or -), or the + beginning or the end of the entire string, respectively.

+
Examples
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PatternMatches any string that ...Would matchWould not match
'foo'contains the literal string foo anywhere.foo, foobar, afoobarfo, f oo, bar
'"foo"'contains the literal string foo as a whole word + only. + foo, foo/bar, some foo barfoobar, foofoo, bar
'*foo'ends with the literal string foo.foo, barfoo, bar/foofoobar, fooo, foo
'foo*'starts with the literal string foo. + foo, foobar, foo/bar foobar, fo, yeti
'!foo'does not contain the literal string foo anywhere. + fobar, fo, kung-fufoo, foobar, barfoo/bar
'!"foo"'does not contain the word + foofobar, kung fu bar, foobarfoo, kung foo bar, bar/foo/bar
'!*foo'does not contain a word ending on + foofoobar, fooo-fofoo, foo bar, bar/foo
'foo*!'does not contain a word starting with + foomyFooBar, barFoofoo, foobar, fo-fooo
+


For dynamic items the following syntax allows to match against file + extensions:

+
PatternMatches any file extension ...Would matchWould not match
'.exe'equal to .exesetup.exe, notepad.exeinstall.bat, shell.nss, shell.ex_, + file + without an extension. +
'!.exe'not equal to .exesetup.exe.zip, video.mp4, shell.ex_, + file + without an extension. + setup.exe, shell.exe
'.exe|.dll'equal to either .exe or .dllshell.exe, shell.dll + shell.zip, shell.nss, file + without an extension. +
+
+
+
+
Inmi Specifies the existing submenu where the modify target is located.
+ Syntax
+
in = "New"
+in = "Sort By"
+
+
+ +
Menuitem Properties
+

This set of properties describe the appearance and location of a given menuitem. For modify-items, this is the target menuitem. For dynamic entries, this is the newly created menuitem.

+
+
Appearance
+
+ + +
+
Location
+
+ + +
+
+ +
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Titlest, nm, ni +

Sets the caption of the menuitem.

+
+
For modify-items (optional)
+

Default = null, which means the title of the target + is + not changed.

+
For dynamic items (required)
+

It is mandatory for menu and item entries, unless a image property is defined.

+
+
+
Visibility (vis)st, nm, ni, nsSets the visibility of a menuitem. Can have one of the following parameters: + + + + + + + + + + + + + + + + + + + + + +
HiddenHide the menuitem.
NormalEnable the menuitem.
DisableDisable the menuitem.
StaticDisplay menuitem as label, with or without an image
LabelDisplay menuitem as label without an image
+
+ Note: The values Static and Label are not available for modify-items. +
+ Default = Normal +
Separator (sep)st, nm, niAdd a separator to the menuitem: + + + + + + + + + + + + + + + + + +
NoneNot adding a separator with the menuitem.
Before, TopAdd a separator before the menuitem.
After, BottomAdd a separator after the menuitem.
BothAdd a separator before and after the menuitem.
+ Default = none +
Position (pos)st, nm, ni, nsThe position at which a menuitem should be inserted into the menu.
+ Position can have one of the following parameters: + + + + + + + + + + + + + + + + + + + + + +
AutoInsert the menuitem to the current position.
MiddleInsert the menuitem to the middle of the menu. +
TopInsert the menuitem to the top of the menu. +
BottomInsert the menuitem to the bottom of the menu. +
IntegerInsert the menuitem to a specified position.
+ Default = auto +
Image, Iconst, nm, niThe icon that appears in a menuitem. This property can be assigned as image files, + resource icons, glyph + or color. With one of the following parameters + + + + + + + + + + + + + + + + + + + + + + + + + +
nullShow menuitem without icon.
Inherit@*Inheriting the image from the parent.*@ + Inherits this property from its parent item. +
CmdAssign image from the command property.
GlyphAssign image as Glyph.
ColorAssign image as color.
PathAssign image from location path or resource icon.
+
+ Note:The value Cmd is not available for modify-items + targets. +
+ Default = null +
Parent, Menust, nm, ni, ns

Move current menuitem to another menu.

+ Default = null
Checkedst, niType of select option: + + + + + + + + + + + + + +
0Not checked
1Display as check mark.
2Display as radio bullet.
+ Default = 0 +
Defaultst, ni +

Specifies that the item is the default. A menu can contain only one default + menuitem, which is displayed in bold.

+ Default = false +
Expandednm +

Move all immediate menuitems to the parent menu.

+ Default = false +
Column(col)nm, ni

Create a new column.

+ Default = true +
Keysst, nm, ni

Show keyboard shortcuts.

+ Default = null
Tipst, nm, ni +

Show a tooltip for the current menu or item.

+ Default = null
+ Syntax
+
tip = "Lorem Ipsum is simply dummy text."
+tip = ["Lorem Ipsum is simply dummy text.", tip.info]
+tip = ["Lorem Ipsum is simply dummy text.", tip.info, 1.2]
+
+
+ +
Command Properties
+

This set of properties describe how a command is executed. Only available for dynamic items.

+ + + +
+
Syntax
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypes(*)Summary
Command (cmd)ni

The command associated with the menuitem. Occurs when the menuitem is clicked or + selected using a shortcut key or access key defined for the menuitem.

+ Default = null +
Arguments (arg, args)ni

The command line parameters to pass to the command property of a menuitem.

+ Default = null +
InvokeniSet execution type + + + + + + + + + +
0, singleexecute the command only once in total. The list of selected + items can be accessed with @sel +
1, multipleexecute the command once for every single item in the current + selection. The currently processed item can be accessed with e.g @sel.path.quote +
+ Default = 0 +
WindowniControls how the window of the executed command is to be shown. Can be one of the following + parameters: +

Hidden, Show, Visible, + Minimized, Maximized

+ Default = show +
Directory (dir)ni

Specifies the working directory to + execute + the command in.

+ Default = null +
Adminni

Execute the command + with administrative permissions.

+ Default = false +
VerbniSpecifies the default operation for the selected file. Value type string + and can have one of the following parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
nullSpecifies that the operation is the default for the selected file type.
OpenOpens a file or an application.
OpenAsOpener dialog when no program is associated to the extension.
RunAsIn Windows 7 and Vista, opens the UAC dialog andin others, open the Run as... Dialog.
EditOpens the default text editor for the file.
ExploreOpens the Windows Explorer in the folder specified in Directory.
PropertiesOpens the properties window of the file.
PrintStart printing the file with the default application.
FindStart a search.
+ Default = open +
Waitni +

Wait for the command + to complete.

+ Default = false +
+
diff --git a/docs/configuration/settings.html b/docs/configuration/settings.html new file mode 100644 index 0000000..cf76ec4 --- /dev/null +++ b/docs/configuration/settings.html @@ -0,0 +1,87 @@ +

Settings

+

+

Settings are containers for storing default values.

+
settings
+{
+	// show menu delay value from 0 to 4000
+	showdelay = 200
+
+	// Prevent interaction with these windows or processes
+	exclude
+	{
+		where = boolean value
+		window = window name
+		process = process name
+	}
+
+	tip = true
+	// or
+	tip
+	{
+		enabled = true
+
+		// normal = [background, text]
+		normal = [default, default]
+
+		// normal = [background, text]
+		primary = [#000, #fff]
+
+		// info = [background, text]
+		info = [#88f, #fff]
+
+		// success = [background, text]
+		success = [#8f8, #fff]
+
+		// warning = [background, text]
+		warning = [#ff8, #fff]
+
+		// danger = [background, text]
+		danger = [#f88, #fff]
+
+		// max width value from 200 to 2000
+		width = 400
+
+		// opacity value from 0 to 100
+		opacity = 100
+
+		// radius size value from 0 to 3
+		radius = 1
+
+		time = 1.5
+
+		padding = [8, 4]
+	}
+
+	// Disable/Enable modify items processing
+	modify
+	{
+		enabled = boolean value
+		image = [0 = disable, 1 = enable, 2 = auto reimage]
+
+		// Allow/disallow modification of title
+		title = boolean value
+
+		// Allow/disallow modification of visibility
+		visibility = boolean value
+
+		// Allow/disallow modification of parent
+		parent = boolean value
+
+		// Allow/disallow modification of position
+		position = boolean value
+
+		// Allow/disallow to add separator
+		separator = boolean value
+
+		// auto set image and group
+		auto = boolean value
+	}
+
+	// Disable/Enable new items processing
+	new
+	{
+		enabled = boolean value
+		// disable/enable image
+		image = boolean value
+	}
+}
diff --git a/docs/configuration/themes.html b/docs/configuration/themes.html new file mode 100644 index 0000000..ad637cd --- /dev/null +++ b/docs/configuration/themes.html @@ -0,0 +1,218 @@ +

Themes

+

+

Theme section to customize the layout and colors of the context menu.

+
theme
+{
+	// theme.name = auto, classic, white, black, or modern
+	name = "modern"
+
+	// view = auto, compact, small, medium, large, wide
+	view = view.compact
+
+	// dark = true, false, default
+	dark = default
+
+	background
+	{
+		color = color value
+		opacity = value from 0 to 100
+
+		// effect value 0 = disable, 1 = transparent, 2 = blur, 3 = acrylic
+		effect = auto
+
+		// for acrylic
+		effect = [3, tint color, opacity]
+
+		gradient
+		{
+			enabled = boolean value
+
+			// linear = [x1, x2, y1, y2]
+			linear = [0, 100, 0, 0]
+
+			// or radial = [cx, cy, r, fx, fy]
+			radial =[ 100, 100, 150, 100, 100]
+
+			// stop = [offset, stop-color]
+			stop = [0.5, color.accent, 20]
+
+			// or add more stop
+			stop = [
+				[offset, stop-color],
+				[offset, stop-color],
+				[offset, stop-color]
+			]
+		}
+	}
+
+	item
+	{
+		opacity = value from 0 to 100
+		radius = value from 0 to 3
+
+		// prefix value [auto, 0 = dont display,  1 = display, 2 = ignore]
+		prefix = 1
+
+		text
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		back
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		border
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		padding
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+
+		margin
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+	}
+
+	border
+	{
+		enabled = boolean value
+		size = value from 0 to 10
+		color =  = value
+		opacity = value
+		radius = value
+
+		padding
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+	}
+
+	shadow
+	{
+		enabled = boolean value
+		size = value from 0 to 30
+		color = value
+		opacity = value from 0 to 100
+		offset = value from 0 to 30
+	}
+
+	font
+	{
+		size = value start from 6
+		name = "tahoma"
+		weight = value from 1 to 9
+		italic = 0
+	}
+
+	separator
+	{
+		size = value form 0 to 40
+		color = value
+		opacity = value
+
+		margin
+		{
+			left = value
+			top = value
+			right = value
+			bottom = value
+		}
+	}
+
+	symbol
+	{
+		normal = color
+		normal.disabled = color
+		select = color
+		select.disabled = color
+
+		// or
+		chevron
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		checkmark
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+
+		bullet
+		{
+			normal = color
+			normal.disabled = color
+			select = color
+			select.disabled = color
+		}
+	}
+
+	image
+	{
+		enabled = boolean value
+
+		color = [color1, color2, color3]
+		gap = value
+		glyph = "font name" // font name for default glyph
+		scale = boolean value
+		align = value
+		[0= Display only the check mark,1 = Display only the image,2 = Display image & checkheck mark together]
+	}
+
+	layout
+	{
+		// Right-to-left layout display for Middle Eastern languages
+		rtl = boolean value
+
+		// Align submenus
+		popup = value from -20 to 20
+	}
+}
+

Padding and Margin value syntax

+

Use the padding shorthand property with four values:

+padding = [1, 2, 3, 4] +
left = 1
+right = 2
+top = 3
+bottom = 4
+

Use the padding shorthand property with two values:

+padding = [4, 2] +
left = 4
+right = 4
+top = 2
+bottom = 2
+

Use the padding shorthand property with one value:

+padding = 4 +
left = 4
+right = 4
+top = 4
+bottom = 4
diff --git a/docs/examples/copy-path.html b/docs/examples/copy-path.html new file mode 100644 index 0000000..5ab4ac1 --- /dev/null +++ b/docs/examples/copy-path.html @@ -0,0 +1,32 @@ +
Copy Path example
+
// type can set with '~taskbar' equals all file types except taskbar.
+menu(type='file|dir|back|root|namespace' mode="multiple"  title='copy to clipboard' image=#ff00ff)
+{
+	// Appears only when multiple selections.
+	item(vis=@(sel.count > 1) title='Copy path (@sel.count) items selected'
+			cmd=command.copy(sel(false, "\n")))
+
+	item(mode="single" title=sel.path 
+			cmd=command.copy(sel.path))
+
+	item(mode="single" type='file|dir|back.dir'
+			vis=sel.short.len!=sel.path.len title=sel.short
+			cmd=command.copy(sel.short))
+	separator
+	item(mode="single" vis=@(sel.parent.len>3) title=sel.parent 
+			cmd=command.copy(sel.parent))
+	separator
+	item(mode="single" type='file|dir|back.dir' title=sel.file.name
+			cmd=command.copy(sel.file.name))
+		   
+	item(mode="single" type='file' title=sel.file.title
+			cmd=command.copy(sel.file.title))
+
+	item(mode="single" type='file' title=sel.file.ext
+		   cmd=command.copy(sel.file.ext))
+}
+
+ + + +
diff --git a/docs/examples/favorites.html b/docs/examples/favorites.html new file mode 100644 index 0000000..e2e9f1c --- /dev/null +++ b/docs/examples/favorites.html @@ -0,0 +1,27 @@ +
Favorite applications and directories example
+
menu(type='desktop|taskbar' title='Favorites' image=#00ff00)
+{
+	menu(title='Applications' image=#ff0000)
+	{
+		item(title='Command prompt' image cmd='cmd.exe')
+		item(title='PowerShell' image cmd='powershell.exe')
+		item(title='Registry editor' image cmd='regedit.exe')
+		separator
+		item(title='Paint' image cmd='mspaint.exe')
+		item(title='Notepad' image cmd='notepad.exe')
+	}
+	separator
+	menu(title='Directories' image=#0000ff)
+	{
+		item(title='Downloads' cmd=user.downloads)
+		item(title='Pictures' cmd=user.pictures)
+		item(title='Home' cmd=user.directory)
+		separator
+		item(title='Windows' cmd=sys.directory)
+		item(title='Program files' cmd=sys.prog())
+	}
+}
+
+ + +
diff --git a/docs/examples/goto.html b/docs/examples/goto.html new file mode 100644 index 0000000..095bb74 --- /dev/null +++ b/docs/examples/goto.html @@ -0,0 +1,53 @@ +
Goto example
+
menu(mode="multiple" title='Goto' sep="both" image= \uE14A)
+{
+	menu(title='Folder' image=\uE1F4)
+	{
+		item(title='Windows' image=inherit cmd=sys.dir)
+		item(title='System' image=inherit cmd=sys.bin)
+		item(title='Program Files' image=inherit cmd=sys.prog)
+		item(title='Program Files x86' image=inherit cmd=sys.prog32)
+		item(title='ProgramData' image=inherit cmd=sys.programdata)
+		item(title='Applications' image=inherit cmd='shell:appsfolder')
+		item(title='Users' image=inherit cmd=sys.users)
+		separator
+		item(title='Desktop' image=inherit cmd=user.desktop)
+		item(title='Downloads' image=inherit cmd=user.downloads)
+		item(title='Pictures' image=inherit cmd=user.pictures)
+		item(title='Documents' image=inherit cmd=user.documents)
+		item(title='Startmenu' image=inherit cmd=user.startmenu)
+		item(title='Profile' image=inherit cmd=user.dir)
+		item(title='AppData' image=inherit cmd=user.appdata)
+		item(title='Temp' image=inherit cmd=user.temp)
+	}
+	
+	item(title=title.control_panel image=\uE0F3 cmd='shell:::{5399E694-6CE5-4D6C-8FCE-1D8870FDCBA0}')
+	item(title='All Control Panel Items' image=\uE0F3 cmd='shell:::{ED7BA470-8E54-465E-825C-99712043E01C}')
+	item(title=title.run image=\uE14B cmd='shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}')
+   
+	menu(title=title.settings sep="before" image=id.settings.icon)
+	{
+		// https://docs.microsoft.com/en-us/windows/uwp/launch-resume/launch-settings-app
+		item(title='systeminfo' image=inherit cmd arg='/K systeminfo')
+		item(title='search' cmd='search-ms:' image=inherit)
+		item(title='settings' image=inherit cmd='ms-settings:')
+		item(title='about' image=inherit cmd='ms-settings:about')
+		item(title='usb' image=inherit cmd='ms-settings:usb')
+		item(title='network-status' image=inherit cmd='ms-settings:network-status')
+		item(title='network-ethernet' image=inherit cmd='ms-settings:network-ethernet')
+		item(title='personalization-background' image=inherit cmd='ms-settings:personalization-background')
+		item(title='personalization-colors' image=inherit cmd='ms-settings:colors')
+		item(title='lockscreen' image=\uE0F3 cmd='ms-settings:lockscreen')
+		item(title='personalization-start' image=inherit cmd='ms-settings:personalization-start')
+		item(title='appsfeatures' image=inherit cmd='ms-settings:appsfeatures')
+		item(title='optionalfeatures' image=inherit cmd='ms-settings:optionalfeatures')
+		item(title='defaultapps' image=inherit cmd='ms-settings:defaultapps')
+		item(title='yourinfo' image=inherit cmd='ms-settings:yourinfo')
+		item(title='windowsupdate' image=inherit cmd='ms-settings:windowsupdate')
+		item(title='windowsdefender' image=inherit cmd='ms-settings:windowsdefender')
+		item(title='network connections' image=inherit cmd='shell:::{7007ACC7-3202-11D1-AAD2-00805FC1270E}')
+	}
+}
+
+ +
diff --git a/docs/examples/index.html b/docs/examples/index.html new file mode 100644 index 0000000..5b34acf --- /dev/null +++ b/docs/examples/index.html @@ -0,0 +1,2 @@ +

Examples


+

This page contains some examples of what Shell can do.

\ No newline at end of file diff --git a/docs/examples/taskbar.html b/docs/examples/taskbar.html new file mode 100644 index 0000000..74a3671 --- /dev/null +++ b/docs/examples/taskbar.html @@ -0,0 +1,13 @@ +
Taskbar example
+
$hello_world = 'Hello World!'
+
+item(title=hello_world cmd=msg(hello_world))
+separator
+item(title='Command prompt' cmd args='/k echo @hello_world')
+separator
+menu(title='Sub menu')
+{
+  item(title='Open Paint' cmd='paint.exe' arg=sel.path)
+  separator
+  item(title='Open Notepad' cmd='notepad.exe' arg='"@sel.path"')
+}
\ No newline at end of file diff --git a/docs/expressions/color.html b/docs/expressions/color.html new file mode 100644 index 0000000..4d18b77 --- /dev/null +++ b/docs/expressions/color.html @@ -0,0 +1,5 @@ +

Color literal

+
+
Hexadecimal Colors
+

interprets color constants as hexadecimal if they are preceded by # and hexadecimal color is specified with: +#RRGGBB or #RRGGBBAA, where the RR (red), GG (green) and BB (blue)and AA (alpha) hexadecimal integers specify the components of the color. All values must be between 00 and FF.
For example, the #0000FF value is rendered as blue, because the blue component is set to its highest value (FF) and the others are set to 00.
There are 140 color names are predefined under the color scope.

\ No newline at end of file diff --git a/docs/expressions/comments.html b/docs/expressions/comments.html new file mode 100644 index 0000000..bc3d1b3 --- /dev/null +++ b/docs/expressions/comments.html @@ -0,0 +1,44 @@ +

Comments

+

Comments can be used to explain Shell code, and to make it more readable. It can also be used to prevent execution Shell code. Comments can be singled-lined or multi-lined.

+
+
Single-line Comments
+

+ Single-line comments start with two forward slashes (//).
+ Any text between // and the end of the line is ignored (will not be executed). +

+

This example uses a single-line comment before a line of code:

+
dynamic 
+{
+	// This is a comment
+	item(title='Hello World!')
+	
+	//item(title='Hello World!')
+}
+ +

This example uses a single-line comment at the end of a line of code:

+
dynamic 
+{
+    item(title='Hello World!') // This is a comment
+}
+
+
+
+
Multi-line Comments
+

+ Multi-line comments start with /* and ends with */.
+ Any text between /* and */ will be ignored. +

+
dynamic
+{
+	item(title='Hello,/* multiple-lines comment inside */ world')
+	
+	/*
+	item(title='test item 1')
+	item(title='test item 2')
+	*/
+}
+

+ Single or multi-line comments?
+ It is up to you which you want to use. Normally, we use // for short comments, and /* */ for longer. +

+
\ No newline at end of file diff --git a/docs/expressions/identifier.html b/docs/expressions/identifier.html new file mode 100644 index 0000000..064c530 --- /dev/null +++ b/docs/expressions/identifier.html @@ -0,0 +1,6 @@ +

Identifier

+
+

The identifier have unique titles described by fully qualified names that indicate a logical hierarchy.
The identifier that has no parameters. Parentheses are added when necessary to separate:

+

There is a hierarchy of keywords in that some keywords are always followed by others.

+
sel.path
+sel.path().ext
diff --git a/docs/expressions/index.html b/docs/expressions/index.html new file mode 100644 index 0000000..4bfb5f7 --- /dev/null +++ b/docs/expressions/index.html @@ -0,0 +1,12 @@ +

Expressions

+
+

Shell provides a variety of statements and expressions. Most of these will be familiar to developers who have programmed in Java script, C, C++, C#.

+

Expressions gives you all the power of Shell, but is using a simplified syntax that's easier to learn if you're a beginner, and makes you more productive if you're an expert.

+

To use expressions, you write them by using proper syntax. Syntax is the set of rules by which the words and symbols in an expression are correctly combined. Initially, expressions in Shell are a little bit hard to read. But with a good understanding of expression syntax and a little practice, it becomes much easier.

+ + diff --git a/docs/expressions/numeric.html b/docs/expressions/numeric.html new file mode 100644 index 0000000..a0a03a3 --- /dev/null +++ b/docs/expressions/numeric.html @@ -0,0 +1,21 @@ +

Numeric literals

+
+

There are two types of numbers. Integer and floating point.

+
Integer literals
+

An integer is a numeric literal(associated with numbers) without any fractional or exponential part. There are two types of integer literals:

+
    +
  1. Decimal literal (base 10)
  2. +
  3. Hexadecimal literal (base 16)
  4. +
+

1. Decimal-literal(base 10):
A non-zero decimal digit followed by zero or more decimal digits(0, 1, 2, 3, 4, 5, 6, 7, 8, 9).

+For example:
Decimal: 0, -9, 22 etc
+

2. Hexadecimal-literal(base 16):
0x followed by one or more hexadecimal digits(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f).

+For example: +
Hexadecimal: 0x7f, 0x2a, 0x521 etc
+
Floating-point iterals
+ +

Floating-point literals specify values that must have a fractional part. These values contain decimal points (.)

+For example: +
-2.0
0.0000234
+ + diff --git a/docs/expressions/operators.html b/docs/expressions/operators.html new file mode 100644 index 0000000..8f613a8 --- /dev/null +++ b/docs/expressions/operators.html @@ -0,0 +1,187 @@ +

Operators

+
+

An operator is a symbol that tells to perform specific mathematical or logical manipulations. Shell is rich in built-in operators and provide the following types of operators

+

This chapter will examine the arithmetic, relational, logical, bitwise, assignment and other operators one by one.

+
Arithmetic Operators
+

The five arithmetical operations supported

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorDescription
+Addition
-Subtraction
*Multiplication
/Division
%Modulo
+
+
Relational and comparison operators
+

Two expressions can be compared using relational and equality operators. For example, to know if two values are equal or if one is greater than the other.

+

The result of such an operation is either true or false (i.e., a Boolean value).

+

The relational operators are:

+ + + + + + + + + + + + + + + + + + + + + + + + +
operatordescription
==Equal to
!=Not equal to
<Less than
>Greater than
<=Less than or equal to
>=Greater than or equal to
+
+
Logical Operators (!, ||, &&)
+

The operator ! is operator for the Boolean operation NOT. It has only one operand, to its right, and inverts it, producing false if its operand is true, and true if its operand is false. Basically, it returns the opposite Boolean value of evaluating its operand. For example:

+

The logical operators && and || are used when evaluating two expressions to obtain a single relational result. The operator && corresponds to the Boolean logical operation AND, which yields true if both its operands are true, and false otherwise. The following panel shows the result of operator && evaluating the expression a && b:

+ + + + + + + + + + + + + + + + + + + +
operatordescription
&&Called Logical AND operator. If both the operands are non-zero, then condition becomes true.
||Called Logical OR Operator. If any of the two operands is non-zero, then condition becomes true.
! + Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true, then Logical NOT operator will make false. +
!(5 == 5)   // evaluates to false because the expression at its right (5 == 5) is true
+!(6 <= 4)   // evaluates to true because (6 <= 4) would be false
+!true       // evaluates to false
+!false      // evaluates to true
+
+
+
Conditional ternary operator
+

The conditional operator evaluates an expression, returning one value if that expression evaluates to true, and a different one if the expression evaluates as false. Its syntax is:

+
condition ? result1 : result2
+

If condition is true, the entire expression evaluates to result1, and otherwise to result2.

+
7==5 ? 4 : 3     // evaluates to 3, since 7 is not equal to 5.
+7==5+2 ? 4 : 3   // evaluates to 4, since 7 is equal to 5+2.
+5>3 ? a : b      // evaluates to the value of a, since 5 is greater than 3.
+a>b ? a : b      // evaluates to whichever is greater, a or b.
+ +
Bitwise Operators
+

Bitwise operators modify variables considering the bit patterns that represent the values they store.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorDescription
&Bitwise AND
|Bitwise inclusive OR
^Bitwise exclusive OR
~Unary complement (bit inversion)
<<Shift bits left
>>Shift bits right
+
Precedence of operators
+

A single expression may have multiple operators. For example:

+
x = 5 + 7 % 2
+

the above expression always assigns 6 to variable x, because the % operator has a higher precedence than the + operator, and is always evaluated before. Parts of the expressions can be enclosed in parenthesis to override this precedence order, or to make explicitly clear the intended effect. Notice the difference:

+
x = 5 + (7 % 2)    // x = 6 (same as without parenthesis)
+x = (5 + 7) % 2    // x = 0
+

From greatest to smallest priority, Operators are evaluated in the following order:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LevelPrecedence groupOperatorDescriptionGrouping
1Postfix (unary)++ --postfix increment / decrementLeft-to-right
()functional forms
[]subscript
.member access
2Prefix (unary)++ --prefix increment / decrementRight-to-left
~ !bitwise NOT / logical NOT
+ -unary prefix
4Arithmetic: scaling* / %multiply, divide, moduloLeft-to-right
5Arithmetic: addition+ -addition, subtractionLeft-to-right
6Bitwise shift<< >>shift left, shift rightLeft-to-right
7Relational< > <= >=comparison operatorsLeft-to-right
8Equality== !=equality / inequalityLeft-to-right
9And&bitwise ANDLeft-to-right
10Exclusive or^bitwise XORLeft-to-right
11Inclusive or|bitwise ORLeft-to-right
12Conjunction&&logical ANDLeft-to-right
13Disjunction||logical ORLeft-to-right
15Assignment-level expressions=assignmentRight-to-left
?:conditional operator
16Sequencing,comma separatorLeft-to-right
+

+ When an expression has two operators with the same precedence level, grouping determines which one is evaluated first: either left-to-right or right-to-left.
+ Enclosing all sub-statements in parentheses (even those unnecessary because of their precedence) improves code readability. +

\ No newline at end of file diff --git a/docs/expressions/string.html b/docs/expressions/string.html new file mode 100644 index 0000000..349b90e --- /dev/null +++ b/docs/expressions/string.html @@ -0,0 +1,37 @@ +

String literal

+
+

string is zero or more characters written inside single or double quotes.

+

You can use quotes inside a string, as long as they don't match the quotes surrounding the string:

+
$var1 = "It's alright"
+$var2 = "He is called 'Johnny'"
+$var3 = 'He is called "Johnny"'
+
+
Single quotes
+
+

single quotes allow you to use the syntax of expressions within them.
The @ sign must be placed before the expressions.

+
item(title = 'windows dir path: @sys.dir')
+
+
Double quotes
+
+

double quotes allow you to use the Escape Character inside them only.
The backslash (\) escape character turns special characters into characters.
The sequence \" inserts a double quote in a string:

+
$var1 = "hello\"world"
+// result: hello"world
+

The complete set of escape sequences is as follows:

+ + + + + + + + + + + + + + + + + +
\'Single quote
\"Double quote
\\Backslash
\0Null
\aAlert
\bBackspace
\fForm Feed
\nNew Line
\rCarriage Return
\tHorizontal Tab
\vVertical Tab
\uxxxxUnicode escape sequence (UTF-16) \uHHHH (range: 0000 - FFFF)
\xnnnnUnicode escape sequence for character with hex value nnnn (variable length version of \uxxxx)
\UxxxxxxxxUnicode escape sequence (UTF-32) \U00HHHHHH (range: 000000 - 10FFFF)
diff --git a/docs/expressions/variables.html b/docs/expressions/variables.html new file mode 100644 index 0000000..736b443 --- /dev/null +++ b/docs/expressions/variables.html @@ -0,0 +1,33 @@ +

Variables

+
+

Variables are containers for storing data values.

+ +

The general rules for constructing names for variables (unique identifiers) are:

+ +

+ All variables must be identified with unique names.
+ These unique names are called identifiers. + Identifiers can be short names (like x and y) or more descriptive names (age, sum, totalVolume). +

+

Note: It is recommended to use descriptive names in order to create understandable and maintainable code

+
Example
+
$hello_world = 'Hello World!'
+$test_add1 = 5 + 6
+
+item(title = hello_world cmd = msg(hello_world))
+
+menu(title = test_add1)
+{
+	$test_sub1 = 11 - 5
+	item(title = test_sub1)
+}
+ diff --git a/docs/functions/app.html b/docs/functions/app.html new file mode 100644 index 0000000..c174667 --- /dev/null +++ b/docs/functions/app.html @@ -0,0 +1,86 @@ +
APP
+
+

The namespace of the application contains file paths, version and some details.

+
+
+
app.directory
+

Returns the path of Shell directory.

+

Syntax

+
app.directory     // usage in section context
+'@app.directory'  // usage inside quoted-string literals
+
+ +
+
app.cfg
+

Returns the path of the configuration file shell.nss (or shell.shl + in older installations).

+

Syntax

+
app.cfg     // usage in section context
+'@app.cfg'  // usage inside quoted-string literals
+
+ +
+
app.dll
+

Returns the path of shell.dll.

+

Syntax

+
app.dll     // usage in section context
+'@app.dll'  // usage inside quoted-string literals
+
+ +
+
app.exe
+

Returns the path of shell.exe.

+

Syntax

+
app.exe     // usage in section context
+'@app.exe'  // usage inside quoted-string literals
+
+ +
+
app.name
+

Returns application name.

+

Syntax

+
app.name     // usage in section context
+'@app.name'  // usage inside quoted-string literals
+
+ +
+
app.version
+

Returns Shell version.

+

Syntax

+
app.version     // usage in section context
+'@app.version'  // usage inside quoted-string literals
+
+ +
+
app.is64
+

Returns the architecture of the application.

+

Syntax

+
app.is64     // usage in section context
+'@app.is64'  // usage inside quoted-string literals
+
+ +
+
app.about
+

Returns Shell information.

+

Syntax

+
app.about     // usage in section context
+'@app.about'  // usage inside quoted-string literals
+
+ +
+
app.reload
+

Reload the configuration file. +

+

Syntax

+
app.reload     // usage in section context
+'@app.reload'  // usage inside quoted-string literals
+
+ +
+
app.unload
+

Unload the configuration file. +

+

Syntax

+
app.unload     // usage in section context
+'@app.unload'  // usage inside quoted-string literals
+
diff --git a/docs/functions/appx.html b/docs/functions/appx.html new file mode 100644 index 0000000..38b07a1 --- /dev/null +++ b/docs/functions/appx.html @@ -0,0 +1,104 @@ +

APPX

+
+
+
appx or appx.path
+

Returns the path of Package.

+

Syntax

+ appx(packageName)
+ appx.path(packageName)
+

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.path("WindowsTerminal")
+// result:
+// C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.11.3471.0_x64__8wekyb3d8bbwe
+
+
+ +
+
appx.name
+

Returns the display name of the Package.

+

Syntax

+ appx.name(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.name("WindowsTerminal")
+// result:
+// Windows Terminal
+
+
+ +
+
appx.id
+

Returns the full name of the Package.

+

Syntax

+ appx.id(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.id("WindowsTerminal")
+// result:
+// Microsoft.WindowsTerminal_1.11.3471.0_x64__8wekyb3d8bbwe
+
+
+ +
+
appx.family
+

Returns the family name of the Package.

+

Syntax

+ appx.family(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.family("WindowsTerminal")
+// result:
+// Microsoft.WindowsTerminal_8wekyb3d8bbwe
+
+
+ +
+
appx.version
+

Returns version of the Package.

+

Syntax

+ appx.version(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.version("WindowsTerminal")
+// result:
+// 1.11.3471.0
+
+
+ +
+
appx.shell
+

Return package settings to run.

+

Syntax

+ appx.shell(packageName) +

Parameters

+
+
packageName
+
can be passed in full name or part of name.
+
+

Example

+
appx.shell("WindowsTerminal")
+// result:
+// shell:appsFolder\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App
+
+
diff --git a/docs/functions/clipboard.html b/docs/functions/clipboard.html new file mode 100644 index 0000000..39b2cf0 --- /dev/null +++ b/docs/functions/clipboard.html @@ -0,0 +1,39 @@ +
CLIPBOARD
+
+

Clipboard handling functions.

+
+ +
+
clipboard.get
+

Returns the value of the stored clipboard.

+

Syntax

+ clipboard.get +
+ +
+
clipboard.set
+

Store a value in the clipboard.

+

Syntax

+ clipboard.set("Hello world!") +
+ +
+
clipboard.length
+

Returns the length of the value stored in the clipboard.

+

Syntax

+ clipboard.length +
+ +
+
clipboard.is_empty
+

Verifies that there is a value stored in the clipboard.

+

Syntax

+ clipboard.is_empty +
+ +
+
clipboard.empty
+

Empty values stored in the clipboard.

+

Syntax

+ clipboard.empty +
diff --git a/docs/functions/color.html b/docs/functions/color.html new file mode 100644 index 0000000..d9fb2bb --- /dev/null +++ b/docs/functions/color.html @@ -0,0 +1,173 @@ +
COLOR
+
+

Color namespace contains predefined colors

+
+
+color.aliceblue
+color.antiquewhite
+color.aqua
+color.aquamarine
+color.azure
+color.beige
+color.bisque
+color.black
+color.blanchedalmond
+color.blue
+color.blueviolet
+color.brown
+color.burlywood
+color.cadetblue
+color.chartreuse
+color.chocolate
+color.coral
+color.cornflowerblue
+color.cornsilk
+color.crimson
+color.cyan
+color.darkblue
+color.darkcyan
+color.darkgoldenrod
+color.darkgray
+color.darkgreen
+color.darkkhaki
+color.darkmagenta
+color.darkolivegreen
+color.darkorange
+color.darkorchid
+color.darkred
+color.darksalmon
+color.darkseagreen
+color.darkslateblue
+color.darkslategray
+color.darkturquoise
+color.darkviolet
+color.deeppink
+color.deepskyblue
+color.dimgray
+color.dodgerblue
+color.firebrick
+color.floralwhite
+color.forestgreen
+color.fuchsia
+color.gainsboro
+color.ghostwhite
+color.gold
+color.goldenrod
+color.gray
+color.green
+color.greenyellow
+color.honeydew
+color.hotpink
+color.indianred
+color.indigo
+color.ivory
+color.khaki
+color.lavender
+color.lavenderblush
+color.lawngreen
+color.lemonchiffon
+color.lightblue
+color.lightcoral
+color.lightcyan
+color.lightgoldenrodyellow
+color.lightgray
+color.lightgreen
+color.lightpink
+color.lightsalmon
+color.lightseagreen
+color.lightskyblue
+color.lightslategray
+color.lightsteelblue
+color.lightyellow
+color.lime
+color.limegreen
+color.linen
+color.magenta
+color.maroon
+color.mediumaquamarine
+color.mediumblue
+color.mediumorchid
+color.mediumpurple
+color.mediumseagreen
+color.mediumslateblue
+color.mediumspringgreen
+color.mediumturquoise
+color.mediumvioletred
+color.midnightblue
+color.mintcream
+color.mistyrose
+color.moccasin
+color.navajowhite
+color.navy
+color.oldlace
+color.olive
+color.olivedrab
+color.orange
+color.orangered
+color.orchid
+color.palegoldenrod
+color.palegreen
+color.paleturquoise
+color.palevioletred
+color.papayawhip
+color.peachpuff
+color.peru
+color.pink
+color.plum
+color.powderblue
+color.purple
+color.red
+color.rosybrown
+color.royalblue
+color.saddlebrown
+color.salmon
+color.sandybrown
+color.seagreen
+color.seashell
+color.sienna
+color.silver
+color.skyblue
+color.slateblue
+color.slategray
+color.snow
+color.springgreen
+color.steelblue
+color.tan
+color.teal
+color.thistle
+color.tomato
+color.transparent
+color.turquoise
+color.violet
+color.wheat
+color.white
+color.whitesmoke
+color.yellow
+color.yellowgreen
+
+
+
color.rgb(red, green, blue)
+
+
color.box
+
color.box(#ff0000)
+
+
color.random or color.random(min, max)
+
color.random
+color.random(0x808080, 0xf0f0f0)
+
+
+
+color.default
+color.invert
+color.accent
+color.accent_light1
+color.accent_light2
+color.accent_light3
+color.accent_dark1
+color.accent_dark2
+color.accent_dark3
+color.opacity
+color.lighten
+color.darken
+color.rgba
+
diff --git a/docs/functions/command.html b/docs/functions/command.html new file mode 100644 index 0000000..0ad0ba3 --- /dev/null +++ b/docs/functions/command.html @@ -0,0 +1,55 @@ +
COMMAND
+
+
command.copy, command.copy_to_clipboard
+

copy to parameter clipboard.

+

Syntax

+ command.copy('string copy to clipboard') +
+ +
+
command.sleep(milliseconds)
+

Suspends the execution of the current thread until the time-out interval elapses.

+

Syntax

+ command.sleep(1000) +
+ +
+
command.random
+

Suspends the execution of the current thread until the time-out interval elapses.

+

Syntax

+ command.random(min value, max value) +
+ +
+
command.navigate
+

Opens a folder in the same explorer window.

+

Syntax

+ command.navigate(path) +
+ +
+
command.cascade_windows
+command.copy_to_folder
+command.customize_this_folder
+command.find
+command.folder_options
+command.invert_selection
+command.minimize_all_windows
+command.move_to_folder
+command.redo
+command.refresh
+command.restart_explorer
+command.restore_all_windows
+command.run
+command.search
+command.select_all
+command.select_none
+command.show_windows_side_by_side
+command.show_windows_stacked
+command.switcher
+command.toggle_desktop
+command.toggleext
+command.togglehidden
+command.undo
+
+
diff --git a/docs/functions/id.html b/docs/functions/id.html new file mode 100644 index 0000000..7c7dbd0 --- /dev/null +++ b/docs/functions/id.html @@ -0,0 +1,175 @@ +
ID
+

The namespace of the id contains the identifiers for most of the system context menus items where the item's title or + icons can be returned

+
+
+
Syntax
+ id.copy
+ id.copy.title
+ id.copy.icon or icon.copy +
+ +
+
List
+
id.add_a_network_location
+id.adjust_date_time
+id.align_icons_to_grid
+id.arrange_by
+id.auto_arrange_icons
+id.autoplay
+id.cancel
+id.cascade_windows
+id.cast_to_device
+id.cleanup
+id.collapse
+id.collapse_all_groups
+id.collapse_group
+id.command_prompt
+id.compressed
+id.configure
+id.content
+id.control_panel
+id.copy
+id.copy_as_path
+id.copy_here
+id.copy_path
+id.copy_to
+id.copy_to_folder
+id.cortana
+id.create_shortcut
+id.create_shortcuts
+id.create_shortcuts_here
+id.customize_notification_icons
+id.customize_this_folder
+id.cut
+id.delete
+id.desktop
+id.details
+id.device_manager
+id.disconnect
+id.disconnect_network_drive
+id.display_settings
+id.edit
+id.eject
+id.empty_recycle_bin
+id.erase_this_disc
+id.exit_explorer
+id.expand
+id.expand_all_groups
+id.expand_group
+id.expand_to_current_folder
+id.extra_large_icons
+id.extract_all
+id.extract_to
+id.file_explorer
+id.folder_options
+id.format
+id.give_access_to
+id.group_by
+id.include_in_library
+id.insert_unicode_control_character
+id.install
+id.large_icons
+id.list
+id.lock_all_taskbars
+id.lock_the_taskbar
+id.make_available_offline
+id.make_available_online
+id.manage
+id.map_as_drive
+id.map_network_drive
+id.medium_icons
+id.merge
+id.more_options
+id.mount
+id.move_here
+id.move_to
+id.move_to_folder
+id.new
+id.new_folder
+id.new_item
+id.news_and_interests
+id.next_desktop_background
+id.open
+id.open_as_portable
+id.open_autoplay
+id.open_command_prompt
+id.open_command_window_here
+id.open_file_location
+id.open_folder_location
+id.open_in_new_process
+id.open_in_new_tab
+id.open_in_new_window
+id.open_new_tab
+id.open_new_window
+id.open_powershell_window_here
+id.open_windows_powershell
+id.open_with
+id.options
+id.paste
+id.paste_shortcut
+id.personalize
+id.pin_current_folder_to_quick_access
+id.pin_to_quick_access
+id.pin_to_start
+id.pin_to_taskbar
+id.play
+id.play_with_windows_media_player
+id.power_options
+id.preview
+id.print
+id.properties
+id.reconversion
+id.redo
+id.refresh
+id.remove_from_quick_access
+id.remove_properties
+id.rename
+id.restore
+id.restore_default_libraries
+id.restore_previous_versions
+id.rotate_left
+id.rotate_right
+id.run
+id.run_as_administrator
+id.run_as_another_user
+id.search
+id.select_all
+id.send_to
+id.set_as_desktop_background
+id.set_as_desktop_wallpaper
+id.settings
+id.share
+id.share_with
+id.shield
+id.show_all_folders
+id.show_cortana_button
+id.show_desktop_icons
+id.show_file_extensions
+id.show_hidden_files
+id.show_libraries
+id.show_network
+id.show_pen_button
+id.show_people_on_the_taskbar
+id.show_task_view_button
+id.show_the_desktop
+id.show_this_pc
+id.show_touch_keyboard_button
+id.show_touchpad_button
+id.show_windows_side_by_side
+id.show_windows_stacked
+id.small_icons
+id.sort_by
+id.store
+id.task_manager
+id.taskbar_settings
+id.tiles
+id.troubleshoot_compatibility
+id.turn_off_bitlocker
+id.turn_on_bitlocker
+id.undo
+id.unpin_from_quick_access
+id.unpin_from_start
+id.unpin_from_taskbar
+id.view
+
diff --git a/docs/functions/image.html b/docs/functions/image.html new file mode 100644 index 0000000..0562883 --- /dev/null +++ b/docs/functions/image.html @@ -0,0 +1,81 @@ +
IMAGE (ICON)
+

The image namespace contains functions that return an icon and are only assigned to the image property +

+
+
image.glyph
+

Return font icon with color and size option.

+

Syntax

+ image.glyph(0xE00B)
+ image.glyph(\uE00B)
+ image.glyph("\uE00B")
+ image.glyph("\xE00B")
+
+ image.glyph(0xE00B, #0000ff)
+ image.glyph(0xE00B, #0000ff, 10)
+ image.glyph(0xE00B, #0000ff, 12, "Segoe MDL2 Assets")
+
+
+
image.res
+

Returns an icon through a path or through resources.

+

Syntax

+ image.res(path)
+ image.res(path, index)
+ image.res(path, -id)
+
+ image(path)
+ image(path, index)
+ image(path, -id)
+
+
+
image.svg, image.svgf
+

Returns an svg image via a string or from a file path.

+

Syntax

+ image.svg('<svg viewBox="0 0 100 100"><path fill="red" d="M0 0 L 100 0 L50 + 100 Z"/></svg>')
+ image.svgf(path)
+
+
+
image.rect
+

Returns a colored rectangle icon of an optional size.

+

Syntax

+ image.rect(#0000ff)
+ image.rect(#0000ff, 10)
+
+ +
+
image.segoe
+

Returns a glyph from "Segoe Fluent Icons" if present then "Segoe MDL2 Assets".

+

Syntax

+ image.segoe(\uxxxx)
+ image.segoe(\uxxxx, 10)
+
+ +
+
image.fluent
+

Returns a glyph from "Segoe Fluent Icons" with optional size.

+

Syntax

+ image.fluent(\uxxxx)
+ image.fluent(\uxxxx, 10)
+
+ +
+
image.mdl
+

Returns a glyph from "Segoe MDL2 Assets" with optional size.

+

Syntax

+ image.mdl(\uxxxx)
+ image.mdl(\uxxxx, 10)
+
+ +
+
image.default
+

+

Syntax

+ image.default +
+ +
+
icon.box
+

+

Syntax

+ icon.box([["path to file"], [index]]) +
diff --git a/docs/functions/index.html b/docs/functions/index.html new file mode 100644 index 0000000..6192cb0 --- /dev/null +++ b/docs/functions/index.html @@ -0,0 +1,156 @@ +

Functions

+

The functions and variables have unique titles described by fully qualified names that indicate a logical hierarchy.

+

Shell has a number of functions and variables built into it that are always available. They are listed here in alphabetical order.

+ +
+
indexof
+

Find the position of a menu item.

+

Syntax

+ indexof(expression[, default position]) +
+ +
+
if
+

Conditionally executes another statement.

+

Syntax

+ if(condition-expression)

+ if(condition-expression, true-expression)

+ if(condition-expression, true-expression, false-expression) +
+ +
+
null
+

Returns a null value.

+

Syntax

+ null(expression)

+
+ +
+
length (len)
+

Returns length of string and array type

+

Syntax

+ length(expression)

+
+ +
+
quote
+

Returns text with a double quotation mark.

+

Syntax

+ quote(expression) +
+ +
+
char
+

Returns the value of the numeric parameter to a character.

+

Syntax

+ char(numeric-expression) +
+ +
+
var
+

Returns the value of the passed variable

+

Syntax

+ var(expression) +
+ +
+
tohex
+

Converting the value of the passed numeric expression to hexadecimal string.

+

Syntax

+ tohex(numeric-expression) +
+ +
+
equal
+

Returns true if the parameters passed are equal.

+

Syntax

+ equal(expression-1, expression-2) +
+ +
+
not
+

Returns true if the parameters passed are not equal.

+

Syntax

+ not(expression-1, expression-2) +
+ +
+
greater
+

Returns true if the first parameter is greater than the second parameter.

+

Syntax

+ greater(expression-1, expression-2) +
+ +
+
less
+

Returns true if the first parameter is less than the second parameter.

+

Syntax

+ less(expression-1, expression-2) +
+ +
+
shl
+

bitwise left shift.

+

Syntax

+ shl(shift-expression, additive-expression) +
+ +
+
shr
+

bitwise right shift.

+

Syntax

+ shr(shift-expression, additive-expression) +
+ +
+
cmd visibility enumerations
+

The flags that specify how an application is to be displayed when it is opened.

+
cmd.hidden
+cmd.show
+cmd.visible
+cmd.normal
+cmd.maximized
+cmd.minimized
+
+ +
+
Selection mode enumerations
+

Syntax

+
mode.none
+mode.single
+mode.multiple
+mode.multiunique
+mode.multisingle
+mode.multi
+
+ +
+
Selection type enumerations
+

Syntax

+
type.desktop
+type.directory(dir)
+type.drive
+type.dvd
+type.file
+type.fixed
+type.namespace
+type.remote
+type.unknown
+type.usb
+type.vhd
+
+ +
Keywords
+
null
+bool
+true
+false
+auto
+none
+default
+
+ +
app | color | image | io | key | msg | path | reg | sel | str | sys | user| input +| ini | clipboard +
+ diff --git a/docs/functions/ini.html b/docs/functions/ini.html new file mode 100644 index 0000000..0457f4d --- /dev/null +++ b/docs/functions/ini.html @@ -0,0 +1,17 @@ +
INI
+
+

Functions for handling with .ini files.

+
+
+
ini.get
+

Returns the value of the key

+

Syntax

+ ini.get('path\to\ini file', "section", "key") +
+ +
+
ini.set
+

Set the key value.

+

Syntax

+ ini.set('path\to\ini file', "section", "key", "value") +
\ No newline at end of file diff --git a/docs/functions/input.html b/docs/functions/input.html new file mode 100644 index 0000000..66dbc80 --- /dev/null +++ b/docs/functions/input.html @@ -0,0 +1,18 @@ +
INPUT
+
+

The input box allows the user to enter and pass data.

+
+
+
input
+

Show the input box with the window title and call parameter passed.
+The function returns a non-zero value if the OK button is pressed. Otherwise, it returns zero.

+

Syntax

+ input("Title", "Prompt") +
+ +
+
input.result
+

Returns the input value resulting from the input box.

+

Syntax

+ input.result +
diff --git a/docs/functions/io.html b/docs/functions/io.html new file mode 100644 index 0000000..0728234 --- /dev/null +++ b/docs/functions/io.html @@ -0,0 +1,183 @@ +
IO
+
+
+
io.attribute enumerations.
+

Syntax

+
io.attribute.archive
+io.attribute.compressed
+io.attribute.device
+io.attribute.directory
+io.attribute.encrypted
+io.attribute.hidden
+io.attribute.invalid
+io.attribute.normal
+io.attribute.offline
+io.attribute.readonly
+io.attribute.sparsefile
+io.attribute.system
+io.attribute.temporary
+io.attribute.virtual
+
+ +
+
io.attributes
+

Retrieves file system attributes for a specified path.

+

Syntax

+ io.attributes(path)

+

attribute verification

+
// check if path is hidden
+io.attribute.hidden(path)
+
+// check if path is directory
+io.attribute.directory(path)
+
+var { atrr = io.attributes(path) }
+
+// check if attr is hidden
+io.attribute.hidden(atrr)
+
+// check if attr is directory
+io.attribute.directory(atrr)
+
+ +
+
io.copy
+

Copies an existing file to a new file.

+

Syntax

+ io.copy(pathFrom, pathTo) +
+ io.copy(pathFrom, pathTo, options) + options:
+ 1 = skip_existing, 2 = overwrite_existing, 4 = update_existing, 16 = recursive
+default = update_existing | recursive

+ Example:
+ io.copy('c:\old', 'd:\new', 16 | 4) +
+ +
+
io.move
+

Moves an existing file or a directory, including its children..

+

Syntax

+ io.move(oldPath, newPath) +
+ +
+
io.rename
+

Rename a file or directory.

+

Syntax

+ io.rename(oldName, newName) +
+ +
+
io.delete
+

Deletes an existing path.

+

Syntax

+ io.delete(path) +
+ +
+
io.directory.create (io.dir.create)
+

Create new directory.

+

Syntax

+ io.directory.create(path) +
+ +
+
io.directory.exists (io.dir.exists)
+

Check if one or more directories exists.

+

Syntax

+ io.directory.exists(path) +
+ io.directory.exists(path1, path2, path3, ...) +
+ +
+
io.directory.empty (io.dir.empty)
+

Check if one or more directory is empty.

+

Syntax

+ io.directory.empty(path) +
+ io.directory.empty(path1, path2, path3, ...) +
+ +
File functions.
+ +
+
io.file.size
+

Retrieves the size of the specified file, in bytes.

+

Syntax

+ io.file.size(path) +
+ +
+
io.file.exists
+

Check if one or more files exists.

+

Syntax

+ io.file.exists(path) +
+ io.file.exists(path1, path2, path3, ...) +
+ +
+
io.file.read
+

Read file contents as text with character count option.

+

Syntax

+ io.file.read(path)
+ io.file.read(path, 12) +
+ +
+
io.file.create
+

Create new file with content option.

+

Syntax

+ io.file.create(path)
+ io.file.create(path, "Hello World!") +
+ +
+
io.file.write
+

Writing to a file with new content.

+

Syntax

+ io.file.write(path, "Hello World!") +
+ +
+
io.file.append
+

Appends text to an existing file, or to a new file if the specified file does not exist.

+

Syntax

+ io.file.append(path, "Hello ") +
+ io.file.append(path, "World!") +
+ +
+
io.datetime
+

Gets or Sets the time of the file.

+

Syntax

+ get date time + +io.datetime.created(sel.path)
+io.datetime.modified(sel.path)
+io.datetime.accessed(sel.path)
+
+io.datetime.created(sel.path, 'y/m/d')
+io.datetime.modified(sel.path, 'y/m/d')
+io.datetime.accessed(sel.path, 'y/m/d')
+ +
+
+ set date time +
+ +io.datetime.created(sel.path,2000,1,1))
+io.datetime.modified(sel.path,2000,1,1))
+io.datetime.accessed(sel.path,2000,1,1))
+
+
+ +
+
io.meta
+

Gets meta data by property key.

+

Syntax

+ io.meta('path\to\file',"System.Size")) +
diff --git a/docs/functions/key.html b/docs/functions/key.html new file mode 100644 index 0000000..2e15999 --- /dev/null +++ b/docs/functions/key.html @@ -0,0 +1,92 @@ +
KEY
+

Keyboard functions

+
+
keys enumerations
+
key.alt
+key.apps
+key.back
+key.cancel
+key.capital
+key.capslock
+key.control
+key.delete
+key.down
+key.end
+key.enter
+key.escape
+key.execute
+key.f1
+key.f10
+key.f11
+key.f12
+key.f2
+key.f3
+key.f4
+key.f5
+key.f6
+key.f7
+key.f8
+key.f9
+key.help
+key.home
+key.insert
+key.lalt
+key.lcontrol
+key.left
+key.lshift
+key.lwin
+key.next
+key.none
+key.pagedown
+key.pageup
+key.pause
+key.play
+key.print
+key.printscreen
+key.prior
+key.ralt
+key.rcontrol
+key.return
+key.right
+key.rshift
+key.rwin
+key.shift
+key.snapshot
+key.space
+key.tab
+key.up
+key.win
+
+ +
+
key
+

Syntax

+
+// check if SHIFT key is pressed
+key(key.shift)
+
+// or
+key == key.shift
+
+// or
+key.shift()
+
+// check if tow keys (SHIFT+CTRL) is pressed
+key(key.shift, key.control)
+
+// check if keys (SHIFT+CTRL+X) is pressed
+key(key.shift, key.control, 87)
+	
+
+ +
+
key.send
+

Send one or more keys to the current window.

+

Syntax

+
key.send(key.f5)
+key.send(key.ctrl,'n')
+key.send(key.shift, key.delete)
+
+ + + diff --git a/docs/functions/msg.html b/docs/functions/msg.html new file mode 100644 index 0000000..bbc16f5 --- /dev/null +++ b/docs/functions/msg.html @@ -0,0 +1,130 @@ +

MSG

+

Displays a modal dialog box that contains a system icon, a set of buttons, and a brief application-specific message, + such as status or error information. The message box returns an integer value that indicates which button the user + clicked.

+ +
Syntax
+
+msg(text)
+msg(text, title)
+msg(text, title, flags)
+
+
+
Parameters
+ + + + + + + + + + + + + +
textThe message to be displayed.
titleThe dialog box title. If this parameter is NULL, the default title is Nilesoft Shell.
flagsThe contents and behavior of the dialog box. This parameter can be a combination of flags from the following + groups of flags. +
+ +
Flags
+
+
To display an icon in the message box, specify one of the following values.
+
+
msg.error
+
A stop-sign icon appears in the message box.
+ +
msg.question
+
A question-mark icon appears in the message box.
+ +
msg.warning
+
An exclamation-point icon appears in the message box.
+ +
msg.info
+
An icon consisting of a lowercase letter i in a circle appears in the message box.
+
+
+
To indicate the buttons displayed in the message box, specify one of the following values.
+
+
msg.ok
+
The message box contains one push button: OK. This is the default.
+ +
msg.okcancel
+
The message box contains two push buttons: OK and Cancel.
+ +
msg.yesnocancel
+
The message box contains three push buttons: Yes, No, and Cancel.
+ +
msg.yesno
+
The message box contains two push buttons: Yes and No.
+
+
+
To indicate the default button, specify one of the following values.
+
+
msg.defbutton1
+
The first button is the default button.
+ +
msg.defbutton2
+
The second button is the default button.
+ +
msg.defbutton3
+
The third button is the default button.
+
+
+
To indicate the modality of the dialog box, specify one of the following values.
+
+
msg.applmodal
+
The user must respond to the message box before continuing work in the current window. However, the user can + move to the windows of other threads and work in those windows. +
+
msg.taskmodal
+
Same as msg.applmodal except that all the top-level windows belonging to the current thread are disabled.
+
+
+
To specify other options, use one or more of the following values.
+
+
msg.right
+
The text is right-justified.
+
msg.rtlreading
+
Displays message and caption text using right-to-left reading order on Hebrew and Arabic systems.
+
msg.setforeground
+
The message box becomes the foreground window.
+
msg.topmost
+
+
+
+
Return value
+

If a message box has a Cancel button, the function returns the msg.idcancel value if either the + ESC key is pressed or the Cancel button is selected. If the message box has no Cancel button, pressing + ESC will no effect - unless an msg.ok button is present. If an msg.ok button is + displayed and the user presses ESC, the return value will be msg.idok.

+

If the function fails, the return value is zero.
+ If the function succeeds, the return value is one of the following values: +

+
+
msg.idok or 1
+
The OK button was selected.
+ +
msg.idcancel or 2
+
The Cancel button was selected.
+ +
msg.idyes or 6
+
The Yes button was selected.
+ +
msg.idno or 7
+
The No button was selected.
+
+
Examples
+
msg("Hello, Warld!","NileSoft Shell", msg.info | msg.ok)
+msg("Hello, Warld!","NileSoft Shell")
+msg("Hello, Warld!")
+

+
+
msg.beep(type)
+

Plays a waveform sound. The waveform sound for each sound type is identified by an entry in the registry.

+

Syntax

+ msg.beep
+ msg.beep(msg.error)
+ msg.beep(msg.warning) +
\ No newline at end of file diff --git a/docs/functions/path.html b/docs/functions/path.html new file mode 100644 index 0000000..3961d5a --- /dev/null +++ b/docs/functions/path.html @@ -0,0 +1,253 @@ +
PATH
+
+ +
+
path.combine (path.join)
+

Combines an array of strings into a path.

+

Syntax

+ path.combine(path1, path2)
+ path.combine("C:", "Windows", "Explorer.exe") +
+ +
+
path.currentdirectory (path.curdir)
+

Retrieves the current directory for the current process.

+

Syntax

+ path.currentdirectory +
+ +
+
path.directory.name (path.dir.name)
+

Return the directory name from the path.

+

Syntax

+ path.directory.name('c:\windows\system32') // returns: system32 +
+ +
+
path.directory.box (path.dir.box)
+

Shows the directory selection box and returns the path of the specified directory.

+

Syntax

+ path.directory.box +
+ +
+
path.empty
+

Check if one or more path is empty.

+

Syntax

+ path.empty(path)
+ path.empty(path1, path2, ...) +
+ +
+
path.exists
+

Check if one or more path exists..

+

Syntax

+ path.exists(path)
+ path.exists(path1, path2, ...) +
+ +
+
path.full
+

Returns the absolute path for the specified path string.

+

Syntax

+ path.full(path) +
+ +
+
path.short
+

Retrieves the short path form of the specified path.

+

Syntax

+ path.short(path) +
+ +
+
path.name
+

Return the name from the path.

+

Syntax

+ path.name(path) +
+ +
+
path.location (path.parent)
+

Return the path of the parent

+

Syntax

+ path.location(path) +
+ +
+
path.location.name
+

Return the name from the parent

+

Syntax

+ path.location.name(path) +
+ +
+
path.root
+

Return the drive path

+

Syntax

+ path.root(path) +
+ +
+
path.title
+

Return the title from the path

+

Syntax

+ path.title(path) +
+ +
+
path.type
+

Return the type of path

+

Syntax

+ path.type(path) == type.file +
+ +
+
path.file.name
+

Return the name of path

+

Syntax

+ path.file.name(path) +
+ +
+
path.file.title
+

Return the name of path without extension

+

Syntax

+ path.file.title(path) +
+ +
+
path.file.ext
+

Return the extension of path

+

Syntax

+ path.file.ext(path) +
+ +
+
path.file.box
+

Shows the file selection box and returns the path of the specified file.

+

Syntax

+ path.file.box
+ path.file.box('All|*.*|Text|*.txt')
+ path.file.box('exe|*.exe', 'c:\windows')
+ path.file.box('exe|*.exe', 'c:\windows', 'explorer.exe') +
+ +
+
path.files
+

Returns all files with the ability to filter.

+

Syntax

+
path.files(sys.dir, ["*"], flags[2=files | 3=dirs | 5=files+dirs | 8=quots | 16=full path], sep)
+	
+// get all files and dirs
+path.files(sys.dir)
+path.files(sys.dir, "*")
+
+// get all files with .exe
+path.files(sys.dir,"*.exe")
+
+// full path + quots
+path.files(sys.dir, '*', 8|16)
+	
+ +
+ +
+
path.isabsolute
+

+

Syntax

+ path.isabsolute(path) +
+ +
+
path.isrelative
+

+

Syntax

+ path.isrelative(path) +
+ +
+
path.isfile
+

+

Syntax

+ path.isfile(path) +
+ +
+
path.isdirectory
+

+

Syntax

+ path.isdirectory(path) +
+ +
+
path.isroot (path.isdrive)
+

+

Syntax

+ path.isdrive(path) +
+ +
+
path.isclsid (path.isnamespace)
+

+

Syntax

+ path.isclsid(path) +
+ +
+
path.isexe
+

+

Syntax

+ path.isexe(path) +
+ +
+
path.removeextension
+

Remove the extension from the passed parameter.

+

Syntax

+ path.removeextension +
+ +
+
path.lnk
+

Return a path from the shortcut

+

Syntax

+ path.lnk(path) +
+
+
path.lnk.type
+

Return type from the shortcut

+

Syntax

+ path.lnk.type(path) +
+
+
path.lnk.dir
+

Return a dir path from the shortcut

+

Syntax

+ path.lnk.dir(path) +
+
+
path.lnk.icon
+

Return a icon path and index from the shortcut

+

Syntax

+ path.lnk.icon(path) +
+
+
path.getknownfolder
+

Retrieves the full path of a known folder identified.

+

Syntax

+ path.getknownfolder('{905e63b6-c1bf-494e-b29c-65b732d3d21a}') +
+ +
+
path.separator(path.sep)
+

Replacing the back slash with a forward slash or defining a spacer.

+

Syntax

+ path.separator('c:\windows\system32') return "c:/windows/system32"
+ path.separator('c:\windows\system32', '#') return "c:#windows#system32" +
+ +
+
path.wsl
+

convert the path to wsl path

+
diff --git a/docs/functions/process.html b/docs/functions/process.html new file mode 100644 index 0000000..e5a5464 --- /dev/null +++ b/docs/functions/process.html @@ -0,0 +1,15 @@ +
PROCESS
+
+

+
+
+
Syntax
+

+process.handle
+process.name
+process.id
+process.path
+process.is_explorer
+process.used
+
+
\ No newline at end of file diff --git a/docs/functions/reg.html b/docs/functions/reg.html new file mode 100644 index 0000000..b853ed7 --- /dev/null +++ b/docs/functions/reg.html @@ -0,0 +1,92 @@ +
REG
+

Registry functions

+
+
+
Registry hive enum
+

Syntax

+
HKCU
+HKCR
+HKLM
+HKU
+HKEY_CLASSES_ROOT
+HKEY_CURRENT_USER
+HKEY_LOCAL_MACHINE
+HKEY_USERS
+
+
+
+
Registry value type Enum
+

Syntax

+
reg.none	// No data type
+reg.sz		// REG_SZ
+reg.expand	// REG_EXPAND_SZ
+reg.binary	// REG_BINARY
+reg.multi	// REG_MULTI_SZ
+reg.dword	// REG_DWORD
+reg.qword	// REG_QWORD
+
+ +
+
The function of reading from the Registry.
+

Syntax

+ reg(reg.lm, 'SOFTWARE\Microsoft\Windows NT\CurrentVersion','ProductName')

+ reg(reg.cr, 'txtfile\DefaultIcon') +
+ +
+
reg.exists
+

Check that the key or value name exists

+

Syntax

+

Check that the key exists

+ reg.exists('HKCU\Control Panel\Desktop') +

Check that the value name exists

+ reg.exists('HKCU\Control Panel\Desktop', "WallPaper") +
+ +
+
reg.get
+

Read data by value name

+

Syntax

+
reg('HKCU\Control Panel\Desktop', "WallPaper")
+reg.get('HKCU\Control Panel\Desktop', "WallPaper")
+reg.get('HKCU\Control Panel\Desktop')
+
+ +
+
reg.set
+

Allows creating a subkey with the value name and value data

+

Syntax

+

Create Subkey

+
reg.set('HKCU\Software\Nilesoft\Shell')
+

Create Subkey with value and set value data type.

+
reg.set('HKCU\Software\Nilesoft\Shell', "test-int", 1, reg.dword)
+reg.set('HKCU\Software\Nilesoft\Shell', "test-str", 1, reg.sz)
+reg.set('HKCU\Software\Nilesoft\Shell', "test-str", 'some string', reg.sz)
+ +

Set value data with auto type detection.


+reg.set('HKCU\Software\Nilesoft\Shell', 'test-auto-int', 1)
+reg.set('HKCU\Software\Nilesoft\Shell', 'test-auto-str', 'some string')
+
+ +
+
reg.delete
+

Allows deleting a subkey or deleting a value

+

Syntax

+

Delete value name.

+
reg.delete('HKCU\Software\Nilesoft\Shell', 'test-auto')
+

Delete subkey.

+
reg.delete('HKCU\Software\Nilesoft\Shell')
+
+ +
+
reg.keys
+

Returns all subkey names

+

Syntax

+
reg.keys('HKCU\Software\Nilesoft\Shell')
+
+
+
reg.values
+

Returns all value names

+

Syntax

+
reg.values('HKCU\Software\Nilesoft\Shell')
+
diff --git a/docs/functions/regex.html b/docs/functions/regex.html new file mode 100644 index 0000000..7fdd0dc --- /dev/null +++ b/docs/functions/regex.html @@ -0,0 +1,20 @@ +
REGEX
+

regex functions

+
+
+
regex.match
+

Returns true if a match exists, false otherwise.

+

Syntax

+
regex.match(str, pattern)
+
+
+
regex.matches
+

Returns an array of strings

+

Syntax

+
regex.matches(str, pattern)
pre> +
+
+
regex.replace
+

Syntax

+
regex.replace(str, pattern, "new str")
+
diff --git a/docs/functions/sel.html b/docs/functions/sel.html new file mode 100644 index 0000000..1f51d2b --- /dev/null +++ b/docs/functions/sel.html @@ -0,0 +1,247 @@ +
SEL
+

Has many functions to handle selected file system objects.

+
+ +
+
sel
+

Returns all selected items with double quotation mark and custom separator.

+

Syntax

+ sel(quote=false, separator=' ') +

Parameters

+
+
quote
+
Sets if the return value shall be quoted.
+
separator
+
Separator to join the different items from the selection.
+
+

Example

+
sel
+sel(true)
+sel(true, "\n")
+
+ +
+
sel.path
+

Returns the path of the selected item..

+
+ +
+
sel.path.name
+

Returns the name without the extension of the selected item.

+
+ +
+
sel.path.length
+

Returns the number of characters in the path of the selected item.

+
+ +
+
sel.path.title
+

Returns the path title of the selected item.

+
+ +
+
sel.path.quote
+

Returns the path of the selected item. with double quotation mark.

+
+ +
+
sel.short
+

Returns the short path of the selected item.

+
+ +
+
sel.short.length
+

Returns the number of characters in the short path of the selected item.

+
+ +
+
sel.raw
+

Returns the path of the selected item in raw format.

+
+ +
+
sel.raw.length
+

Returns the number of characters in the raw path of the selected item.

+
+ +
+
sel.root
+

Returns the root directory from the path of the selected items.

+
+ +
+
sel.name
+

Returns the name and extension of the selected item.

+
+ +
+
sel.name.length
+

Returns the number of characters in the name of the selected item.

+
+ +
+
sel.title
+

Returns the name without extension of the selected item.

+
+ +
+
sel.title.length
+

Returns the number of characters in the name without extension of the selected item.

+
+ +
+
sel.parent
+

Returns the directory path for the selected item.

+
+ +
+
sel.parent.quote
+

Returns the directory path for the selected item with quotation mark.

+
+ +
+
sel.parent.raw
+

Returns the directory path for the selected item in raw format.

+
+ +
+
sel.parent.name
+

Returns the name of the parent of the selected item.

+
+ +
+
sel.parent.length
+

Returns the number of characters in the parent path of the selected item.

+
+ +
+
sel.count
+

Returns count selected items.

+
+ +
+
sel.back
+

Returns whether the selection is in the background.

+
+ +
+
sel.curdir or sel.workdir
+

Returns the path of current working directory.

+
+ +
+
sel.file
+

Returns the path for the selected item. If it is a file

+
+ +
+
sel.file.name
+

Returns the name for the selected item. If it is a file.

+
+ +
+
sel.file.name.length
+

Returns the number of characters in the name of the selected item. If it is a file.

+
+ +
+
sel.file.ext
+

Returns the extension for the selected item. If it is a file.

+
+ +
+
sel.file.title
+

Returns the name without an extension for the selected item. If it is a file.

+
+ +
+
sel.file.quote
+

Returns the path for the selected item with quotation mark. If it is a file.

+
+ +
+
sel.directory
+

Returns the path for the selected item. If it is a directory.

+
+ +
+
sel.directory.name
+

Returns the name for the selected item. If it is a directory.

+
+ +
+
sel.directory.length
+

Returns the number of characters in the path of the selected item. If it is a directory.

+
+ +
+
sel.directory.quote
+

Returns the path for the selected item with quotation mark. If it is a directory.

+
+ +
+
sel.get
+

Returns the path of the selected item by referring to the index number.

+

Syntax

+ sel.get(index=0) +
+ +
+
sel.path.raw
+

Returns the raw path of the selected item by referring to the index number.

+

Syntax

+ sel.path.raw(index=0) +
+ +
+
sel.length
+

Returns the number of characters in the path of the selected item by referring to the index number.

+

Syntax

+ sel.length(index=0) +
+ +
+
sel.readonly
+

Returns whether the selected item by referring to the index number is read-only.

+

Syntax

+ sel.readonly(index=0) +
+ +
+
sel.hidden
+

Returns whether the selected item by referring to the index number is hidden.

+

Syntax

+ sel.hidden(index=0) +
+ +
+
sel.meta
+

Gets meta data by property key.

+

Syntax

+ sel.meta("System.Size")) +
+
+
sel.lnk
+

Return the target file/dir path from the selected shortcut

+

Syntax

+ sel.lnk +
+
+
sel.lnk.type
+

Return type the shortcut

+

Syntax

+ sel.lnk.type +
+
+
sel.lnk.dir
+

Return a dir path from the shortcut

+

Syntax

+ sel.lnk.dir +
+
+
sel.lnk.icon
+

Return a icon path and index from the shortcut

+

Syntax

+ sel.lnk.icon +
diff --git a/docs/functions/str.html b/docs/functions/str.html new file mode 100644 index 0000000..76b14be --- /dev/null +++ b/docs/functions/str.html @@ -0,0 +1,214 @@ +
STR
+
+ +
+
str.get (str.at)
+

Returns a character from a specific location in the string.

+

Syntax

+ str.get("Hello World!", 7) +
+ +
+
str.set
+

Sets a character with a specific location in the string.

+

Syntax

+ str.set("Hello World!", 6, '-') +
+ +
+
str.contains
+

Returns a value indicating whether a specified substring occurs within this string.

+

Syntax

+ str.contains("Hello World!", 'World') +
+ +
+
str.empty (str.null)
+

Tests whether the string contains characters.

+

Syntax

+ str.empty("") +
+ +
+
str.start
+

Checks whether the string starts with the specified prefix.

+

Syntax

+ str.start("Hello World!", "World!") +
+ +
+
str.end
+

Checks whether the string ends with the specified suffix.

+

Syntax

+ str.end("Hello World!", "World!") +
+ +
+
str.equals
+

Determines whether two String have the same value.

+

Syntax

+ str.equals("Hello World!", "Hello World!") +
+ +
+
str.not
+

Determine if two strings do not have the same value.

+

Syntax

+ str.not("Hello World!", "Hello-World!") +
+ +
+
str.length (str.len)
+

Gets the number of characters in the current string.

+

Syntax

+ str.length("Hello World!") +
+ +
+
str.trim
+

Returns a new string in which all leading and trailing occurrences of a set of specified characters from the current string are removed.

+

Syntax

+

Removes all leading and trailing white-space characters from the current string.

+ str.trim(" Hello World! ")

+

Removes all leading and trailing 'H!' characters from the current string.

+ str.trim("Hello World!", "H!") +
+ +
+
str.trimstart
+

Returns a new string in which all leading occurrences of a set of specified characters from the current string are removed.

+

Syntax

+

Removes all leading white-space characters from the current string.

+ str.trimstart(" Hello World!")
+ +

Removes all leading 'H' characters from the current string.

+ str.trimstart("Hello World!", "H") +
+ +
+
str.trimend
+

Returns a new string in which all trailing occurrences of a set of specified characters from the current string are removed.

+

Syntax

+

Removes all trailing white-space characters from the current string.

+ str.trimend("Hello World! ")
+ +

Removes all trailing '!' characters from the current string.

+ str.trimend("Hello World!", "!") +
+ +
+
str.find
+

Searches a string in a forward direction for the first occurrence of a substring that matches a specified sequence of characters.

+

Syntax

+ str.find("Hello World!", "lo") +
+ +
+
str.findlast
+

Searches a string in a backward direction for the first occurrence of a substring that matches a specified sequence of characters.

+

Syntax

+ str.findlast("Hello World!", "Wor") +
+ +
+
str.lower
+

Returns a copy of this string converted to lowercase.

+

Syntax

+ str.lower("Hello World!") +
+ +
+
str.upper
+

Returns a copy of this string converted to uppercase.

+

Syntax

+ str.upper("Hello World!") +
+ +
+
str.left
+

Extracts the left part of a string.

+

Syntax

+ str.left("Hello World!", 5) +
+ +
+
str.right
+

Extracts the right part of a string.

+

Syntax

+ str.right("Hello World!", 5) +
+ +
+
str.sub
+

Copies a substring of at most some number of characters from a string beginning from a specified position.

+

Syntax

+ str.sub("Hello World!", 5)
+ str.sub("Hello World!", 0, 5) +
+ +
+
str.remove
+

Removes an element or a range of elements in a string from a specified position.

+

Syntax

+ str.replace("Hello World!", " ")
+ str.remove("Hello World!", 5)
+ str.remove("Hello World!", 5, 1) +
+ +
+
str.replace
+

Replace elements in a string at a specified position with specific characters or characters copied from other ranges or strings.

+

Syntax

+ str.replace("Hello World!", "World", "User")
+ str.replace("Hello World!", "world", "user", true) +
+ +
+
str.padleft
+

Returns a new string of a specified length in which the beginning of the current string is padded with spaces or with a specified character.

+

Syntax

+ str.padleft("Hello World!", "*")
+ str.padleft("Hello World!", "*", 3) +
+ +
+
str.padright
+

Returns a new string of a specified length in which the end of the current string is padded with spaces or with a specified character.

+

Syntax

+ str.padright("Hello World!", "*")
+ str.padright("Hello World!", "*", 3) +
+ +
+
str.padding
+

Returns a new string of a specified length in which the start and end of the current string is padded with spaces or with a specified character.

+

Syntax

+ str.padding("Hello World!", "*")
+ str.padding("Hello World!", "*", 3) +
+ +
+
str.guid
+

Returns a new guid string

+

Syntax

+ str.guid return 00000000000000000000000000000000
+ str.guid(1) return 00000000-0000-0000-0000-000000000000
+ str.guid(2) return {00000000-0000-0000-0000-000000000000}
+ str.guid(3) return (00000000-0000-0000-0000-000000000000)
+
+ +
+
str.capitalize
+

Returns a new capitalize string

+

Syntax

+ str.capitalize('hello world') return "Hello World"
+
+ +
+
str.res
+

Returns a string resource from the executable file. "shell32.dll" is the default file.

+

Syntax

+ str.res(-4640) return "Runs the selected command with elevation" from "shell32.dll"
+ str.res('explorer.dll', -22000) return "Desktop"
+
+ diff --git a/docs/functions/sys.html b/docs/functions/sys.html new file mode 100644 index 0000000..d3529f4 --- /dev/null +++ b/docs/functions/sys.html @@ -0,0 +1,166 @@ +
SYS (SYSTEM)
+ +
+
sys.name
+

Returns Windows name.

+

Syntax

+ sys.name +
+ +
+
sys.type
+

Returns system architecture.

+

Syntax

+ sys.type == 64
+ sys.type == 32 +
+ +
+
sys.is64
+

Returns if system architecture is x64.

+

Syntax

+ sys.is64 +
+ +
+
sys.dark
+

Check if dark mode is enabled.

+

Syntax

+ sys.dark +
+ +
+
sys.var
+

Retrieves the value of an environment variable.

+

Syntax

+ sys.var('WINDIR') +
+ +
+
sys.version (sys.ver)
+

Windows version.

+

Syntax

+
sys.version
+sys.version.build
+sys.version.major
+sys.version.minor
+sys.version.name
+sys.version.type
+
+ +
+
sys.datetime (system.datetime)
+

Date and time format

+

Syntax

+
sys.datetime                                   // the date and time in a short format (Format: YYYY.MM.DD-HH.MM.SS).
+sys.datetime.short                             // the date and time in a short format (Format: YYYY.MM.DD-HH.MM.SS).
+sys.datetime.dayofweek (sys.datetime.dw)       // the day of the week as a number (Sunday as 1)
+
+sys.datetime.date                              // the full date in a long format (Format: YYYY.MM.DD).
+sys.datetime.yy                                // the year part of the current date as a two-digit number.
+sys.datetime.year (sys.datetime.y)             // the year part of the current date as a four-digit number.
+sys.datetime.month (sys.datetime.m)            // the month part of the current date.
+sys.datetime.day (sys.datetime.d)              // the day part of the current date.
+
+sys.datetime.time                              // the full time in hours, minutes, and seconds (Format: HH.MM.SS).
+sys.datetime.pm                                // "AM" or "PM" based on the current time.
+sys.datetime.hour (sys.datetime.h)             // the hour part of the current time (24-hour format).
+sys.datetime.minute (sys.datetime.min)         // the minutes part of the current time.
+sys.datetime.second (sys.datetime.s)           // the seconds part of the current time.
+sys.datetime.milliseconds (sys.datetime.ms)    // the milliseconds part of the current time as a three-digit number.
+
+sys.datetime("D")                              // the full date in a short format (Format: DD/MM/YYYY).
+sys.datetime("Y")                              // the year part of the current date as a four-digit number.
+sys.datetime("y")                              // the year part of the current date as a two-digit number.
+sys.datetime("m")                              // the month part of the current date as a two-digit number.
+sys.datetime("d")                              // the day part of the current date as a two-digit number.
+sys.datetime("P") (sys.datetime("p"))          // "AM" or "PM" based on the current time.
+sys.datetime("h")                              // the hour part of the current time as a two-digit number (12-hour format).
+sys.datetime("H")                              // the hour part of the current time as a two-digit number (24-hour format).
+sys.datetime("M")                              // the minute part of the current time as a two-digit number.
+sys.datetime("S")                              // the second part of the current time as a two-digit number.
+sys.datetime("s")                              // the milliseconds part of the current time as a three-digit number.
+
+datetime("y/m/d")                              // the date in a short format (Format: YYYY/MM/DD).
+datetime("h:M P")                              // the time in a short format (Format: HH:MM AM/PM).
+datetime("H.M.S.s")                            // the time in a long format (Format: HH.MM.SS.MS).
+
+ +
+
Windows paths
+
sys                                            // %WINDIR%
+
+sys.root                                       // %SYSTEMDRIVE%
+
+sys.programdata                                // %PROGRAMDATA%
+sys.prog                                       // %PROGRAMFILES%
+sys.prog32                                     // %PROGRAMFILES(x86)%
+sys.templates
+
+sys.users
+sys.appdata                                    // %APPDATA%
+sys.temp                                       // %TEMP%
+
+sys.directory (sys.dir)                        // %WINDIR%
+sys.path                                       // %WINDIR%
+sys.bin                                        // %WINDIR%\system32
+sys.bin32
+sys.bin64
+sys.wow
+
+ +
+
sys.is_primary_monitor
+

Returns true if the current monitor is the primary

+

Syntax

+ sys.is_primary_monitor
+
+ +
+
sys.langid
+

Returns the language ID

+

Syntax

+ sys.langid
+
+ +
+
sys.extended
+

Returns whether the Shift key is currently pressed

+

Syntax

+ sys.extended
+
+ +
+
sys.is11
+

Returns whether the Windows version is 11

+

Syntax

+ sys.is11
+
+ +
+
sys.is10
+

Returns whether the Windows version is 10

+

Syntax

+ sys.is10
+
+ +
+
sys.is81
+

Returns whether the Windows version is 8.1

+

Syntax

+ sys.is81
+
+ +
+
sys.is8
+

Returns whether the Windows version is 8

+

Syntax

+ sys.is8
+
+ +
+
sys.is7
+

Returns whether the Windows version is 7

+

Syntax

+ sys.is7
+
\ No newline at end of file diff --git a/docs/functions/this.html b/docs/functions/this.html new file mode 100644 index 0000000..5ede648 --- /dev/null +++ b/docs/functions/this.html @@ -0,0 +1,18 @@ +
THIS
+
+

This namespace contains functions that are used with the current item in the context menu.

+
+
+
Syntax
+

+this.type	// Returns the type of the current item [item = 0, menu = 1, separator = 2]
+this.checked	// Returns true if the current item is checked
+this.pos	// Returns the position of the current item in the context menu
+this.disabled	// Returns true if the current item is disabled
+this.sys	// Returns true if the current item is a system item
+this.title	// Returns the title of the current item
+this.id		// Returns the ID of the current item
+this.count	// Returns the number of items in the context menu
+this.length	// Returns the length of the current item's title
+
+
diff --git a/docs/functions/user.html b/docs/functions/user.html new file mode 100644 index 0000000..dbedc7c --- /dev/null +++ b/docs/functions/user.html @@ -0,0 +1,36 @@ +
USER
+
+
+
user.name
+

Returns the current username.

+

Syntax

+ user.name +
+ +
+
Functions to return the path of user directories
+

Syntax

+
user.home
+user.appdata
+user.contacts
+user.desktop
+user.directory (user.dir)
+user.documents
+user.documentslibrary
+user.downloads
+user.favorites
+user.libraries
+user.localappdata
+user.music
+user.personal
+user.pictures
+user.profile
+user.quicklaunch
+user.sendto
+user.startmenu
+user.temp
+user.templates
+user.videos
+
+
+ diff --git a/docs/functions/window.html b/docs/functions/window.html new file mode 100644 index 0000000..d9776ce --- /dev/null +++ b/docs/functions/window.html @@ -0,0 +1,34 @@ +
WINDOW, WND
+
+

+
+
+
Syntax
+

+window.is_taskbar	// Returns true if the window handle is for the Taskbar window
+window.is_desktop	// Returns true if the window handle is for the Desktop window
+window.is_explorer	// Returns true if the window handle is for the Explorer window
+window.is_tree		// Returns true if the window handle is for the Side window
+window.is_edit		// Returns true if the window handle is for the Edit menu
+window.is_start		// Returns true if the window handle is for the Win+X menu
+
+window.send(name, msg, wparam, lparam)	// Search for the window by name and send the specified message
+window.post(name, msg, wparam, lparam)	// Search for the window by name and send the specified message without waiting
+
+window.send(null, msg, wparam, lparam)	// Send the specified message to current window.
+window.post(null, msg, wparam, lparam)	// Send the specified message without waiting to current window.
+
+window.command(command)	// Send WM_COMMAND to current window.
+window.command(command, name)	// Search for the window by name and send the command to it.
+
+window.handle
+window.name
+window.title
+window.owner
+window.parent
+window.parent.handle
+window.parent.name
+window.is_contextmenuhandler
+						
+
+
\ No newline at end of file diff --git a/docs/get-started.html b/docs/get-started.html new file mode 100644 index 0000000..7de9bfe --- /dev/null +++ b/docs/get-started.html @@ -0,0 +1,33 @@ +

Get Started

+
+

+ This tutorial will teach you the basics of Shell.
+ It is not necessary to have any prior experience. +

+

+ To start using Shell, you need:
+ A text editor, like Notepad, to write Shell code. +

+
Quickstart
+

Let's create our first menu item.

+

Open the configuration file "shell.nss" and Write the following code and save.

+ +
+
item(title='Hello, World!' cmd=msg('Hello @user.name'))
+
+

Don't worry if you don't understand the code above - we will discuss it in detail in later chapters.

+ +

The result will look something for this when you press the right-click in an empty place on the desktop:

+
+ +
+

Congratulations You have now added the first time a menu item to the context menu

diff --git a/docs/images/config.png b/docs/images/config.png new file mode 100644 index 0000000..8dcac98 Binary files /dev/null and b/docs/images/config.png differ diff --git a/docs/images/copypath1.png b/docs/images/copypath1.png new file mode 100644 index 0000000..5411955 Binary files /dev/null and b/docs/images/copypath1.png differ diff --git a/docs/images/copypath2.png b/docs/images/copypath2.png new file mode 100644 index 0000000..7adf0c0 Binary files /dev/null and b/docs/images/copypath2.png differ diff --git a/docs/images/copypath3.png b/docs/images/copypath3.png new file mode 100644 index 0000000..f286620 Binary files /dev/null and b/docs/images/copypath3.png differ diff --git a/docs/images/dark/goto.png b/docs/images/dark/goto.png new file mode 100644 index 0000000..7b14d07 Binary files /dev/null and b/docs/images/dark/goto.png differ diff --git a/docs/images/fav1.png b/docs/images/fav1.png new file mode 100644 index 0000000..6b81f47 Binary files /dev/null and b/docs/images/fav1.png differ diff --git a/docs/images/fav2.png b/docs/images/fav2.png new file mode 100644 index 0000000..a30bb4f Binary files /dev/null and b/docs/images/fav2.png differ diff --git a/docs/images/fav3.png b/docs/images/fav3.png new file mode 100644 index 0000000..b033dc2 Binary files /dev/null and b/docs/images/fav3.png differ diff --git a/docs/images/goto.png b/docs/images/goto.png new file mode 100644 index 0000000..7b14d07 Binary files /dev/null and b/docs/images/goto.png differ diff --git a/docs/images/helloworld.png b/docs/images/helloworld.png new file mode 100644 index 0000000..ae668b0 Binary files /dev/null and b/docs/images/helloworld.png differ diff --git a/docs/images/light/goto.png b/docs/images/light/goto.png new file mode 100644 index 0000000..7b14d07 Binary files /dev/null and b/docs/images/light/goto.png differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..24ba172 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,26 @@ +

Introduction

+
+
What is Shell?
+

+ Shell is an extension of Windows File Explorer that can be used to create high-performance context menu items. + And gives user a high level of control over context menu of Windows File Explorer. +

+

The Right Click Menu or the Context Menu is the menu, which appears when you right-click on the desktop, file, folder or taskbar in Windows. This menu gives you added functionality by offering you actions you can take with the item.

+

Shell is all you need to customize or add new items with several functions to Windows File Explorer Context menu and Much More.(cascade menus, advanced menus, multi-level menus, command menus, separator).

+
+ +
+
Why Use Shell
+ diff --git a/docs/installation.html b/docs/installation.html new file mode 100644 index 0000000..ba4e93f --- /dev/null +++ b/docs/installation.html @@ -0,0 +1,218 @@ +

Installation

+
+ +
+

Shell can be installed in the following ways:

+
+

Please also note the following reference sections:

+ +
+
+
Installer version
+
+
Install
+

Download the installation file (Installer/Portable), + run setup.exe, follow the installation steps, and agree to restart Windows File Explorer.

+

The program will be installed to C:\Program Files\Nilesoft Shell\, unless you have chosen + a different installation path during the installation steps.

+
+
+
+
Uninstall
+

Inside the Shell program folder (C:\Program Files\Nilesoft Shell\ by default), run the unst000.exe + or unstall.exe file, then follow the steps, and then agree to restart Windows File Explorer. +

+
+
+
+
+
Portable version
+
+
Install
+

Download the + installation file (Installer/Portable), + run setup.exe, + click Next, chose the folder you want the program to be extracted + to, Check the option Portable Mode, and click + Extract.

+

Open an elevated command prompt (or use gsudo), change to the directory you have extracted the program to, and run

+
+
Administrator: Command Prompt
+
shell -register -restart
+
+

For further details, see the chapter Command-Line Help below.

+
+
+
+
Uninstall
+

Open an elevated command prompt (or use gsudo), change to the directory you have extracted the program to, and run

+
+
Administrator: Command Prompt
+
shell -unregister -restart
+
+
+
+ Tip: Close all instances of Windows File Explorer before uninstalling to avoid needing a reboot after + it (Shell) has been uninstalled. +
+
+

For further details see the chapter Command-Line Help below.

+
+
+
+
+
Windows Package Manager
+

Windows Package Manager is available from Windows 10 version 1809.

+
+
Install
+

Open a command prompt, and run

+
+
COMMAND PROMPT
+
winget install Nilesoft.Shell
+
+

The program will be installed to C:\Program Files\Nilesoft Shell\.

+
+
+
+
Uninstall
+

Open a command prompt, and run

+
+
COMMAND PROMPT
+
winget uninstall Nilesoft.Shell
+
+
+
+
+
+
Scoop
+

Scoop can be installed following the instructions at scoop.sh.

+
+
Install
+

Open a command prompt, and run

+
+
COMMAND PROMPT
+
scoop install nilesoft-shell
+
+

The program will be installed to %USERPROFILE%\scoop\apps\nilesoft-shell\current\.

+
+ Tip: If you get the error Couldn't find manifest for 'nilesoft-shell', please run first +
+
COMMAND PROMPT
+
scoop bucket add extras
+
+
+

Open an elevated command prompt (or use gsudo), and run

+
+
Administrator: Command Prompt
+
shell -register -restart
+
+

For further details see the chapter Command-Line Help below.

+
+
+
+
Uninstall
+

Open an elevated command prompt (or use gsudo), and run

+
+
Administrator: Command Prompt
+
shell -unregister -restart
+
+

Then run

+
+
Administrator: Command Prompt
+
scoop uninstall nilesoft-shell
+
+
+
+
+
+
Chocolatey
+

Chocolatey can be installed following the instructions at chocolatey.org.

+
+
Install
+
+ Notice: Until the package has been moderated, you need to add the specific version string to the + installer, adding e.g.
+
+
COMMAND PROMPT
+
+ choco install nilesoft.shell --version=1.8.1 +
+
+ Please find the latest published version at + Chocolatey's Version History and use the latest version number (replacing 1.8.1). +
+
+

Open an elevated command prompt (or use gsudo), and run

+
+
COMMAND PROMPT
+
+ choco install nilesoft.shell +
+
+

The program will be installed to C:\Program Files\Nilesoft Shell\.

+
+
+
+
Uninstall
+

Open an elevated command prompt (or use gsudo), and run

+
+
COMMAND PROMPT
+
choco uninstall nilesoft.shell
+
+
+
+ +
+ +
+
Command-Line Help

+ shell -[options] +

+
Options
+ + + + + + + + + + + + + + + + + + + + + + + + + +
-register (-r)Registering.
-unregister (-u)Unregistering.
-restart (-re)Restart Windows Explorer.
-treatDisable Windows 11 context menu.
-silent (-s)Prevents displaying messages.
-?Display this help message.
+
+
+
+
Use the following keys to enable/disable
+

These keys are used when you press right-click or press Shift+F10 keys

+ CTRL To enable and reload the configuration file shell.nss
+ WIN To make priority to the modern context menu for Windows 11
+ CTRL+WIN To disable Shell and Enable Classic Context Menu
+ RIGHT-CLICK+LEFT-CLICK To reload the configuration file shell.nss
+
diff --git a/docs/menu.json b/docs/menu.json new file mode 100644 index 0000000..f9b10e1 --- /dev/null +++ b/docs/menu.json @@ -0,0 +1,59 @@ +[ + {"title":"Introduction", "link":"/docs"}, + {"title":"Installation", "link":"/docs/installation"}, + {"title":"Get Started", "link":"/docs/get-started"}, + { + "title":"Configuration", "link":"/docs/configuration", + "items": [ + {"title":"Settings", "link":"/docs/configuration/settings"}, + {"title":"Themes", "link":"/docs/configuration/themes"}, + {"title":"Modify items", "link":"/docs/configuration/modify-items"}, + {"title":"New items", "link":"/docs/configuration/new-items"}, + {"title":"Properties", "link":"/docs/configuration/properties" } + ] + },{ + "title":"Expressions", "link":"/docs/expressions", + "items": [ + {"title":"Comments", "link":"/docs/expressions/comments"}, + {"title":"Variables", "link":"/docs/expressions/variables"}, + {"title":"String literal", "link":"/docs/expressions/string"}, + {"title":"Numeric literal", "link":"/docs/expressions/numeric"}, + {"title":"Color literal", "link":"/docs/expressions/color"}, + {"title":"Operators", "link":"/docs/expressions/operators"}, + {"title":"Identifier", "link":"/docs/expressions/identifier"} + ] + },{ + "title":"Functions", "link":"/docs/functions", + "items": [ + {"title":"app", "link":"/docs/functions/app"}, + {"title":"appx", "link":"/docs/functions/appx"}, + {"title":"color", "link":"/docs/functions/color"}, + {"title":"command", "link":"/docs/functions/command"}, + {"title":"id", "link":"/docs/functions/id"}, + {"title":"image", "link":"/docs/functions/image"}, + {"title":"io", "link":"/docs/functions/io"}, + {"title":"key", "link":"/docs/functions/key"}, + {"title":"msg", "link":"/docs/functions/msg"}, + {"title":"path", "link":"/docs/functions/path"}, + {"title":"process", "link":"/docs/functions/process"}, + {"title":"reg", "link":"/docs/functions/reg"}, + {"title":"sel", "link":"/docs/functions/sel"}, + {"title":"str", "link":"/docs/functions/str"}, + {"title":"sys", "link":"/docs/functions/sys"}, + {"title":"this", "link":"/docs/functions/this"}, + {"title":"user", "link":"/docs/functions/user"}, + {"title":"window", "link":"/docs/functions/window"}, + {"title":"clipboard", "link":"/docs/functions/clipboard"}, + {"title":"input", "link":"/docs/functions/input"}, + {"title":"ini", "link":"/docs/functions/ini"}, + {"title":"regex", "link":"/docs/functions/regex"} + ] + },{ + "title":"Examples", "link":"/docs/examples", + "items": [ + {"title":"Copy path", "link":"/docs/examples/copy-path"}, + {"title":"Favorites", "link":"/docs/examples/favorites"}, + {"title":"Go to", "link":"/docs/examples/goto"} + ] + } +] \ No newline at end of file diff --git a/packages/assets/logo-128.png b/packages/assets/logo-128.png new file mode 100644 index 0000000..11e1412 Binary files /dev/null and b/packages/assets/logo-128.png differ diff --git a/packages/assets/logo-256.png b/packages/assets/logo-256.png new file mode 100644 index 0000000..287f039 Binary files /dev/null and b/packages/assets/logo-256.png differ diff --git a/packages/assets/logo-32.png b/packages/assets/logo-32.png new file mode 100644 index 0000000..884cd45 Binary files /dev/null and b/packages/assets/logo-32.png differ diff --git a/packages/assets/logo-512.png b/packages/assets/logo-512.png new file mode 100644 index 0000000..39814a6 Binary files /dev/null and b/packages/assets/logo-512.png differ diff --git a/packages/choco/nilesoft-shell.1.8.1.nupkg b/packages/choco/nilesoft-shell.1.8.1.nupkg new file mode 100644 index 0000000..6ecf9c8 Binary files /dev/null and b/packages/choco/nilesoft-shell.1.8.1.nupkg differ diff --git a/packages/choco/nilesoft-shell.1.9.10.nupkg b/packages/choco/nilesoft-shell.1.9.10.nupkg new file mode 100644 index 0000000..48babe1 Binary files /dev/null and b/packages/choco/nilesoft-shell.1.9.10.nupkg differ diff --git a/packages/choco/nilesoft-shell.1.9.15.nupkg b/packages/choco/nilesoft-shell.1.9.15.nupkg new file mode 100644 index 0000000..d928a73 Binary files /dev/null and b/packages/choco/nilesoft-shell.1.9.15.nupkg differ diff --git a/packages/choco/nilesoft-shell.1.9.nupkg b/packages/choco/nilesoft-shell.1.9.nupkg new file mode 100644 index 0000000..d168f54 Binary files /dev/null and b/packages/choco/nilesoft-shell.1.9.nupkg differ diff --git a/packages/choco/nilesoft-shell.nuspec b/packages/choco/nilesoft-shell.nuspec new file mode 100644 index 0000000..2e4fdb0 --- /dev/null +++ b/packages/choco/nilesoft-shell.nuspec @@ -0,0 +1,23 @@ + + + + nilesoft-shell + 1.9 + Nilesoft Shell + Mahmoud Gomaa + Mahmoud Gomaa + https://nilesoft.org + https://cdn.jsdelivr.net/gh/moudey/Shell@main/packages/assets/logo-256.png + 2023 Nilesoft Ltd. + https://raw.githubusercontent.com/moudey/Shell/main/LICENSE + https://github.com/moudey/Shell/tree/main/packages/choco + https://nilesoft.org/docs + context-menu right-click file-explorer shell-extension + Powerful context menu manager for Windows File Explorer. + Shell is a context menu extender that lets you handpick the items to integrate into Windows File Explorer context menu, create custom commands to access all your favorite web pages, files, and folders, and launch any application directly from the context menu. It also provides you a convenient solution to modify or remove any context menu item added by the system or third party software. + Changes in the configuration file structure, making it more flexible, improving performance, fixing some issues, and adding more helper functions make the Explorer more powerful. + + + + + diff --git a/packages/choco/tools/chocolateyinstall.ps1 b/packages/choco/tools/chocolateyinstall.ps1 new file mode 100644 index 0000000..be70e7f --- /dev/null +++ b/packages/choco/tools/chocolateyinstall.ps1 @@ -0,0 +1,13 @@ +$ErrorActionPreference = 'Stop' # stop on all errors +$url = 'https://nilesoft.org/download/shell/1.9/setup.exe' +$packageArgs = @{ + packageName = $env:ChocolateyPackageName + fileType = 'exe' + url = $url + softwareName = 'Nilesoft Shell' + checksum = '4df2b30fc6b9d6d7c95c7e5070fbeb305c7d1b30ef3c135bb9e2838c10114fb6' + checksumType = 'sha256' + silentArgs = '/VERYSILENT /NORESTART' # Inno Setup + validExitCodes= @(0) +} +Install-ChocolateyPackage @packageArgs \ No newline at end of file diff --git a/packages/choco/tools/chocolateyuninstall.ps1 b/packages/choco/tools/chocolateyuninstall.ps1 new file mode 100644 index 0000000..45faf92 --- /dev/null +++ b/packages/choco/tools/chocolateyuninstall.ps1 @@ -0,0 +1,24 @@ +$ErrorActionPreference = 'Stop' # stop on all errors +$packageArgs = @{ + packageName = $env:ChocolateyPackageName + softwareName = 'Nilesoft Shell' + fileType = 'exe' + silentArgs = '/VERYSILENT /NORESTART' # Inno Setup + validExitCodes= @(0) +} + +[array]$key = Get-UninstallRegistryKey -SoftwareName $packageArgs['softwareName'] + +if ($key.Count -eq 1) { + $key | % { + $packageArgs['file'] = "$($_.UninstallString)" + Uninstall-ChocolateyPackage @packageArgs + } +} elseif ($key.Count -eq 0) { + Write-Warning "$packageName has already been uninstalled by other means." +} elseif ($key.Count -gt 1) { + Write-Warning "$($key.Count) matches found!" + Write-Warning "To prevent accidental data loss, no programs will be uninstalled." + Write-Warning "Please alert package maintainer the following keys were matched:" + $key | % {Write-Warning "- $($_.DisplayName)"} +} diff --git a/screenshots/acrylic.png b/screenshots/acrylic.png new file mode 100644 index 0000000..4351a96 Binary files /dev/null and b/screenshots/acrylic.png differ diff --git a/screenshots/edit.png b/screenshots/edit.png new file mode 100644 index 0000000..c788bc3 Binary files /dev/null and b/screenshots/edit.png differ diff --git a/screenshots/file-manage.png b/screenshots/file-manage.png new file mode 100644 index 0000000..127a14e Binary files /dev/null and b/screenshots/file-manage.png differ diff --git a/screenshots/folder-back.png b/screenshots/folder-back.png new file mode 100644 index 0000000..b53534c Binary files /dev/null and b/screenshots/folder-back.png differ diff --git a/screenshots/goto2.png b/screenshots/goto2.png new file mode 100644 index 0000000..7b14d07 Binary files /dev/null and b/screenshots/goto2.png differ diff --git a/screenshots/gradient.png b/screenshots/gradient.png new file mode 100644 index 0000000..6bd5cf4 Binary files /dev/null and b/screenshots/gradient.png differ diff --git a/screenshots/sel.png b/screenshots/sel.png new file mode 100644 index 0000000..03b4f86 Binary files /dev/null and b/screenshots/sel.png differ diff --git a/screenshots/taskbar.png b/screenshots/taskbar.png new file mode 100644 index 0000000..9615c62 Binary files /dev/null and b/screenshots/taskbar.png differ diff --git a/screenshots/terminal.png b/screenshots/terminal.png new file mode 100644 index 0000000..e77b0f8 Binary files /dev/null and b/screenshots/terminal.png differ diff --git a/screenshots/view.png b/screenshots/view.png new file mode 100644 index 0000000..26ab4fd Binary files /dev/null and b/screenshots/view.png differ diff --git a/src/3rdparty/detours/Makefile b/src/3rdparty/detours/Makefile new file mode 100644 index 0000000..a0718ae --- /dev/null +++ b/src/3rdparty/detours/Makefile @@ -0,0 +1,30 @@ +############################################################################## +## +## Makefile for Detours. +## +## Microsoft Research Detours Package +## +## Copyright (c) Microsoft Corporation. All rights reserved. +## + +ROOT = . +!include "$(ROOT)\system.mak" + +all: + cd "$(MAKEDIR)\src" + @$(MAKE) /NOLOGO /$(MAKEFLAGS) + +clean: + cd "$(MAKEDIR)\src" + @$(MAKE) /NOLOGO /$(MAKEFLAGS) clean + +realclean: clean + cd "$(MAKEDIR)\src" + @$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean + + -rmdir /q /s $(BINDS) 2> nul + -rmdir /q /s dist 2> nul + + -del /q /f /s *~ 2>nul + +################################################################# End of File. diff --git a/src/3rdparty/detours/src/Makefile b/src/3rdparty/detours/src/Makefile new file mode 100644 index 0000000..0b43b59 --- /dev/null +++ b/src/3rdparty/detours/src/Makefile @@ -0,0 +1,74 @@ +############################################################################## +## +## Makefile for Detours. +## +## Microsoft Research Detours Package, Version 4.0.1 +## +## Copyright (c) Microsoft Corporation. All rights reserved. +## + +#DETOURS_DEBUG="debug" + +DETOURS_NAME=detours-$(DETOURS_TARGET_PROCESSOR)$(DETOURS_CONFIG) +ROOT = .. +!include "$(ROOT)\system.mak" + +#######################/####################################################### +## +CFLAGS=/nologo /W4 /WX /we4777 /we4800 /Zi /MT /Gy /Gm- /Zl /Od /DDETOUR_DEBUG=$(DETOURS_DEBUG) + +CFLAGS=$(CFLAGS) /DWIN32_LEAN_AND_MEAN /D_WIN32_WINNT=0x0601 $(DETOURS_DEFINITION) + +!if defined(DETOURS_ANALYZE) +CFLAGS=$(CFLAGS) /analyze +!endif + +OBJS = \ + $(OBJD)\detours.obj \ + $(OBJD)\disasm.obj \ + +############################################################################## +## +.SUFFIXES: .cpp .h .obj + +!ifdef DETOURS_ANALYZE +.cpp{$(OBJD)}.obj: + $(CC) $(CFLAGS) /Fd$(BIND)\$(DETOURS_NAME).pdb /Fo$(OBJD)\ /c $< +!else +.cpp{$(OBJD)}.obj:: + $(CC) $(CFLAGS) /Fd$(BIND)\$(DETOURS_NAME).pdb /Fo$(OBJD)\ /c $< +!endif + +############################################################################## + +all: dirs \ + $(BIND)\$(DETOURS_NAME).lib \ + $(BIND)\detours.h \ + +############################################################################## + +clean: + -del *~ 2>nul + -del $(BIND)\$(DETOURS_NAME).pdb $(BIND)\$(DETOURS_NAME).pdb 2>nul + -rmdir /q /s $(OBJD) 2>nul + +realclean: clean + -rmdir /q /s $(OBJDS) 2>nul + +############################################################################## + +dirs: + @if not exist "$(BIND)" mkdir "$(BIND)" && echo. Created $(BIND) + @if not exist "$(OBJD)" mkdir "$(OBJD)" && echo. Created $(OBJD) + +$(BIND)\$(DETOURS_NAME).lib : $(OBJS) + link /lib /MACHINE:$(DETOURS_TARGET_PROCESSOR) /out:$@ /nologo $(OBJS) + +$(BIND)\detours.h : detours.h + copy detours.h $@ + +$(OBJD)\detours.obj : detours.cpp detours.h +$(OBJD)\disasm.obj : disasm.cpp detours.h + + +################################################################# End of File. diff --git a/src/3rdparty/detours/src/detours.cpp b/src/3rdparty/detours/src/detours.cpp new file mode 100644 index 0000000..25cd3a4 --- /dev/null +++ b/src/3rdparty/detours/src/detours.cpp @@ -0,0 +1,2388 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Core Detours Functionality (detours.cpp of detours.lib) +// +// Microsoft Research Detours Package, Version 4.0.1 +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// + + +//#define DETOUR_DEBUG 1 +#define DETOURS_INTERNAL +#include "detours.h" + +#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH +#error detours.h version mismatch +#endif + +#define NOTHROW + +////////////////////////////////////////////////////////////////////////////// +// +struct _DETOUR_ALIGN +{ + BYTE obTarget : 3; + BYTE obTrampoline : 5; +}; + +C_ASSERT(sizeof(_DETOUR_ALIGN) == 1); + +////////////////////////////////////////////////////////////////////////////// +// +// Region reserved for system DLLs, which cannot be used for trampolines. +// +static PVOID s_pSystemRegionLowerBound = (PVOID)(ULONG_PTR)0x70000000; +static PVOID s_pSystemRegionUpperBound = (PVOID)(ULONG_PTR)0x80000000; + +////////////////////////////////////////////////////////////////////////////// +// +static bool detour_is_imported(PBYTE pbCode, PBYTE pbAddress) +{ + MEMORY_BASIC_INFORMATION mbi; + VirtualQuery((PVOID)pbCode, &mbi, sizeof(mbi)); + __try { + PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase; + if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { + return false; + } + + PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + + pDosHeader->e_lfanew); + if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { + return false; + } + + if (pbAddress >= ((PBYTE)pDosHeader + + pNtHeader->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress) && + pbAddress < ((PBYTE)pDosHeader + + pNtHeader->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress + + pNtHeader->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size)) { + return true; + } + } +#pragma prefast(suppress:28940, "A bad pointer means this probably isn't a PE header.") + __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { + return false; + } + return false; +} + +inline ULONG_PTR detour_2gb_below(ULONG_PTR address) +{ + return (address > (ULONG_PTR)0x7ff80000) ? address - 0x7ff80000 : 0x80000; +} + +inline ULONG_PTR detour_2gb_above(ULONG_PTR address) +{ +#if defined(DETOURS_64BIT) + return (address < (ULONG_PTR)0xffffffff80000000) ? address + 0x7ff80000 : (ULONG_PTR)0xfffffffffff80000; +#else + return (address < (ULONG_PTR)0x80000000) ? address + 0x7ff80000 : (ULONG_PTR)0xfff80000; +#endif +} + +///////////////////////////////////////////////////////////////////////// X86. +// +#ifdef DETOURS_X86 + +struct _DETOUR_TRAMPOLINE +{ + BYTE rbCode[30]; // target code + jmp to pbRemain + BYTE cbCode; // size of moved target code. + BYTE cbCodeBreak; // padding to make debugging easier. + BYTE rbRestore[22]; // original target code. + BYTE cbRestore; // size of original target code. + BYTE cbRestoreBreak; // padding to make debugging easier. + _DETOUR_ALIGN rAlign[8]; // instruction alignment array. + PBYTE pbRemain; // first instruction after moved code. [free list] + PBYTE pbDetour; // first instruction of detour function. +}; + +C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 72); + +enum { + SIZE_OF_JMP = 5 +}; + +inline PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE pbJmpVal) +{ + PBYTE pbJmpSrc = pbCode + 5; + *pbCode++ = 0xE9; // jmp +imm32 + *((INT32*&)pbCode)++ = (INT32)(pbJmpVal - pbJmpSrc); + return pbCode; +} + +inline PBYTE detour_gen_jmp_indirect(PBYTE pbCode, PBYTE *ppbJmpVal) +{ + *pbCode++ = 0xff; // jmp [+imm32] + *pbCode++ = 0x25; + *((INT32*&)pbCode)++ = (INT32)((PBYTE)ppbJmpVal); + return pbCode; +} + +inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) +{ + while (pbCode < pbLimit) { + *pbCode++ = 0xcc; // brk; + } + return pbCode; +} + +inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) +{ + if (pbCode == NULL) { + return NULL; + } + if (ppGlobals != NULL) { + *ppGlobals = NULL; + } + + // First, skip over the import vector if there is one. + if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [imm32] + // Looks like an import alias jump, then get the code it points to. + PBYTE pbTarget = *(UNALIGNED PBYTE *)&pbCode[2]; + if (detour_is_imported(pbCode, pbTarget)) { + PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; + pbCode = pbNew; + } + } + + // Then, skip over a patch jump + if (pbCode[0] == 0xeb) { // jmp +imm8 + PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; + // DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); + pbCode = pbNew; + + // First, skip over the import vector if there is one. + if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [imm32] + // Looks like an import alias jump, then get the code it points to. + PBYTE pbTarget = *(UNALIGNED PBYTE *)&pbCode[2]; + if (detour_is_imported(pbCode, pbTarget)) { + pbNew = *(UNALIGNED PBYTE *)pbTarget; + pbCode = pbNew; + } + } + // Finally, skip over a long jump if it is the target of the patch jump. + else if (pbCode[0] == 0xe9) { // jmp +imm32 + pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; + pbCode = pbNew; + } + } + return pbCode; +} + +inline void detour_find_jmp_bounds(PBYTE pbCode, + PDETOUR_TRAMPOLINE *ppLower, + PDETOUR_TRAMPOLINE *ppUpper) +{ + // We have to place trampolines within +/- 2GB of code. + ULONG_PTR lo = detour_2gb_below((ULONG_PTR)pbCode); + ULONG_PTR hi = detour_2gb_above((ULONG_PTR)pbCode); + // DETOUR_TRACE(("[%p..%p..%p]\n", (PVOID)lo, pbCode, (PVOID)hi)); + + // And, within +/- 2GB of relative jmp targets. + if (pbCode[0] == 0xe9) { // jmp +imm32 + PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; + + if (pbNew < pbCode) { + hi = detour_2gb_above((ULONG_PTR)pbNew); + } + else { + lo = detour_2gb_below((ULONG_PTR)pbNew); + } + } + + *ppLower = (PDETOUR_TRAMPOLINE)lo; + *ppUpper = (PDETOUR_TRAMPOLINE)hi; +} + +inline BOOL detour_does_code_end_function(PBYTE pbCode) +{ + if (pbCode[0] == 0xeb || // jmp +imm8 + pbCode[0] == 0xe9 || // jmp +imm32 + pbCode[0] == 0xe0 || // jmp eax + pbCode[0] == 0xc2 || // ret +imm8 + pbCode[0] == 0xc3 || // ret + pbCode[0] == 0xcc) { // brk + return TRUE; + } + else if (pbCode[0] == 0xf3 && pbCode[1] == 0xc3) { // rep ret + return TRUE; + } + else if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] + return TRUE; + } + else if ((pbCode[0] == 0x26 || // jmp es: + pbCode[0] == 0x2e || // jmp cs: + pbCode[0] == 0x36 || // jmp ss: + pbCode[0] == 0x3e || // jmp ds: + pbCode[0] == 0x64 || // jmp fs: + pbCode[0] == 0x65) && // jmp gs: + pbCode[1] == 0xff && // jmp [+imm32] + pbCode[2] == 0x25) { + return TRUE; + } + return FALSE; +} + +inline ULONG detour_is_code_filler(PBYTE pbCode) +{ + // 1-byte through 11-byte NOPs. + if (pbCode[0] == 0x90) { + return 1; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x90) { + return 2; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x00) { + return 3; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x40 && + pbCode[3] == 0x00) { + return 4; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x44 && + pbCode[3] == 0x00 && pbCode[4] == 0x00) { + return 5; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && + pbCode[3] == 0x44 && pbCode[4] == 0x00 && pbCode[5] == 0x00) { + return 6; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x80 && + pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && + pbCode[6] == 0x00) { + return 7; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x84 && + pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && + pbCode[6] == 0x00 && pbCode[7] == 0x00) { + return 8; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && + pbCode[3] == 0x84 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && + pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00) { + return 9; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x0F && + pbCode[3] == 0x1F && pbCode[4] == 0x84 && pbCode[5] == 0x00 && + pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && + pbCode[9] == 0x00) { + return 10; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x66 && + pbCode[3] == 0x0F && pbCode[4] == 0x1F && pbCode[5] == 0x84 && + pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && + pbCode[9] == 0x00 && pbCode[10] == 0x00) { + return 11; + } + + // int 3. + if (pbCode[0] == 0xcc) { + return 1; + } + return 0; +} + +#endif // DETOURS_X86 + +///////////////////////////////////////////////////////////////////////// X64. +// +#ifdef DETOURS_X64 + +struct _DETOUR_TRAMPOLINE +{ + // An X64 instuction can be 15 bytes long. + // In practice 11 seems to be the limit. + BYTE rbCode[30]; // target code + jmp to pbRemain. + BYTE cbCode; // size of moved target code. + BYTE cbCodeBreak; // padding to make debugging easier. + BYTE rbRestore[30]; // original target code. + BYTE cbRestore; // size of original target code. + BYTE cbRestoreBreak; // padding to make debugging easier. + _DETOUR_ALIGN rAlign[8]; // instruction alignment array. + PBYTE pbRemain; // first instruction after moved code. [free list] + PBYTE pbDetour; // first instruction of detour function. + BYTE rbCodeIn[8]; // jmp [pbDetour] +}; + +C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 96); + +enum { + SIZE_OF_JMP = 5 +}; + +inline PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE pbJmpVal) +{ + PBYTE pbJmpSrc = pbCode + 5; + *pbCode++ = 0xE9; // jmp +imm32 + *((INT32*&)pbCode)++ = (INT32)(pbJmpVal - pbJmpSrc); + return pbCode; +} + +inline PBYTE detour_gen_jmp_indirect(PBYTE pbCode, PBYTE *ppbJmpVal) +{ + PBYTE pbJmpSrc = pbCode + 6; + *pbCode++ = 0xff; // jmp [+imm32] + *pbCode++ = 0x25; + *((INT32*&)pbCode)++ = (INT32)((PBYTE)ppbJmpVal - pbJmpSrc); + return pbCode; +} + +inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) +{ + while (pbCode < pbLimit) { + *pbCode++ = 0xcc; // brk; + } + return pbCode; +} + +inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) +{ + if (pbCode == NULL) { + return NULL; + } + if (ppGlobals != NULL) { + *ppGlobals = NULL; + } + + // First, skip over the import vector if there is one. + if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] + // Looks like an import alias jump, then get the code it points to. + PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; + if (detour_is_imported(pbCode, pbTarget)) { + PBYTE pbNew = *(UNALIGNED PBYTE *)pbTarget; + pbCode = pbNew; + } + } + + // Then, skip over a patch jump + if (pbCode[0] == 0xeb) { // jmp +imm8 + PBYTE pbNew = pbCode + 2 + *(CHAR *)&pbCode[1]; + //DETOUR_TRACE(("%p->%p: skipped over short jump.\n", pbCode, pbNew)); + pbCode = pbNew; + + // First, skip over the import vector if there is one. + if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] + // Looks like an import alias jump, then get the code it points to. + PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; + if (detour_is_imported(pbCode, pbTarget)) { + pbNew = *(UNALIGNED PBYTE *)pbTarget; + pbCode = pbNew; + } + } + // Finally, skip over a long jump if it is the target of the patch jump. + else if (pbCode[0] == 0xe9) { // jmp +imm32 + pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; + pbCode = pbNew; + } + } + return pbCode; +} + +inline void detour_find_jmp_bounds(PBYTE pbCode, + PDETOUR_TRAMPOLINE *ppLower, + PDETOUR_TRAMPOLINE *ppUpper) +{ + // We have to place trampolines within +/- 2GB of code. + ULONG_PTR lo = detour_2gb_below((ULONG_PTR)pbCode); + ULONG_PTR hi = detour_2gb_above((ULONG_PTR)pbCode); + + // And, within +/- 2GB of relative jmp vectors. + if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] + PBYTE pbNew = pbCode + 6 + *(UNALIGNED INT32 *)&pbCode[2]; + + if (pbNew < pbCode) { + hi = detour_2gb_above((ULONG_PTR)pbNew); + } + else { + lo = detour_2gb_below((ULONG_PTR)pbNew); + } + } + // And, within +/- 2GB of relative jmp targets. + else if (pbCode[0] == 0xe9) { // jmp +imm32 + PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32 *)&pbCode[1]; + + if (pbNew < pbCode) { + hi = detour_2gb_above((ULONG_PTR)pbNew); + } + else { + lo = detour_2gb_below((ULONG_PTR)pbNew); + } + } + + *ppLower = (PDETOUR_TRAMPOLINE)lo; + *ppUpper = (PDETOUR_TRAMPOLINE)hi; +} + +inline BOOL detour_does_code_end_function(PBYTE pbCode) +{ + if (pbCode[0] == 0xeb || // jmp +imm8 + pbCode[0] == 0xe9 || // jmp +imm32 + pbCode[0] == 0xe0 || // jmp eax + pbCode[0] == 0xc2 || // ret +imm8 + pbCode[0] == 0xc3 || // ret + pbCode[0] == 0xcc) { // brk + return TRUE; + } + else if (pbCode[0] == 0xf3 && pbCode[1] == 0xc3) { // rep ret + return TRUE; + } + else if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] + return TRUE; + } + else if ((pbCode[0] == 0x26 || // jmp es: + pbCode[0] == 0x2e || // jmp cs: + pbCode[0] == 0x36 || // jmp ss: + pbCode[0] == 0x3e || // jmp ds: + pbCode[0] == 0x64 || // jmp fs: + pbCode[0] == 0x65) && // jmp gs: + pbCode[1] == 0xff && // jmp [+imm32] + pbCode[2] == 0x25) { + return TRUE; + } + return FALSE; +} + +inline ULONG detour_is_code_filler(PBYTE pbCode) +{ + // 1-byte through 11-byte NOPs. + if (pbCode[0] == 0x90) { + return 1; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x90) { + return 2; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x00) { + return 3; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x40 && + pbCode[3] == 0x00) { + return 4; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x44 && + pbCode[3] == 0x00 && pbCode[4] == 0x00) { + return 5; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && + pbCode[3] == 0x44 && pbCode[4] == 0x00 && pbCode[5] == 0x00) { + return 6; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x80 && + pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && + pbCode[6] == 0x00) { + return 7; + } + if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x84 && + pbCode[3] == 0x00 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && + pbCode[6] == 0x00 && pbCode[7] == 0x00) { + return 8; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && + pbCode[3] == 0x84 && pbCode[4] == 0x00 && pbCode[5] == 0x00 && + pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00) { + return 9; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x0F && + pbCode[3] == 0x1F && pbCode[4] == 0x84 && pbCode[5] == 0x00 && + pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && + pbCode[9] == 0x00) { + return 10; + } + if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x66 && + pbCode[3] == 0x0F && pbCode[4] == 0x1F && pbCode[5] == 0x84 && + pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && + pbCode[9] == 0x00 && pbCode[10] == 0x00) { + return 11; + } + + // int 3. + if (pbCode[0] == 0xcc) { + return 1; + } + return 0; +} + +#endif // DETOURS_X64 + +//////////////////////////////////////////////////////////////////////// IA64. +// +#ifdef DETOURS_IA64 + +struct _DETOUR_TRAMPOLINE +{ + // On the IA64, a trampoline is used for both incoming and outgoing calls. + // + // The trampoline contains the following bundles for the outgoing call: + // movl gp=target_gp; + // + // brl target_code; + // + // The trampoline contains the following bundles for the incoming call: + // alloc r41=ar.pfs, b, 0, 8, 0 + // mov r40=rp + // + // adds r50=0, r39 + // adds r49=0, r38 + // adds r48=0, r37 ;; + // + // adds r47=0, r36 + // adds r46=0, r35 + // adds r45=0, r34 + // + // adds r44=0, r33 + // adds r43=0, r32 + // adds r42=0, gp ;; + // + // movl gp=ffffffff`ffffffff ;; + // + // brl.call.sptk.few rp=disas!TestCodes+20e0 (00000000`00404ea0) ;; + // + // adds gp=0, r42 + // mov rp=r40, +0 ;; + // mov.i ar.pfs=r41 + // + // br.ret.sptk.many rp ;; + // + // This way, we only have to relocate a single bundle. + // + // The complicated incoming trampoline is required because we have to + // create an additional stack frame so that we save and restore the gp. + // We must do this because gp is a caller-saved register, but not saved + // if the caller thinks the target is in the same DLL, which changes + // when we insert a detour. + // + DETOUR_IA64_BUNDLE bMovlTargetGp; // Bundle which sets target GP + BYTE rbCode[sizeof(DETOUR_IA64_BUNDLE)]; // moved bundle. + DETOUR_IA64_BUNDLE bBrlRemainEip; // Brl to pbRemain + // This must be adjacent to bBranchIslands. + + // Each instruction in the moved bundle could be a IP-relative chk or branch or call. + // Any such instructions are changed to point to a brl in bBranchIslands. + // This must be adjacent to bBrlRemainEip -- see "pbPool". + DETOUR_IA64_BUNDLE bBranchIslands[DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE]; + + // Target of brl inserted in target function + DETOUR_IA64_BUNDLE bAllocFrame; // alloc frame + DETOUR_IA64_BUNDLE bSave37to39; // save r37, r38, r39. + DETOUR_IA64_BUNDLE bSave34to36; // save r34, r35, r36. + DETOUR_IA64_BUNDLE bSaveGPto33; // save gp, r32, r33. + DETOUR_IA64_BUNDLE bMovlDetourGp; // set detour GP. + DETOUR_IA64_BUNDLE bCallDetour; // call detour. + DETOUR_IA64_BUNDLE bPopFrameGp; // pop frame and restore gp. + DETOUR_IA64_BUNDLE bReturn; // return to caller. + + PLABEL_DESCRIPTOR pldTrampoline; + + BYTE rbRestore[sizeof(DETOUR_IA64_BUNDLE)]; // original target bundle. + BYTE cbRestore; // size of original target code. + BYTE cbCode; // size of moved target code. + _DETOUR_ALIGN rAlign[14]; // instruction alignment array. + PBYTE pbRemain; // first instruction after moved code. [free list] + PBYTE pbDetour; // first instruction of detour function. + PPLABEL_DESCRIPTOR ppldDetour; // [pbDetour,gpDetour] + PPLABEL_DESCRIPTOR ppldTarget; // [pbTarget,gpDetour] +}; + +C_ASSERT(sizeof(DETOUR_IA64_BUNDLE) == 16); +C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 256 + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * 16); + +enum { + SIZE_OF_JMP = sizeof(DETOUR_IA64_BUNDLE) +}; + +inline PBYTE detour_skip_jmp(PBYTE pPointer, PVOID *ppGlobals) +{ + PBYTE pGlobals = NULL; + PBYTE pbCode = NULL; + + if (pPointer != NULL) { + PPLABEL_DESCRIPTOR ppld = (PPLABEL_DESCRIPTOR)pPointer; + pbCode = (PBYTE)ppld->EntryPoint; + pGlobals = (PBYTE)ppld->GlobalPointer; + } + if (ppGlobals != NULL) { + *ppGlobals = pGlobals; + } + if (pbCode == NULL) { + return NULL; + } + + DETOUR_IA64_BUNDLE *pb = (DETOUR_IA64_BUNDLE *)pbCode; + + // IA64 Local Import Jumps look like: + // addl r2=ffffffff`ffe021c0, gp ;; + // ld8 r2=[r2] + // nop.i 0 ;; + // + // ld8 r3=[r2], 8 ;; + // ld8 gp=[r2] + // mov b6=r3, +0 + // + // nop.m 0 + // nop.i 0 + // br.cond.sptk.few b6 + // + + // 002024000200100b + if ((pb[0].wide[0] & 0xfffffc000603ffff) == 0x002024000200100b && + pb[0].wide[1] == 0x0004000000203008 && + pb[1].wide[0] == 0x001014180420180a && + pb[1].wide[1] == 0x07000830c0203008 && + pb[2].wide[0] == 0x0000000100000010 && + pb[2].wide[1] == 0x0080006000000200) { + + ULONG64 offset = + ((pb[0].wide[0] & 0x0000000001fc0000) >> 18) | // imm7b + ((pb[0].wide[0] & 0x000001ff00000000) >> 25) | // imm9d + ((pb[0].wide[0] & 0x00000000f8000000) >> 11); // imm5c + if (pb[0].wide[0] & 0x0000020000000000) { // sign + offset |= 0xffffffffffe00000; + } + PBYTE pbTarget = pGlobals + offset; + + if (detour_is_imported(pbCode, pbTarget) && *(PBYTE*)pbTarget != NULL) { + PPLABEL_DESCRIPTOR ppld = (PPLABEL_DESCRIPTOR)*(PBYTE *)pbTarget; + pbCode = (PBYTE)ppld->EntryPoint; + pGlobals = (PBYTE)ppld->GlobalPointer; + if (ppGlobals != NULL) { + *ppGlobals = pGlobals; + } + } + } + return pbCode; +} + + +inline void detour_find_jmp_bounds(PBYTE pbCode, + PDETOUR_TRAMPOLINE *ppLower, + PDETOUR_TRAMPOLINE *ppUpper) +{ + (void)pbCode; + *ppLower = (PDETOUR_TRAMPOLINE)(ULONG_PTR)0x0000000000080000; + *ppUpper = (PDETOUR_TRAMPOLINE)(ULONG_PTR)0xfffffffffff80000; +} + +inline BOOL detour_does_code_end_function(PBYTE pbCode) +{ + // Routine not needed on IA64. + (void)pbCode; + return FALSE; +} + +inline ULONG detour_is_code_filler(PBYTE pbCode) +{ + // Routine not needed on IA64. + (void)pbCode; + return 0; +} + +#endif // DETOURS_IA64 + +#ifdef DETOURS_ARM + +struct _DETOUR_TRAMPOLINE +{ + // A Thumb-2 instruction can be 2 or 4 bytes long. + BYTE rbCode[62]; // target code + jmp to pbRemain + BYTE cbCode; // size of moved target code. + BYTE cbCodeBreak; // padding to make debugging easier. + BYTE rbRestore[22]; // original target code. + BYTE cbRestore; // size of original target code. + BYTE cbRestoreBreak; // padding to make debugging easier. + _DETOUR_ALIGN rAlign[8]; // instruction alignment array. + PBYTE pbRemain; // first instruction after moved code. [free list] + PBYTE pbDetour; // first instruction of detour function. +}; + +C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 104); + +enum { + SIZE_OF_JMP = 8 +}; + +inline PBYTE align4(PBYTE pValue) +{ + return (PBYTE)(((ULONG)pValue) & ~(ULONG)3u); +} + +inline ULONG fetch_thumb_opcode(PBYTE pbCode) +{ + ULONG Opcode = *(UINT16 *)&pbCode[0]; + if (Opcode >= 0xe800) { + Opcode = (Opcode << 16) | *(UINT16 *)&pbCode[2]; + } + return Opcode; +} + +inline void write_thumb_opcode(PBYTE &pbCode, ULONG Opcode) +{ + if (Opcode >= 0x10000) { + *((UINT16*&)pbCode)++ = Opcode >> 16; + } + *((UINT16*&)pbCode)++ = (UINT16)Opcode; +} + +PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE *ppPool, PBYTE pbJmpVal) +{ + PBYTE pbLiteral; + if (ppPool != NULL) { + *ppPool = *ppPool - 4; + pbLiteral = *ppPool; + } + else { + pbLiteral = align4(pbCode + 6); + } + + *((PBYTE*&)pbLiteral) = DETOURS_PBYTE_TO_PFUNC(pbJmpVal); + LONG delta = pbLiteral - align4(pbCode + 4); + + write_thumb_opcode(pbCode, 0xf8dff000 | delta); // LDR PC,[PC+n] + + if (ppPool == NULL) { + if (((ULONG)pbCode & 2) != 0) { + write_thumb_opcode(pbCode, 0xdefe); // BREAK + } + pbCode += 4; + } + return pbCode; +} + +inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) +{ + while (pbCode < pbLimit) { + write_thumb_opcode(pbCode, 0xdefe); + } + return pbCode; +} + +inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) +{ + if (pbCode == NULL) { + return NULL; + } + if (ppGlobals != NULL) { + *ppGlobals = NULL; + } + + // Skip over the import jump if there is one. + pbCode = (PBYTE)DETOURS_PFUNC_TO_PBYTE(pbCode); + ULONG Opcode = fetch_thumb_opcode(pbCode); + + if ((Opcode & 0xfbf08f00) == 0xf2400c00) { // movw r12,#xxxx + ULONG Opcode2 = fetch_thumb_opcode(pbCode+4); + + if ((Opcode2 & 0xfbf08f00) == 0xf2c00c00) { // movt r12,#xxxx + ULONG Opcode3 = fetch_thumb_opcode(pbCode+8); + if (Opcode3 == 0xf8dcf000) { // ldr pc,[r12] + PBYTE pbTarget = (PBYTE)(((Opcode2 << 12) & 0xf7000000) | + ((Opcode2 << 1) & 0x08000000) | + ((Opcode2 << 16) & 0x00ff0000) | + ((Opcode >> 4) & 0x0000f700) | + ((Opcode >> 15) & 0x00000800) | + ((Opcode >> 0) & 0x000000ff)); + if (detour_is_imported(pbCode, pbTarget)) { + PBYTE pbNew = *(PBYTE *)pbTarget; + pbNew = DETOURS_PFUNC_TO_PBYTE(pbNew); + return pbNew; + } + } + } + } + return pbCode; +} + +inline void detour_find_jmp_bounds(PBYTE pbCode, + PDETOUR_TRAMPOLINE *ppLower, + PDETOUR_TRAMPOLINE *ppUpper) +{ + // We have to place trampolines within +/- 2GB of code. + ULONG_PTR lo = detour_2gb_below((ULONG_PTR)pbCode); + ULONG_PTR hi = detour_2gb_above((ULONG_PTR)pbCode); + + *ppLower = (PDETOUR_TRAMPOLINE)lo; + *ppUpper = (PDETOUR_TRAMPOLINE)hi; +} + + +inline BOOL detour_does_code_end_function(PBYTE pbCode) +{ + ULONG Opcode = fetch_thumb_opcode(pbCode); + if ((Opcode & 0xffffff87) == 0x4700 || // bx + (Opcode & 0xf800d000) == 0xf0009000) { // b + return TRUE; + } + if ((Opcode & 0xffff8000) == 0xe8bd8000) { // pop {...,pc} + __debugbreak(); + return TRUE; + } + if ((Opcode & 0xffffff00) == 0x0000bd00) { // pop {...,pc} + __debugbreak(); + return TRUE; + } + return FALSE; +} + +inline ULONG detour_is_code_filler(PBYTE pbCode) +{ + if (pbCode[0] == 0x00 && pbCode[1] == 0xbf) { // nop. + return 2; + } + if (pbCode[0] == 0x00 && pbCode[1] == 0x00) { // zero-filled padding. + return 2; + } + return 0; +} + +#endif // DETOURS_ARM + +#ifdef DETOURS_ARM64 + +struct _DETOUR_TRAMPOLINE +{ + // An ARM64 instruction is 4 bytes long. + // + // The overwrite is always composed of 3 instructions (12 bytes) which perform an indirect jump + // using _DETOUR_TRAMPOLINE::pbDetour as the address holding the target location. + // + // Copied instructions can expand. + // + // The scheme using MovImmediate can cause an instruction + // to grow as much as 6 times. + // That would be Bcc or Tbz with a large address space: + // 4 instructions to form immediate + // inverted tbz/bcc + // br + // + // An expansion of 4 is not uncommon -- bl/blr and small address space: + // 3 instructions to form immediate + // br or brl + // + // A theoretical maximum for rbCode is thefore 4*4*6 + 16 = 112 (another 16 for jmp to pbRemain). + // + // With literals, the maximum expansion is 5, including the literals: 4*4*5 + 16 = 96. + // + // The number is rounded up to 128. m_rbScratchDst should match this. + // + BYTE rbCode[128]; // target code + jmp to pbRemain + BYTE cbCode; // size of moved target code. + BYTE cbCodeBreak[3]; // padding to make debugging easier. + BYTE rbRestore[24]; // original target code. + BYTE cbRestore; // size of original target code. + BYTE cbRestoreBreak[3]; // padding to make debugging easier. + _DETOUR_ALIGN rAlign[8]; // instruction alignment array. + PBYTE pbRemain; // first instruction after moved code. [free list] + PBYTE pbDetour; // first instruction of detour function. +}; + +C_ASSERT(sizeof(_DETOUR_TRAMPOLINE) == 184); + +enum { + SIZE_OF_JMP = 12 +}; + +inline ULONG fetch_opcode(PBYTE pbCode) +{ + return *(ULONG *)pbCode; +} + +inline void write_opcode(PBYTE &pbCode, ULONG Opcode) +{ + *(ULONG *)pbCode = Opcode; + pbCode += 4; +} + +struct ARM64_INDIRECT_JMP { + struct { + ULONG Rd : 5; + ULONG immhi : 19; + ULONG iop : 5; + ULONG immlo : 2; + ULONG op : 1; + } ardp; + + struct { + ULONG Rt : 5; + ULONG Rn : 5; + ULONG imm : 12; + ULONG opc : 2; + ULONG iop1 : 2; + ULONG V : 1; + ULONG iop2 : 3; + ULONG size : 2; + } ldr; + + ULONG br; +}; + +#pragma warning(push) +#pragma warning(disable:4201) + +union ARM64_INDIRECT_IMM { + struct { + ULONG64 pad : 12; + ULONG64 adrp_immlo : 2; + ULONG64 adrp_immhi : 19; + }; + + LONG64 value; +}; + +#pragma warning(pop) + +PBYTE detour_gen_jmp_indirect(BYTE *pbCode, ULONG64 *pbJmpVal) +{ + // adrp x17, [jmpval] + // ldr x17, [x17, jmpval] + // br x17 + + struct ARM64_INDIRECT_JMP *pIndJmp; + union ARM64_INDIRECT_IMM jmpIndAddr; + + jmpIndAddr.value = (((LONG64)pbJmpVal) & 0xFFFFFFFFFFFFF000) - + (((LONG64)pbCode) & 0xFFFFFFFFFFFFF000); + + pIndJmp = (struct ARM64_INDIRECT_JMP *)pbCode; + pbCode = (BYTE *)(pIndJmp + 1); + + pIndJmp->ardp.Rd = 17; + pIndJmp->ardp.immhi = jmpIndAddr.adrp_immhi; + pIndJmp->ardp.iop = 0x10; + pIndJmp->ardp.immlo = jmpIndAddr.adrp_immlo; + pIndJmp->ardp.op = 1; + + pIndJmp->ldr.Rt = 17; + pIndJmp->ldr.Rn = 17; + pIndJmp->ldr.imm = (((ULONG64)pbJmpVal) & 0xFFF) / 8; + pIndJmp->ldr.opc = 1; + pIndJmp->ldr.iop1 = 1; + pIndJmp->ldr.V = 0; + pIndJmp->ldr.iop2 = 7; + pIndJmp->ldr.size = 3; + + pIndJmp->br = 0xD61F0220; + + return pbCode; +} + +PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE *ppPool, PBYTE pbJmpVal) +{ + PBYTE pbLiteral; + if (ppPool != NULL) { + *ppPool = *ppPool - 8; + pbLiteral = *ppPool; + } + else { + pbLiteral = pbCode + 8; + } + + *((PBYTE*&)pbLiteral) = pbJmpVal; + LONG delta = (LONG)(pbLiteral - pbCode); + + write_opcode(pbCode, 0x58000011 | ((delta / 4) << 5)); // LDR X17,[PC+n] + write_opcode(pbCode, 0xd61f0000 | (17 << 5)); // BR X17 + + if (ppPool == NULL) { + pbCode += 8; + } + return pbCode; +} + +inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) +{ + while (pbCode < pbLimit) { + write_opcode(pbCode, 0xd4100000 | (0xf000 << 5)); + } + return pbCode; +} + +inline INT64 detour_sign_extend(UINT64 value, UINT bits) +{ + const UINT left = 64 - bits; + const INT64 m1 = -1; + const INT64 wide = (INT64)(value << left); + const INT64 sign = (wide < 0) ? (m1 << left) : 0; + return value | sign; +} + +inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID *ppGlobals) +{ + if (pbCode == NULL) { + return NULL; + } + if (ppGlobals != NULL) { + *ppGlobals = NULL; + } + + // Skip over the import jump if there is one. + pbCode = (PBYTE)pbCode; + ULONG Opcode = fetch_opcode(pbCode); + + if ((Opcode & 0x9f00001f) == 0x90000010) { // adrp x16, IAT + ULONG Opcode2 = fetch_opcode(pbCode + 4); + + if ((Opcode2 & 0xffe003ff) == 0xf9400210) { // ldr x16, [x16, IAT] + ULONG Opcode3 = fetch_opcode(pbCode + 8); + + if (Opcode3 == 0xd61f0200) { // br x16 + +/* https://static.docs.arm.com/ddi0487/bb/DDI0487B_b_armv8_arm.pdf + The ADRP instruction shifts a signed, 21-bit immediate left by 12 bits, adds it to the value of the program counter with + the bottom 12 bits cleared to zero, and then writes the result to a general-purpose register. This permits the + calculation of the address at a 4KB aligned memory region. In conjunction with an ADD (immediate) instruction, or + a Load/Store instruction with a 12-bit immediate offset, this allows for the calculation of, or access to, any address + within +/- 4GB of the current PC. + +PC-rel. addressing + This section describes the encoding of the PC-rel. addressing instruction class. The encodings in this section are + decoded from Data Processing -- Immediate on page C4-226. + Add/subtract (immediate) + This section describes the encoding of the Add/subtract (immediate) instruction class. The encodings in this section + are decoded from Data Processing -- Immediate on page C4-226. + Decode fields + Instruction page + op + 0 ADR + 1 ADRP + +C6.2.10 ADRP + Form PC-relative address to 4KB page adds an immediate value that is shifted left by 12 bits, to the PC value to + form a PC-relative address, with the bottom 12 bits masked out, and writes the result to the destination register. + ADRP ,