12

I'm deciding on the programming language I want to use for a simple script that will make a HTTP request checking for avaliable updates, download the update if avaliable and execute a program. On MacOS and all distros of Linux I can safely bet that some version of python will be avaliable on the system - and if a Linux distro doesn't come with python, I can safely assume that user of such niche OS will know how to install it.

But with Windows I know that out of the box it doesnt't have python, jre, or even runtime libraries for running CLR languages. Is there anything else beside Powershell I can use?

The program is distributed for Windows as a ZIP file and it's portable (non installer required). This is why I want the language to already to be avaliable on user's system.

16
  • 31
    What makes you specifically rule out PowerShell? Commented Mar 4 at 12:48
  • 2
    @u1686_grawity unfamiliarity, mostly. Since I exclusively work with Linux, I developed good sense of which task are best suited for a shell script and which are better with a dedicated program. Judging by your comment, Powershell isn't exactly an equivalent of bash on Linux and would be a good fit for what I described (I left out that the script will display a dialog window to confirm if the update should be downloaded)? Commented Mar 4 at 13:35
  • 11
    powershell is a scripting language but powerful as a full compiled language. It can even call native code and be used for GUI programming. It's more powerful than bash and given the objective nature it's easier to process things on the pipeline without text parsing
    – phuclv
    Commented Mar 4 at 15:18
  • 14
    Python is not a safe bet on macOS post 12.3, and its also not even remotely a guarantee on Linux (Alpine is a trivial example of a popular distro that does not ship Python by default, and I can think of a dozen others without even thinking). The standard choice for Linux, and macOS (and BSD) is POSIX shell script. Commented Mar 5 at 2:45
  • 2
    @java-addict301, AustinHemmelgarn I'll only clarify that by "not niche" I meant specifically popular desktop distros that might be used by someone, who will struggle with an error message "python is not installed on your system". It's my understanding that with modern Linux (specifically desktop editions, which is my target), you need to go out of your way to not have python installed and not eventually install it as a dependency as you use your system. Commented Mar 5 at 19:46

6 Answers 6

29

You don't need a general-purpose language if you can ship a compiled program – you're already writing a program in the first place; use the same method to write an Updater.exe alongside the main App.exe. For example, as you said you write Lua and bundle it with a runtime to make an .exe file, so you can also do the same to make an updater in Lua.

As for built-ins, PowerShell would be your best option, generally. It runs on .NET CLR and exists somewhere in-between Bash and C# – the language is built mainly for "shell script" type of work, but you have full access to all standard .NET classes (as well as COM and WMI/CIM), and can even use inline C# code via Add-Type if you end up needing FFI (P/Invoke).

There is a built-in HTTP client available as Invoke-RestMethod (irm) and a slightly different HTTP client under Invoke-WebRequest (iwr); one of them can parse JSON and XML. To display a message, you can call .NET WinForms using:

[System.Windows.Forms.MessageBox]::Show("Hello!")

All reasonably recent Windows versions include "Windows PowerShell" version 5. It lacks some niceties, e.g. some options for Invoke-WebRequest are missing, but otherwise is nearly the same as modern PowerShell 7.

The only downside is that PowerShell scripts always show a console window; there is so far no equivalent of pythonw.exe or similar. (It's a long story.)

All other options are slightly worse:

  • Compiled .exe that uses WinHTTP (or statically linked to libcurl). You can compile a Windows .exe from Linux using Mingw64.
  • VBScript. It's officially "deprecated" now, but it still ships with all Windows versions because of things like slmgr.vbs. Some corporate systems might disable it, but they're equally likely to disable PowerShell.
  • Batch script that uses various arcana to unpack an embedded binary such as curl.exe into %TEMP% (as seen in some not-entirely-legal tools).
  • Batch script that uses the curl.exe that comes built-in with Windows 10. (I would use Nirsoft's nircmd.exe for displaying the popup message, but nothing stops you from echo-ing a VBScript into %TEMP%, or something else.)
13
  • you can use powershell or vbs to show a GUI and hide the console though
    – phuclv
    Commented Mar 4 at 15:21
  • 2
    Then you can write the updater as another Lua script turned into an .exe, no? Commented Mar 4 at 16:39
  • 1
    @LarsKristensen: I can imagine that being done in banks or whatever, but I suppose if you get to that point, you're already in a situation where the IT team would Really Prefer if you asked for approval before running your portable apps from a USB stick either way... Commented Mar 5 at 6:47
  • 2
    @LarsKristensen: Isn't "Open in Notepad" the default action for .ps1 scripts, though? Commented Mar 5 at 9:20
  • 5
    The one issue I take with this is the comparison between vbscript vs powershell disabled status. Powershell is only enabled out of the box if you're talking about signed scripts, and it's unlikely the OP has gone that far. So, effectively, the vbscript and powershell situations are reversed: vbscript is enabled unless someone has taken affirmative action to disable it, and powershell is disabled unless you take affirmative action with your script to allow it. Commented Mar 5 at 18:44
14

The only languages that can be counted upon to exist in every modern Windows version are:

Batch is a very old language with multiple idiosyncrasies, but does most jobs (more or less). It can be pretty painful to use for complex operations.

PowerShell is much newer, but its syntax is totally new (one can find examples for almost every question on the internet). It has a steeper learning curve, but can do very many operations, much more extensively than Batch. Some operations require the installation of additional modules from the internet, which might affect negatively your distributed scripts.

VBScript is perhaps the more familiar language-like and is also very ancient. Microsoft would like to see it deprecated. However, so much software has been written using it that it seems unlikely to disappear in the years to come (or ever).

6
  • 3
    VB Script is being deprecated in the near future. I suspect within a year it will fully depreciate
    – Ramhound
    Commented Mar 4 at 15:45
  • 1
    VB Script is different since Microsoft will choose when Windows no longer has the capability to run VB Scripts
    – Ramhound
    Commented Mar 5 at 0:38
  • 4
    Didn't there use to be a VBScript equivalent, based on Javascript, named JScript? It could call all the same APIs. Was it removed?
    – marczellm
    Commented Mar 5 at 9:29
  • 2
    @marczellm I just checked, and it looks like it hasn't officially been deprecated, but it at least seems like it was quietly retired with the transition from IE to Edge. Hasn't had any real updates since 2015.
    – Idran
    Commented Mar 5 at 15:00
  • 1
    Was JScript removed? Commented Mar 6 at 16:45
6

A lot of scripting languages have a way to package them into a single-file binary executable.

The usual strategy is to include a custom interpreter executable that loads scripts from itself (read itself as the source file) and the zip file format. It works because the metadata in zip files are stored at the end of the file but executables are loaded from the beginning of the file. Therefore it is possible to simply join any executable with any zip file into a single file making that file both a valid executable and a valid zip file. So now all you need is a script interpreter that unzips the source file before loading the script.

You mentioned Python. Python has PyOxidizer that can "compile" python scripts into a single binary executable. I'm not a Python user so I've never used it but you may want to take a look.

Javascript has several methods to package a binary. There's of course Electron made famous by VSCode. There's also nwjs. Of course, both of those are for GUI applications but for command line scripts there's pkg.

For Ruby there's Orca and AllInOneRuby. For Perl there's Packer. And for Tcl there's FreeWrap.

1

The closest things I could find on Windows were single-binary interpreters, and the ones I used were GNU Make and busybox-w32. Busybox's sh implementation was quite functional, reliable, and sufficient for a couple scripts I wrote, and along with the dated GnuWin32 standalone binaries I was able to accomplish what I needed.

1

If I were faced with a similar challenge, I'd reach for a language or runtime that can easily compile stand-alone binaries. For a more native (machine-level) language I'd try Go (GoLang). For scripting, I'd use JavaScript/TypeScript through Deno. Go can cross compile to many operating systems. And Deno has a deno compile command to bundle your scripts into a portable executable. Also, both languages have great standard libraries.

-1

If your app is graphical, did you consider JavaScript?

You can serve in the cloud an "installation" webpage, then open it from your app with a query parameter = current installed version

  • the page would do the HTTP request
  • the page would prompt to update if the version is lower (ex. re-downloading the installer)

This is what LibreOffice do. The app query for update internally then redirect to a web page to download a new version.

There are several advantages:

  • this page would double-down as an install page for new users
  • you can track the activity of this page with analytics
  • you can promote complimentary or new products in the future if needed
  • you can ask for donations (like LibreOffice does) etc.

Of course this doesn't allow self-updating the app, but it may be enough depending on what you try to do and the maturity of your project.

2
  • Can you clarify what do you mean as "JavaScript"? I can check for updates and open the web page from the app itself, updater is needed for replacing the binaries in-place before lunching them. Commented Mar 5 at 20:34
  • @ReverentLapwing indeed this solution doesn't allow to update the binary, but depending on your project the trade-offs could be interesting. I edited the answer and mentioned LibreOffice as an example.
    – Offirmo
    Commented Mar 7 at 5:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .