{"id":18544775,"url":"https://github.com/131/dispatcher","last_synced_at":"2025-04-09T19:31:25.715Z","repository":{"id":10760922,"uuid":"13023486","full_name":"131/dispatcher","owner":"131","description":"Process forwarder (stdin/stdout/stderr)","archived":false,"fork":false,"pushed_at":"2023-11-21T01:13:31.000Z","size":175,"stargazers_count":49,"open_issues_count":0,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2023-11-21T15:36:48.600Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/131.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2013-09-23T00:27:47.000Z","updated_at":"2023-11-21T15:36:48.601Z","dependencies_parsed_at":"2023-01-11T20:14:58.781Z","dependency_job_id":"465b0c39-36b5-4bdf-b62c-23e98a90bb13","html_url":"https://github.com/131/dispatcher","commit_stats":null,"previous_names":[],"tags_count":45,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/131%2Fdispatcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/131%2Fdispatcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/131%2Fdispatcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/131%2Fdispatcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/131","download_url":"https://codeload.github.com/131/dispatcher/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223407844,"owners_count":17140572,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T20:17:34.700Z","updated_at":"2024-11-06T20:17:35.252Z","avatar_url":"https://github.com/131.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://github.com/131/dispatcher/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/131/dispatcher/actions/workflows/test.yml)\n[![Version](https://img.shields.io/github/v/release/131/dispatcher)](https://github.com/131/dispatcher/releases)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)\n![Available platform](https://img.shields.io/badge/platform-win32-blue.svg)\n\n\n\n\ndispatcher\n==========\nPowerful process forwarder (or proxy) for Windows. It can be considered as a open source, free and more powerfull alternative to\n[chocolatey shimgen](https://chocolatey.org/docs/features-shim)\n\n# How to use\nRename/duplicate `dispatcher.exe` to `[something].exe`.\nWrite a `[something].config` file next to it to configure redirection.\n\nConfiguration file syntax is :\n```\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003cadd key=\"PATH\" value=\"[relative of full path to the exe you want to call]\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n\n# Download\nFind all downloads in [GitHub Releases](https://github.com/131/dispatcher/releases)\n\n\n# Motivation  - sample usage\nI use a lot of command line tool in windows (interpreters, encoders, git \u0026 related tools)\nAll of them need to be in my **`PATH`** (that I don’t like to change).\nMerging them all in the same folder is a no go (.dll conflicts / overrides)\n\nUsing [dispatcher.exe](https://github.com/131/dispatcher) allows me to register only ONE directory in my Windows **`PATH`**, with very simple .exe forwarding processes to their genuine installation path.\n\n```\n# Current setup tree\nC:\\Program Files\\node\\bin\\node.exe\nC:\\Program Files x86\\php\\bin\\php.exe\nD:\\weird\\directory\\turtoisesvn\\svn.exe\nC:\\cygwin\\bin\\git.exe\n\n\n# I create  a single, well balanced directory\nC:\\dispatchedbin\\\n\n# I dispatch all binaries I want in it\nC:\\dispatchedbin\\node.exe\nC:\\dispatchedbin\\node.exe.config =\u003e D:\\weird\\directory\\node-testing\\node.exe\n\nC:\\dispatchedbin\\php.exe\nC:\\dispatchedbin\\php.exe.config =\u003e C:\\Program Files x86\\php\\bin\\php.exe\n```\n\n# Advanced usage, few things to understand\n* There is a fundamental difference in console applications  \u0026 desktop applications for windows\n* therefore [dispatcher](https://github.com/131/dispatcher) comes in 2 flavors - respectively dispatcher_cmd.exe \u0026  dispatcher_win.exe.\n* You cannot spawn x64 executables located in c:\\windows\\system32 from a win32 application.\n* therefore [dispatcher.exe](https://github.com/131/dispatcher) is available in 2 architectures : x32 \u0026 x64\n\n## Forced args\nYou can force additional args (injected before args that might have been sent toward `[dispatched].exe`\n``` (node.exe.config)\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003cadd key=\"ARGV[XXX]\" value=\"[optional argv 0 to XXX]\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n\n\n## Env vars\nYou can define custom env var in dispatcher.config\n``` (node.exe.config)\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003c!-- Mandatory --\u003e\n    \u003cadd key=\"PATH\" value=\"D:\\apps\\System32\\bash.exe\"/\u003e\n    \u003c!-- All optionals --\u003e\n    \u003cadd key=\"ARGV0\" value=\"-c\"/\u003e\n    \u003cadd key=\"ARGV1\" value=\"/usr/sbin/sshd -D\"/\u003e\n    \u003cadd key=\"USE_SHOWWINDOW\" value=\"true\"/\u003e\n    \u003cadd key=\"CWD\" value=\"c:\\my\\working\\dir\"/\u003e\n\n    \u003cadd key=\"ENV_FOO\" value=\"bar\"/\u003e\n    \u003cadd key=\"ENV_OTHERTHING\" value=\"something\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n## %dwd% macro\n* `%dwd%` is replaced with the absolute path to the `[dispatched].exe` directory\n\n\n## Multiple flavor\nUsing the env var `DISPATCHER_*NAME*_FLAVOR` you can toggle multiple flavor of an exe with the same dispatcher\n```\nnode.config\n\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n\n    \u003cadd key=\"PATH\" value=\"..\\node-v12.22.9-win-x64\\node.exe\"/\u003e\n    \u003cadd key=\"PATH_8\" value=\"..\\node-v8.17.0-win-x64\\node.exe\"/\u003e\n    \u003cadd key=\"PATH_16\" value=\"..\\node-v16.19.0-win-x64\\node.exe\"/\u003e\n\n    \u003cadd key=\"ENV_NODE_PATH\" value=\"%dwd%/node_modules\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n\n\nset DISPATCHER_NODE_FLAVOR=8 # will toggle node 8\nset DISPATCHER_NODE_FLAVOR=16 # will toggle node 16\n\n```\n\n\n## DETACHED flag\nWhen using dispatcher_win, you can use the `DETACHED` flag for the dispatcher NOT to wait for the child to exit.\n\n```\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003cadd key=\"PATH\" value=\"putty.exe\"/\u003e\n    \u003cadd key=\"DETACHED\" value=\"true\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n\n\n## spawn a command line app with no window (WSL bash.exe)\nIf you dispatch a console app (e.g. WSL bash.exe) from a desktop app (i.e. dispatch_win_x64.exe) you'll hide the window\n\n```\n# In my current configuration\nD:\\apps\\wsl-init.exe (dispatch_win_x64.exe)\nD:\\apps\\wsl-init.exe.config\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003cadd key=\"PATH\" value=\"C:\\Windows\\System32\\bash.exe\"/\u003e\n    \u003cadd key=\"ARGV0\" value=\"-c\"/\u003e\n    \u003cadd key=\"ARGV1\" value=\"/usr/sbin/sshd -D\"/\u003e\n    \u003cadd key=\"USE_SHOWWINDOW\" value=\"true\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n\n\n## Pre-executation command\nUsing the `PRESTART_CMD` flag make **dispatcher** run a command before another (useful for services).\n\n\n## Using dispatcher to run Windows service\nUsing the `AS_SERVICE` flag make **dispatcher** expose a Windows Service compliant interface. (therefore, you can use **dispatcher** to register any nodejs/php/whaterver script as a service. You'll have to manage the registration by yourself - see [sc create](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-create),[sc start](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-start), [sc stop](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-stop), ... APIs). Also, if needed, you can run a service in an interactive session (interact with desktop - use [murrayju CreateProcessAsUser](https://github.com/murrayju/CreateProcessAsUser) ).\n\nWhen using \"auto\" as value for `AS_SERVICE`, dispatcher will use the service mode only if running as NT_AUTHORITY.\n\n\n```\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003cadd key=\"PATH\" value=\"node.exe\"/\u003e\n    \u003cadd key=\"ARGV0\" value=\"main.js\"/\u003e\n    \u003cadd key=\"AS_SERVICE\" value=\"true\"/\u003e\n\n\u003c!-- prevent execution during UWF servicing sessions -\u003e\n    \u003cadd key=\"UWF_SERVICING_DISABLED\" value=\"true\"/\u003e\n\n\u003c!-- to run a service in interactive session --\u003e\n    \u003cadd key=\"AS_DESKTOP_USER\" value=\"true\"/\u003e\n\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n\n## UWF_SERVICING_DETECT\nUsing the `AS_SERVICE` or the `UWF_SERVICING_DETECT` flag will populate the `UWF_SERVICING_ENABLED` env variable with wether or not servicing mode is in progress.\n\n\n## Redirect output to a file (usefull for services)\nUsing the `OUTPUT` flag redirect stderr \u0026 stdout to a dedicated file. Date modifiers are available.\n\n```\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003cadd key=\"PATH\" value=\"node.exe\"/\u003e\n    \u003cadd key=\"ARGV0\" value=\"main.js\"/\u003e\n    \u003cadd key=\"OUTPUT\" value=\"%temp%\\logs-%Y%-%m%-%d% %H%-%i%-%s%.log\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n\n\n# Service restart policy\nIn service mode, dispatcher will restart your process every time it exit, with an exponential (pow 2) backoff delay.\n\n\n## SERVICE_RESTART_ON_NETWORK_CHANGE\nDispatcher can monitor network interface status change.\nUse the `SERVICE_RESTART_ON_NETWORK_CHANGE` flag to reset the backoff delay.\n\n```\n\u003c?xml version=\"1.0\" encoding=\"utf-8\" ?\u003e\n\u003cconfiguration\u003e\n  \u003cappSettings\u003e\n    \u003cadd key=\"PATH\" value=\"node.exe\"/\u003e\n    \u003cadd key=\"ARGV0\" value=\"main.js\"/\u003e\n    \u003cadd key=\"AS_SERVICE\" value=\"true\"/\u003e\n\n    \u003cadd key=\"SERVICE_RESTART_ON_NETWORK_CHANGE\" value=\"true\"/\u003e\n  \u003c/appSettings\u003e\n\u003c/configuration\u003e\n```\n\n\n## Configuration lookup path\ndispatcher will lookup for configurations directives in\n\n* if existing `[dispatched].config` (xml file)\n* if existing `[dispatched].exe.config`  (xml file)\n* all matching `[dispatched_directory]/[dispatched].config.d/*.config`  (xml files)\n\nAny directive defined multipled time will be overrided with the latest value\n\n\n## Using multiple versions of the same software\n```\ninstall php 5 in\nC:\\Program Files x86\\php5.0\\bin\\php.exe\ninstall php 7 in\nC:\\Program Files x86\\php7.0\\bin\\php.exe\n\nCreate to dispatcher (php5.exe \u0026 php7.exe)\n```\n\n## Make a portable binary out of any shell/script\nUsing dispatcher.exe is a nifty way to create portable binaries out of shell scripts (.bat,.js,.php)\n\n\n# How does it work\ndispatcher use kernel32 Process spawn to force stdin, stdout \u0026 stderr handler to the forwarded process. Therefore, supports PIPE, Console or FILE as process handle (\u0026 all others handler). The dispatcher \u0026 the underlying process are bound to kernel32 Job group (tied together, you cannot kill one without the other). Exit code is forwarded.\n\n\n# Running the command is slow\nIf you have a fresh install of Windows, you may have to build native images to [improve performance of managed applications](https://learn.microsoft.com/en-us/dotnet/framework/tools/ngen-exe-native-image-generator).\n\nOpen Command Prompt as an administrator and run these commands:\n```\n%windir%\\Microsoft.NET\\Framework\\v4.0.30319\\ngen.exe executeQueuedItems\n%windir%\\Microsoft.NET\\Framework64\\v4.0.30319\\ngen.exe executeQueuedItems\n```\n\nIf this does not solve the issue, it may be the application that Dispatcher is calling itself having slowdown issues.\n\n\n## Tested \u0026 approved binaries (for reference)\n\n* cmd apps : git (msysgit-1.8.4), php, node, python, svn, xpdf (pdftotext \u0026 ..), openssl, rsync, bash, gzip, tar, sed, ls, tee \u0026 co (from msysgit), ffmpeg, gsprint, 7z, ...\n* desktop apps : nwjs, process explorer\n\n\n# Credits\n* [131](https://github.com/131)\n* [murrayju](https://github.com/murrayju/CreateProcessAsUser)\n* Code signing, courtesy of IVS Group.\n\n\n# Relatives/alternatives\n* [run.exe](http://www.straightrunning.com/projectrun.php) kinda stuff\n* [shimgen](https://chocolatey.org/docs/features-shim)\n\n\n# Shoutbox, keywords, SEO love\nbackground cmd, wsl bash, linux subsystem, process forward, kernel32, USE_SHOWWINDOW\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F131%2Fdispatcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F131%2Fdispatcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F131%2Fdispatcher/lists"}