What is the relationship between Windows Shell and the Shell API? - windows

The centerpiece of Microsoft Windows' UI is called Windows Shell. Classically it was Windows Explorer, but I understand that in Windows 8 it's something else ("Immersive Shell"?) Anyways, it's possible to replace the shell with something else - Windows itself supports Command Prompt as the shell out of the box, but there are several 3rd party shells available as well, and have been for more than two decades.
At the same time there's something called "The Shell API". It includes a lot of functions, interfaces, registry keys, etc. which are designed to allow a program to interact with the Shell. You can, for instance, show the Windows File-copy dialog from your own program; navigate the Shell Namespace, write an extension for the Shell; etc.
And this confuses me. If the Shell can be replaced, doesn't that mean that the Shell API is replaced with it? Won't installing a different shell break all the applications that use the Shell API? Even more - things like the Shell Namespace are essential to Windows as such; I can't imagine replacing it with something else.
Or is it so the Shell API is separate from the Shell itself, and every replaceable Shell must implement a specific set of interfaces (and adhere to mandatory conventions like the Shell Namespace) in order to work?

It is separate. The shell is Explorer.exe. The shell api is implemented in DLLs. So you can use them even if Explorer.exe isn't running.
Of course don't expect shell extensions to work in a replacement shell.

Related

Adding custom commands to terminal along side application

I am working on an application where we are using xtermjs and node-pty inside of an electron application. We are adding a terminal to our application and would like to add some custom commands that are used in the terminal that are related to our application.
What are some options for adding these commands?
We want them installed with the application.
They don't have to be useable inside an 'external' terminal, but it is ok if they are. By external, i mean your normal terminal. Not our xterm & node-pty implementation.
And we want them to behave the same as other normal unix commands. Where you can pipe with other commands && them together and stuff.
I have played around with intercepting commands between xterm and node-pty and that was a disaster. I am now considering, just writing bash scripts for the commands and having the installer manage putting them where they need to be so they can be used.
Just wondering what my options are, thanks.
You can simply put all your executables in a directory that you add to your PATH when you invoke the shell in your terminal emulator.
The commands will be available to the user like any others in any construct that accepts commands, regardless of the user's shell or shell version (i.e. it'll work equally well in bash, zsh and fish).
If you need the commands to coordinate with your terminal emulator (e.g. if you want to process the command in JS in your Node.js process), you can arrange that via a second environment variable containing e.g. a host/port to connect to.

On Windows what is the difference between Git Bash vs Windows Power Shell vs Command prompt

I am a Mac guy who is used to Mac's Terminal. Now I am using Windows.
Whats the diff between those CLI options?
When should I use one over the other?
Are there more CLI options that I should consider?
What CLI would you use if you were a Mac person trying to adapt to Windows?
The reason I am trying to use Windows, is that I want to ensure the CLI of my Docker projects work for Windows users, that I can write files coming from my container to Windows and ensure my README files have instructions for Windows users. And basically test everything I do on Windows too, like Python.
Git bash is bash, which is IIRC also the default shell on MacOS. It is not the default shell on Windows, although several implementations exist (CygWin, MinGW, ...).
Git is bundled with a number of POSIX (UNIX/Linux/etc.) utilities in addition to bash; in order to avoid "collisions" with similarly named Windows commands, the most common installation option is to install bash in such a way that the other POSIX commands are only available when running bash. The Git installer will create a shortcut to launch this "private" version of bash, hence "git bash".
The Windows command prompt runs the default Windows shell, CMD.EXE, which is a derivative of the old MS-DOS command shell, COMMAND.COM. It is much less capable than most POSIX shells; for example, it did not until relatively recently support an if/then/else construct, and it does not support shell functions or aliases (although there are some workarounds for these limitations).
PowerShell is more of a scripting environment. I'd compare it to Perl on UNIX/Linux systems -- much more powerful than the standard shell, but not necessarily something I'd want to use at the command line.
One thing to be aware of is that some of the nicer PowerShell features may require you to update your version of PowerShell -- the version bundled with Windows is typically a few years old. And updating PowerShell usually requires admin privilege; depending on the version, you may also need to update the .NET framework.
If I were a Mac person trying to adapt to Windows ... it depends. In the short term it would be easier to use something familiar like bash. But long term, you -- and more importantly, your potential users -- may not want to be dependent on a third party tool, especially since for Windows users that will typically present an additional learning curve.
As to which to use when ... it really depends on what you're trying to accomplish -- both in terms of technical functionality and the interface you want to present to your users. As noted above, I'd consider PowerShell more appropriate for scripting than the CLI, unless you just need to run a cmdlet (either a built-in or one you've created yourself).
This is a high-level overview of some of the differences between the shells, not a feature by feature comparison.
CMD (Command Prompt) and PowerShell are both shells for Windows. CMD.exe was borne from COMMAND.COM, which was itself born from MS-DOS, and has some logical constructs and can run programs, process output, and do most basic tasks you would expect from a shell. It is generally considered very limited based on what other shells can do, but is not incapable if you know how to use it. However, it was never really "designed", with new features getting tacked on without a clear roadmap.
Powershell is a shell designed from the ground up with ties into .NET and has more modern language constructs built in. Microsoft designed Powershell as a replacement to CMD.exe and batch scripting, though CMD is far from being deprecated. Powershell can call directly into .NET classes, work with WMI objects natively, and has built in remoting capabilities. It is more akin to a programming or scripting language than batch scripting is. There is a much stronger community surrounding Powershell today than there is for batch scripting, and it is generally recommended to write new code in Powershell than to continue to use batch (CMD) scripting.
Powershell does feel like CMD at first. You can run programs in it and process their output, and in most cases programs will behave exactly the same whether they are run from Powershell, or from CMD. However, you will quickly notice some differences - not all variables are considered environment variables, variables are prefixed with a $ as opposed to being wrapped in %, and the Powershell pipeline is far more powerful than the CMD pipeline. Powershell is also entirely object-oriented, which is unique when compared to most other shell languages which are primarily text based.
You can read more here about why Powershell is recommended over batch scripting, and there is a good bit of history on CMD.exe and batch files as well.
Git Bash is the same bash shell you are used to on Linux and MacOS but instead compiled for Windows. It has the Git prefix with the name to indicate it was installed with Git for Windows, a packaging of git and various *nix utilities compiled for Windows for use with git. You can run sh and bash scripts in it, as well as call the Unix programs it installs with it.
The Unix utilities can generally be run in CMD or PowerShell too, but by default the installer does not add these utilities to the SYSTEM or USER PATH, as to not potentially override the same utilities the user may use in other contexts. Basically, it isolates the utilities installed with Git Bash to Git Bash.
Outside of git automation, I wouldn't recommend using Git Bash itself for anything production related, you would probably rather manage an installation of cygwin, msys2, or another Unix compatibility layer yourself in that case. But it can be a handy shell to have during development, although these days I generally prefer PowerShell over bash for Windows scripting.

Do all applications have a command line interface?

I've been learning shell script on my Mac recently. Take an application like Atlassian's SourceTree as an example. My understanding is that it's just a GUI for git commands, which can be executed through command line. Pressing a button just triggers a corresponding git command, which is effectively run through the command line behind the scenes. If that is the case, do all applications that have a GUI function this way? Are all applications essentially just running their commands through the machine's shell script? And if so, are the underlying commands that are being used publicly available, offering an API of sorts for any application?
This is more complex than that.
Many applications only have a GUI (e.g., Safari), many others only have a CLI (e.g., find).
When a GUI app and a CLI app perform the same function, they may communicate with each other or they may not:
As you point out a GUI application can run a CLI command behind the scene (with system() or popen() for instance)
An alternative is that both applications use the same underlying library
Or no code is shared at all (think of ls vs. Finder on Mac)
Finally on Mac some GUI apps can be controlled with Applescript language, which is available through osascript command. In other words, you can control iTunes with a bash script.
Definitely, not all applications behave that way. In fact, from my experience, I'd say that there are few applications that follow that. Most applications perform their own operations relying directly on the OS platform and functionalities, instead of executing shell commands which, in addition, are hard (and most of the time impossible) to port between OSs.

bat file to launch exe and wait for string in standard output

Folks,
Is it possible to create a bat file that launches an executable and waits for a pre-determined string in the standard output. When that string is found, the batch file will exit (the exe can continue running). How could this be accomplished?
In short, no.
Note that originally MS-DOS was an operating system in which Windows ran. Now it is an application that simulates the earlier OS. The way to solve your would possibly involve using an application called from within MS-DOS, that will perform this kind of logic (i.e. IF(file_is_present_with_string)THEN {...}) in the MS-DOS command library.
Powershell is a powerful scripting language allowing you to perform many operations previously unavailable in MS-DOS, such as take the output from one MS-DOS command (e.g. ipconfig /all) and reformat it into a different layout, possibly using it as another command's input parameters (e.g. select a value from ipconfig and use it in another command). Although it supports MS-DOS command execution, it does so through the use of CMDLETs (pronouned command-let) which is a self-contained application designed to run inside Powershell. There are many other CMDLETs out there that might be able to help solve your problem.

Difference between Linux text mode and Windows command prompt

I don't know if this is a dumb question or not but again as my professor says if you have doubts then clear them . What is the difference between Linux text mode and windows command prompt (cmd). I know both windows and Linux are different Operating Systems but when you look at the commands, some of the commands are common For Example cd command.
Although superficially similar in some ways, the two command line interfaces have different lineages:
The Windows command prompt is based heavily on that of MS-DOS / PC-DOS, which in turn was based on the CP/M Console Command Processor. The CP/M CCP interface was itself based on an earlier operating system called RSTS.
The Linux shells trace their roots back to the original UNIX Thompson shell; the Thompson shell borrowed from the Multics shell (where the term "shell" originated).
Traces of these are still evident today - the DIR command in the Windows command prompt can be traced all the way back to the DIR command in RSTS, and similarly the ls command in GNU coreutils can be traced back to the Multics "list segments" command.
They're both based on the same idea and are called Command-Line Interfaces (see wikipedia). They operate off the same principals, just using different keywords to perform similar commands. It should be noted however, that the commands although similarly named, may not perform the exact same function. They are just abstractions of lower level functions of the operating system. Just like people can explain similar ideas using different words and phrases, the same applies in this situation. For reference here's a list of Bash commands: http://ss64.com/bash/ and the same website has windows commands.
The difference is the operating system. The command prompt (cmd) and a terminal emulator (linux bash shell or similar) are text interfaces to the operating system. They allow you to manipulate the file system and run programs without the graphical interface.
You should read about Linux shells. The Bash shell for instance, is among the most used Linux shells... ever!
http://doc.dev.md/lsst/ch01sec07.html
http://www.tuxfiles.org/linuxhelp/shell.html
And if you're looking for a list of commands: http://www.physics.ubc.ca/mbelab/computer/linux-intro/html/
It is not that commands are in common (well yes, maybe some), it is that they have the same name and do almost the same things, as for cd as you said.
The shells are an abstraction of the underlying operative system, Linux and Windows have a different kernel, hence the difference.
You might want to start here with your reading.

Resources