Repository: xonsh/xonsh

Issue:
Can't use winget, the official package manager for windows, in xonsh.
<!--- Provide a general summary of the issue in the Title above -->
<!--- If you have a question along the lines of "How do I do this Bash command in xonsh"
please first look over the Bash to Xonsh translation guide: https://xon.sh/bash_to_xsh.html
If you don't find an answer there, please do open an issue! -->

## xonfig

<details>

```
+------------------+---------------------+
| xonsh            | 0.9.18              |
| Git SHA          | 26475146            |
| Commit Date      | May 5 06:42:28 2020 |
| Python           | 3.7.6               |
| PLY              | 3.11                |
| have readline    | True                |
| prompt toolkit   | 3.0.3               |
| shell type       | prompt_toolkit      |
| pygments         | 2.5.2               |
| on posix         | False               |
| on linux         | False               |
| on darwin        | False               |
| on windows       | True                |
| on cygwin        | False               |
| on msys2         | False               |
| is superuser     | True                |
| default encoding | utf-8               |
| xonsh encoding   | utf-8               |
| encoding errors  | surrogateescape     |
+------------------+---------------------+
```

</details>

## Expected Behavior
<!--- Tell us what should happen -->
Winget commands successfully run.

## Current Behavior
<!--- Tell us what happens instead of the expected behavior -->
<!--- If part of your bug report is a traceback, please first enter debug mode before triggering the error
To enter debug mode, set the environment variable `XONSH_DEBUG=1` _before_ starting `xonsh`.
On Linux and OSX, an easy way to to do this is to run `env XONSH_DEBUG=1 xonsh` -->
Winget commands work successfully in cmd, but fail in xonsh
```
For full traceback set: $XONSH_SHOW_TRACEBACK = True
OSError: [Errno 22] Invalid argument: 'C:\\Users\\lin\\AppData\\Local\\Microsoft\\WindowsApps\\winget.exe'
```

xonsh (left) and cmd (right)
![image](https://user-images.githubusercontent.com/54425948/92865310-ba559580-f430-11ea-9f0a-f32411b6fb0b.png)

### Traceback
<details>

```
xonsh: To log full traceback to a file set: $XONSH_TRACEBACK_LOGFILE = <filename>
Traceback (most recent call last):
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 17776, in default
    run_compiled_code(code, self.ctx, None, "single")
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 2942, in run_compiled_code
    func(code, glb, loc)
  File "<xonsh-code>", line 1, in <module>
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 22658, in subproc_captured_hiddenobject
    return run_subproc(cmds, captured="hiddenobject")
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 22579, in run_subproc
    specs = cmds_to_specs(cmds, captured=captured)
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 22532, in cmds_to_specs
    spec = SubprocSpec.build(cmd, captured=captured)
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 22300, in build
    spec.resolve_executable_commands()
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 22375, in resolve_executable_commands
    self.cmd = get_script_subproc_command(self.binary_loc, self.cmd[1:])
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 21863, in get_script_subproc_command
    elif _is_binary(fname):
  File "E:\anaconda3\lib\site-packages\xonsh\__amalgam__.py", line 21825, in _is_binary
    with open(fname, "rb") as f:
OSError: [Errno 22] Invalid argument: 'C:\\Users\\lin\\AppData\\Local\\Microsoft\\WindowsApps\\winget.exe'
```

</details>

## Steps to Reproduce
<!--- Please try to write out a minimal reproducible snippet to trigger the bug, it will help us fix it! -->
1. Download and install [winget](https://github.com/microsoft/winget-cli/releases)
2. Run any winget command in xonsh. For example, "winget install deepvocal", or "winget search browser"


## For community
⬇️  **Please click the 👍 reaction instead of leaving a `+1` or 👍  comment**

[I have created an issue in the winget repo](https://github.com/microsoft/winget-cli/issues/565)



Discussion:
To temporarily solve this problem, run this command in an elevated xonsh:

```
echo @winget %* > C:\Windows\System32\wg.bat
```

Then you can use "wg" command instead of "winget".
Hey there @oxygen-dioxide - A couple of things: Does `C:\\Users\\lin\\AppData\\Local\\Microsoft\\WindowsApps\\winget.exe` actually exist on your filesystem?  Also could you please upgrade xonsh to 0.9.21 and see if this is still happening? Thanks!
1. Yes, "C:\\Users\\lin\\AppData\\Local\\Microsoft\\WindowsApps\\winget.exe" exists.
![image](https://user-images.githubusercontent.com/54425948/93335562-39940080-f859-11ea-8be8-70ec7a95d3ca.png)

2. After I upgraded to xonsh 0.9.21, winget still failed to work in xonsh
What do `__xonsh__.commands_cache.get('winget')` and `__xonsh__.commands_cache.get('winget.exe')` return?
```
lin@LAPTOP-K4JTR2V5 ~\Desktop $ __xonsh__.commands_cache.get('winget')
('C:\\Users\\lin\\AppData\\Local\\Microsoft\\WindowsApps\\winget.exe', None)
lin@LAPTOP-K4JTR2V5 ~\Desktop $ __xonsh__.commands_cache.get('winget.exe')
('C:\\Users\\lin\\AppData\\Local\\Microsoft\\WindowsApps\\winget.exe', None)
```
I think I have seen something similar with with other WindowsApps. They are not real exe files. They are shims created by windows with zero file size. 

![image](https://user-images.githubusercontent.com/1038978/93427549-472fa180-f8be-11ea-98e7-89a2768d476a.png)

So it fails when we inspect them with `_is_binary()`. If we could find a way to detect those kind of exe files we probably work around the problem. Can you fix that @oxygen-dioxide ? 
Sorry, I am a amateur python user. I'm not able to fix this issue.
I don't know how we can detect these App Execution aliases.  They show up when running `os.listdir()` and they can be used as arguments to `popen` (esentially `CreateProcess` resolves them). But we can't open them and `os.path.exists()` returns false. 
@xonsh/xore   Ouch. I just accidentally pushed my fix to this issue directly to master :( VSCode is dangerous that way.

I am quite sure it works, but I will still let one of you roll it back so we can do a proper PR. Sorry. It is late here. 

Resolving patch:
diff --git a/xonsh/built_ins.py b/xonsh/built_ins.py
--- a/xonsh/built_ins.py
+++ b/xonsh/built_ins.py
@@ -184,10 +184,7 @@ def is_app_execution_alias(fname):
         Here try to detect if a file is an app execution alias
     """
     fname = pathlib.Path(fname)
-    return (
-        not os.path.exists(fname)
-        and fname.name in os.listdir(fname.parent)
-    )
+    return not os.path.exists(fname) and fname.name in os.listdir(fname.parent)
 
 
 def _is_binary(fname, limit=80):


Test patch: