Embeddable Package Manager (+core in .bat); π Lightweight tool to Create or Distribute using basic shell scripts (does not require powershell or dotnet-cli); NuGet / Chocolatey client;
Copyright (c) 2015-2025 Denis Kuzmin <x-3F@outlook.com> github/3F
gnt
-help
| gnt
~& svc.gnt
| gnt
*/p:use=documentation
gnt Fnv1a128 # Get Fnv1a128 package
gnt +DllExport # Install DllExport package
gnt *DllExport # Install and Run DllExport.bat
gnt ~hMSBuild # Touch hMSBuild
gnt /t:pack /p:ngin="bin\DllExport" # Create new DllExport package
gnt "Conari;regXwild" # Get Conari & regXwild packages
msbuild gnt.core /p:ngpackages=LuNari/1.6.0 # Use msbuild to get LuNari 1.6.0
gnt Huid/1.0.0:src.zip /t:grab # Grab Huid 1.0 as zip without unpacking
gnt /p:ngconfig="dir\packages.config" # Use specified packages.config
set ngpackages=Conari & gnt # shell scripts
gnt /p:ngpackages=putty.portable/0.69 # chocolatey
/p:ngserver="https://chocolatey.org/api/v2/package/"
Download all editions: Core, Minified, Executable, C# version for .NET, ...
Direct Links to the latest stable:
- (Windows) Latest stable compiled batch-script [ gnt.bat ]
https://3F.github.io/GetNuTool/releases/latest/gnt/
- netfx4sdk - Developer Pack (SDK). NETFX 4: Visual Studio 2022+ / MSBuild 17+ / or other modern tools;
- hMSBuild - Compiled text-based embeddable pure batch-scripts for searching modern MSBuild instances;
- .NET DllExport Manager - Part of the DllExport tool that provides its completely independent management and distribution beyond the NuGet ecosystem. Relies on MvsSln as well;
> gnt # via single shell script
> msbuild gnt.core # via MSBuild engine
[NuGet gnt.raw("/t:pack /p:ngin=7z.Libs")] # via SobaScript
new GetNuTool() # .NET(netfx 4.0+, .NET 5+, .NET Core, Mono) C#
Lightweight Portable and completely Embeddable (+core in .bat) package tool to create or distribute everything from anything.
Back in those days it was originally developed as an alternative to solution level limitations, i.e. github.com/NuGet/Home/issues/1521. In attempt to provide a tool to easily maintain projects, libraries, and other related build processes; For all projects at once at the solution level and of course for each separately if necessary.
For example, it was designed to be more friendly to such NuGet packages:
- vsSolutionBuildEvent (before, aka vsSBE.CI.MSBuild)
- 7z.Libs
- DllExport
- ILAsm
However! GetNuTool has more powerful ways even for standard NuGet packages providing a wider range of use cases.
- Install .nupkg packages from remote NuGet (or like: chocolatey, ...) servers.
- Grab or Install any zipped packages from direct sources (local, remote http, https, ftp, ...).
- Controlled unpacking of all received packages. Modes:
get
orgrab
orinstall
ortouch
- Hash values control using
sha1
for receiving every package if used unsecured channels (~windows xp) etc. - Creating new NuGet packages .nupkg from .nuspec.
- Two supported formats: xml packages.config (+extra: output, sha1) and inline records.
- Inline records and packages.config are fully compatible between, and config has backward compatibility with original packages.config
- Configurable custom folders for every receiving.
- Request to the server only if the package is not installed.
- Supports proxy with custom credential.
- Default settings are overridden through an environment variables: default .config files, NuGet server, etc.
- The ability to create one click ~8 KB .bat wrappers for any packages. Try for example vsSolutionBuildEvent.bat
- Easy integration into any scripts such as pure batch-script netfx4sdk, DllExport, hMSBuild
- C# projects support via GetNuTool.cs
- .pkg.install.bat and .pkg.install.sh support for install, run, touch modes and additionally via
+
(plus),*
(asterisk),~
(tilde) i.e.gnt +...
,gnt *...
,gnt ~...
respectively.
Note:
- Dependencies are not considered.
- Doesn't manage projects or solutions files. You need MvsSln or anything else together with.
- NuGet events (Init.ps1, Install.ps1, Uninstall.ps1) from /tools will not be launched automatically.
- To use events (from Visual Studio, MSBuild, NuGet, etc.), you can with vsSolutionBuildEvent, or vsCommandEvent, or configure it like DllExport project, or command it manually.
For receiving packages or zipped files from local or remote source, then installing / extracting.
The get
is used by default but you can also specify /t:get
Property | Description | Default values |
---|---|---|
ngconfig | Define .config files. | 1.9+ packages.config;.tools\packages.config |
π ngserver | Define server. | 1.0+ https://www.nuget.org/api/v2/package/ |
ngpackages | List of packages. Disables ngconfig if specified. | |
ngpath | Common path for all packages. | 1.0+ packages |
wpath | 1.4+ To change working directory. | 1.4+ (The absolute path of the directory where the GetNuTool is located) |
π proxycfg | 1.6.2+ To configure connection via proxy. | |
ssl3 | 1.9+ Do not drop legacy ssl3, tls1.0, tls1.1 if true . |
|
break | 1.9+ Disable the break on first package error if no |
*π env protected property in 1.10+. Changing the value using an environment variables with the same name is prohibited. All intersections in used environment must be removed before actual execution (for example set "ngserver="
), otherwise it will result in denied error.
Attribute | Description | Example |
---|---|---|
id | Identifier of package. | Conari |
version | (Optional) Package version. | 1.5.0 or 1.5-beta2 or 1.5-RC etc. |
output | (Optional) Where to store package data. | ../tests/case1 |
sha1 | (Optional) Expected sha1 for this package. | eead8f5c1fdff2abd4da7d799fbbe694d392c792 |
Note:
- As of version 1.2+, attributes are now case sensitive. Please use lowercase for
id
,version
,output
,sha1
. - It will link to the latest available version if
version
attribute is not defined. output
attribute is relative tongpath
. You can also use absolute path.sha1
activates the alternative security check before each accessing (modes: get, install, run, touch, grab). It useful when connection is not secure like on windows xp with obsolete ciphers. But please note: some servers (like official NuGet) may repackage .nupkg for some purposes, such as adding .signature.p7s etc. This of course changes sha1 hash value that you need to check.id
allows onlya-z
A-Z
0-9
.
-
_
symbols without whitespaces.
id[/version][?sha1][:path];id2[/version][?sha1][:path];...
delimiters:
;
1.6+Name1;Name2;Name3
|
1.0-1.9Name1|Name2|Name3
/p:ngpackages=Name1
/p:ngpackages="Name1;Name2"
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Name1" version="1.5.0" />
<package id="Name2" output="path" />
<package id="Name3" version="2.2-RC" sha1="eead8f5c1fdff2abd4da7d799fbbe694d392c792" />
</packages>
/p:ngconfig=".nuget/packages.config"
/p:ngconfig="debug.config;release.config;..."
[usr[:pwd]@]host[:port]
/p:proxycfg="example.com:4321"
1.9+
Grabs data without unpacking. The available parameters are similar to the get
above.
For example:
gnt Huid/1.0.0:src.nupkg /t:grab
gnt :../netfx4sdk.cmd /t:grab /p:ngserver=https://server/netfx4sdk.cmd
msbuild gnt.core /t:grab /p:ngpackages=Fnv1a128:src.nupkg
gnt Huid/1.0.0?24ecda9a4fb8920067df31788d3dea708996ab08:src.nupkg /t:grab
Creates the new .nupkg packages using .nuspec specification.
Can also be found in the package folder after using get
.
Property | Description | Default values |
---|---|---|
ngin | Path to directory where .nuspec to create package from it. | |
ngout | Optional path to save the final .nupkg package in other place. |
|
wpath | 1.4+ To change working directory. | 1.4+ (The absolute path of the directory where the GetNuTool is located) |
gnt /t:pack /p:ngin=path\to\dir
gnt /t:pack /p:ngin="path to\dir";ngout=..\dst.nupkg
1.10+
GetNuTool automatically invokes .pkg.install.bat (or .pkg.install.sh depending on the environment) in activated install
or run
or touch
modes if the package provides support for this. Note: Once per clean install (it won't trigger for cached or already unpacked packages).
The available options are the same as for the get
mode described above.
The install
mode can be activated in different ways,
gnt +DllExport
gnt +"DllExport;Conari"
or using /t:install
msbuild gnt.core /t:install /p:ngpackages=DllExport
io.github._3F.GetNuTool gnt = new();
gnt.Run(ngpackages: "Conari;DllExport", tmode: "install");
The run
mode is similar to the install described above but using *
instead of +
,
gnt *DllExport
gnt *"DllExport;Conari"
and /t:run
msbuild gnt.core /t:run /p:ngpackages=DllExport
gnt.Run(ngpackages: "Conari;DllExport", tmode: "run");
The touch
mode extends the install mode and allows to work with package and its contents in a one-time or temporary execution. Once processing is complete, the package and its contents will be deleted.
To activate this mode, you can define ~
(tilde) in arguments:
gnt ~hMSBuild
or using /t:touch
msbuild gnt.core /t:touch /p:ngpackages=hMSBuild
gnt.Run(ngpackages: "hMSBuild", tmode: "touch");
You can also control the mode options via /p:use=...
gnt ~GetNuTool /p:use=documentation
.pkg.install.* are text files which can optionally be located in the root directory of the package and support the following optional arguments:
Arguments | # | alternative in bat | alternative in bash | Example |
---|---|---|---|---|
Version of the arguments format | %~1 |
- | - | 1 |
Activated tMode | %~2 |
- | - | install or run or touch |
Full path to the working directory | %~3 |
%cd% |
$PWD |
D:\projects\obj\ |
Full path to the package | %~4 |
%~dp0 |
$(dirname "$0") |
D:\projects\obj\packages\DllExport\ |
Accessible environment variables:
Environment variable | Description | Example |
---|---|---|
GetNuTool |
GetNuTool version | 1.9.0.58814+bb83b59 |
debug |
Activated debug mode | true |
use |
Mode options | help.cmd |
.pkg.install.* can be used for any purposes related to the installation process, for example, providing License.txt
copy /Y/V "%~dp0\License.txt" "%cd%\"
or updating the version number for the directory up to the received
set /p _version=<"%~4\.version"
ren "%~4" MyPackage.%_version%
or to start setting up or updating something automatically.
Additionally touch
mode allows to wrap or deliver anything, for example:
- Add .pkg.install.bat
@echo off
if not "%~2"=="touch" exit /B0
if "%use%"=="help" (
echo.
echo In the Beginning the World ...
exit /B0
)
- Generate package:
gnt /t:pack /p:ngin=D:\prg\MyPackage
- Upload to the server you want.
- In the end, your workflow will contain nothing but the result after
gnt ~MyPackage /p:use=help
> gnt ~MyPackage /p:use=help /p:info=no;logo=no
In the Beginning the World ...
For a real example, see the following .pkg.install.bat from DllExport package (1.8.2+)
@echo off
copy /Y/V "%~dp0\DllExport.bat" "%cd%\">nul || exit /B1
if "%~2"=="touch" exit /B0
set /p _version=<"%~dp0\.version"
set /p _rel=<"%~dp0\.release.version"
if defined _rel set _version=%_version%-%_rel%
set "dst=%~dp0\..\DllExport.%_version%"
if exist "%dst%" rmdir /S/Q "%dst%"
::`ren` must be processed as a single command along with the called program due to line-by-line processing by the cmd processor after loss of src
ren "%~dp0" DllExport.%_version% && if "%~2"=="run" ("%cd%\DllExport.bat") else echo.exit/B0>"%dst%\.cmd"&"%dst%\.cmd"
Logic follows the instructions from here:
- Copy DllExport.bat into solution folder.
- Don't do anything else if activated
touch
mode (i.e.gnt ~DllExport
). Otherwise:- Associate the latest received package (i.e.
gnt +DllExport
) with a specific version (as if it were likegnt +DllExport/1.8.2-RC
etc.) - Run Wizard if activated
run
mode (i.e.gnt *DllExport
).
- Associate the latest received package (i.e.
In the end, ~8 KB of the gnt.bat now helps to achieve the same result in a fully automated way.
Property | Value |
---|---|
debug | true to add extra info in stream. |
logo | no to hide logo when processing starts. |
info | no to hide information about receiving packages etc. |
For example:
gnt /t:pack /p:ngin=packages\LX4Cnh /p:debug=true
set debug=true & gnt /p:ngpackages="Conari;LX4cn;Fnv1a128";break=no
GetNuTool now is part of NuGetComponent
#[NuGet gnt.raw("/t:pack /p:ngin=D:\7z.Libs")]
GetNuTool.cs includes a fully compatible gnt.core inside.
Add GetNuTool.cs to your project (.NET Framework 4.0+, .NET 5+, Mono, .NET Core, .NET Standard), then use it like:
io.github._3F.GetNuTool gnt = new();
// NOTE: older GetNuTool (before 1.10) used the `net.r_eg` namespace
// var gnt = new net.r_eg.GetNuTool();
gnt.Run(ngpackages: "Conari;regXwild");
//...
gnt.Run(ngpackages: "Fnv1a128");
NOTE: modern GetNuTool now provides its own package; In this case GetNuTool.cs can be automatically added to your project after installation in Visual Studio or like. Control it via $(GetNuToolDisableCsharp)
option.
To override the way messages are printed in 1.10+
class MyGnt: io.github._3F.GetNuTool
{
public override void StdOutLine(string msg = "", params object[] args)
{
base.StdOutLine(msg, args);
}
public override void StdErrLine(string msg = "", params object[] args)
{
base.StdErrLine(msg, args);
}
}
...
MyGnt gnt = new();
gnt.Run();
~8 KB gnt.bat
includes a fully compatible gnt.core inside.
First key to gnt.bat | Description | Example |
---|---|---|
... | 1.9+ alias to ngpackages=... |
gnt Conari , gnt "regXwild;Fnv1a128" |
-unpack |
1.6+ To generate minified gnt.core from gnt.bat. | gnt -unpack |
-msbuild |
1.6 - 1.8 To use specific msbuild. Removed in 1.9. Override engine instead | gnt -msbuild "D:\MSBuild\bin\amd64\msbuild" /p:ngpackages=Conari |
+ |
1.10+ Activate install mode. Automatic call .pkg.install.* for supported packages. tMode == install |
gnt +DllExport , gnt +"DllExport;Conari" |
* |
1.10+ Activate run mode. Automatic call .pkg.install.* for supported packages. tMode == run |
gnt *DllExport , gnt *"DllExport;Conari" |
~ |
1.10+ Activate touch mode. Automatic call .pkg.install.* for supported packages with their automatic disposal. tMode == touch |
gnt ~hMSBuild |
Other keys to gnt.bat | Description | Example |
---|---|---|
/help -help /h -h /? -? |
1.9 Reserved; 1.10+ Help command; | gnt /help |
1.10+
gnt ~
(using touch mode), gnt *
(using run mode), gnt +
(using install mode)
For example:
Gets svc.gnt.bat
gnt ~
Access svc.gnt helper and execute -sha1-get command
gnt ~& svc.gnt -sha1-get LX4Cnh/1.1
Install and run the documentation
gnt */p:use=documentation
Get version of the core
gnt ~/p:use=version
syntax
gnt ~/p:use=?
etc.
Note you can also generate wrapper using svc.gnt -embed, for example:
gnt ~/p:use=doc
as help.bat
svc.gnt -embed "~/p:use=doc" -name help
GetNuTool allows to override the engine in the following ways:
Either create hMSBuild.cmd
stub (inside the directory from which the call gnt.bat is planned, or globally using system or environment PATH) with the following content, for example:
@echo msbuild.exe
Or the same but using the full hMSBuild.bat (~19 KB) script.
Or manually via -unpack command:
gnt -unpack & msbuild.exe gnt.core {args}
Deprecated:
1.9: msb.gnt.cmd
file stub and %msb.gnt.cmd%
environment variable.
1.6 - 1.8: -msbuild
key.
1.10+
https://www.nuget.org/packages/GetNuTool/
Predefined properties:
MSBuild Properties | Description |
---|---|
GetNuToolRootPkg |
Root path to the installed GetNuTool package. |
GetNuToolBatPath |
Path to the directory where batch scripts (.bat,.cmd). |
GetNuToolBat |
Full path to gnt.bat edition. |
GetNuToolSvcBat |
Full path to svc.gnt.bat helper. |
GetNuToolCsharp |
Full path to GetNuTool.cs edition. |
GetNuToolCore |
Full path to gnt.core. |
Preferences:
MSBuild Property / Environment variable | Default value | Description |
---|---|---|
GetNuToolDisableCsharp |
To prevent adding GetNuTool.cs for compilation with the project, set as false |
GetNuTool supports install mode (+run, +touch) starting with 1.10.
Supported use
commands:
Command | Description |
---|---|
? |
alias svc.gnt -core syntax |
doc / documentation |
(depending on modes) Copy GetNuTool.version.html into the working directory; then open it. |
- |
nothing |
(empty) |
Copy fresh gnt.bat and svc.gnt.bat into the working directory. |
version |
alias svc.gnt -version |
version-short |
alias svc.gnt -version-short |
Note gnt /help
is alias to gnt ~/p:use=?
Empty package name is alias to GetNuTool/{version}
: gnt ~
, gnt +
, gnt *
For example, to install gnt.bat and svc.gnt.bat helper into the working directory:
gnt ~
Note gnt ~GetNuTool
is equal to gnt ~
but gnt ~GetNuTool/1.10
can be different depending on actual gnt.bat
Same but using addional properties (n. ngserver):
gnt ~/p:ngserver=...
All this will result in overwriting existing local copies if there are any inside the working directory. To prevent this behaviour, update reaonly attribute e.g. attrib +r gnt.bat
to lock updating and attrib -r gnt.bat
to unlock respectively.
Using the format gnt ~& svc.gnt ...
allows accessing to svc.gnt even if it doesn't exist locally, for example:
gnt ~& svc.gnt -help
GetNuTool supports hostname + IPv4 + IPv6 (via square brackets, http://[::1]
) for specified protocol:
- Over http:
http://
server/,https://
server/ - Over ftp:
ftp://
server/,ftp://
usr@server/,ftp://
usr:pwd@server/ - Over URL File Format:
file:///
D:/path/
Local paths:
- absolute:
D:/path/
,D:\path\
,D:\\path\\
, ... - relative:
../path/
,..\..\path\
, ...
Proxy format:
[usr[:pwd]@]host[:port]
. For example,guest:1234@10.0.2.15:7428
gnt vsSolutionBuildEvent/1.16.1:../SDK & SDK\GUI
gnt Conari
gnt /p:ngpackages=Conari
msbuild gnt.core /p:ngpackages=Conari
gnt "Conari;regXwild;MvsSln"
gnt /p:ngpackages="Conari;regXwild;MvsSln"
gnt Fnv1a128
gnt /t:pack /p:ngin=packages/Fnv1a128
gnt LX4Cnh? /p:logo=no;info=no
... 65f7d7f5d29a16a91f1c0a8ae01ef65d5868c2cf[x]
gnt LX4Cnh?65f7d7f5d29a16a91f1c0a8ae01ef65d5868c2cf
msbuild gnt.core /p:ngconfig=".nuget/packages.config";ngpath="../packages"
gnt Conari /p:proxycfg="guest:1234@10.0.2.15:7428"
set ngpackages=Conari & call gnt || echo Failed
gnt "7z.Libs;vsSolutionBuildEvent/1.16.1:../packages/SDK"
Direct link to a remote package via https:
gnt :DllExport /p:ngserver=https://server/DllExport.1.7.4.nupkg
Direct link to a local package that will be stored at the top level next to the gnt
gnt : /p:ngserver=D:/local_dir/vsSolutionBuildEvent.SDK10.nupkg /p:ngpath=SDK10
gnt "Conari;Fnv1a12;LX4Cnh" /p:break=no /p:debug=true
Conari use D:\prg\projects\GetNuTool\GetNuTool\bin\Release\packages\Conari
Fnv1a12 ... The remote server returned an error: (404) Not Found.
LX4Cnh ... D:\prg\projects\GetNuTool\GetNuTool\bin\Release\packages\LX4Cnh
- /.version
- /build-info.txt
- /lib/net40/LX4Cnh.dll
- /lib/net40/LX4Cnh.xml
- /lib/net5.0/LX4Cnh.dll
- /lib/net5.0/LX4Cnh.xml
- /License.txt
- /LX4Cnh.nuspec
- /Readme.md
- /tools/gnt.bat
- /tools/hMSBuild.bat
...
gnt Huid/1.0.0:src.zip /t:grab
See also examples from tests/
git clone https://github.com/3F/GetNuTool.git src
cd src & build & bin\Release\gnt Conari
Test the result using the following,
- tests.bat - for .bat edition
- tests.csharp.bat - for C# edition
GetNuTool releases are now accompanied by a .sha1 file in the official distribution; At the same time, commits from which releases are published are signed with the committer's verified signature (GPG).
Make sure you are using official, unmodified, safe versions.
Note: .sha1 file is a text list of published files with checksums in the format:
40-hexadecimal-digits
<space>
file
e9e533b0da8e5546eff821a40fbf7ca20ab9cf7e path\file
...
It is important to note the following: this is not a specialized protection of gnt.bat, this is only part of its capabilities which can also be used to check itself too.
For example, to validate itself:
gnt ~& svc.gnt -sha1-cmp gnt.bat sha1 -package-as-path
Where sha1 is the checksum from the official distribution. Also, the official package (gnt +GetNuTool
) provides validate.gnt.bat; this is wrapper of the command above, located in \shell\batch\
How safe is it?
Since the testing logic is part of the feature id[/version][?sha1]
support (here above, read about the alternative security check before each accessing on legacy windows xp etc), it is located inside gnt.bat. This way improves control over unexpected changes, however, it still cannot fully guarantee automatic protection against third party interference directly into the gnt.bat.
Same for env protected properties (n. v1.10: ngserver and proxycfg); this improves control over unexpected modification in environment when processing at runtime, but this of course cannot stop direct modifications of the code. Keep this in mind.
GetNuTool is waiting for your awesome contributions!