tzk icon indicating copy to clipboard operation
tzk copied to clipboard

FileNotFoundError: [WinError 2] The system cannot find the file specified

Open Jestdie opened this issue 3 years ago • 11 comments

Computer Info

  • OS Windows 11
  • Python 3.10.2
  • tzk version 0.1.4
  • git version 2.35.1.windows.2
  • node v16.13.2

Details

I get the error found below whenever I run tzk init or tzk convert. I tried updating all dependencies found in the documentation. I tried uninstalling all dependencies and reinstalling.
I am out of ideas, so I am posting here in hopes someone knows what I am doing wrong.

Error

C:\Users\JiN\wiki>tzk init
tzk: Creating new tzk_config.py...
tzk: Creating new package.json...
tzk: Installing npm packages from package.json...
Traceback (most recent call last):
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\Scripts\tzk.exe\__main__.py", line 7, in <module>
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\site-packages\tzk\__main__.py", line 424, in launch
    args._cls().execute(args)
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\site-packages\tzk\__main__.py", line 157, in execute
    tw.install(args.wiki_name, args.tiddlywiki_version_spec, args.author)
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\site-packages\tzk\tw.py", line 192, in install
    _init_npm(wiki_name, tw_version_spec, author)
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\site-packages\tzk\tw.py", line 100, in _init_npm
    subprocess.check_call(("npm", "install"))
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 364, in check_call
    retcode = call(*popenargs, **kwargs)
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 345, in call
    with Popen(*popenargs, **kwargs) as p:
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 966, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1435, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified

Jestdie avatar Feb 05 '22 05:02 Jestdie

As a work around I installed TZK using WSL.

Jestdie avatar Feb 05 '22 08:02 Jestdie

  File "C:\Users\JiN\AppData\Local\Programs\Python\Python310\lib\site-packages\tzk\tw.py", line 100, in _init_npm
    subprocess.check_call(("npm", "install"))
...
FileNotFoundError: [WinError 2] The system cannot find the file specified

It sounds like npm isn't on your $PATH – are you sure you ran npm --version as suggested in the documentation to check that it was installed? It's possible you might need to reboot your computer after installing to get your environment variables fully updated.

If you run where.exe npm, what's the output?

sobjornstad avatar Feb 05 '22 14:02 sobjornstad

npm version: 8.4.1

where.exe npm output:

C:\Program Files\nodejs\npm
C:\Program Files\nodejs\npm.cmd
C:\Users\JiN\AppData\Roaming\npm\npm
C:\Users\JiN\AppData\Roaming\npm\npm.cmd

Edit: Did a fresh reboot, no changes.

Jestdie avatar Feb 05 '22 15:02 Jestdie

I hacked around a bit and got tzk init and tzk listen to complete.

I don't know python, so to be honest I am not sure what the code I added does exactly.

But, I traced the first error back to, line 17 of tw.py, "return subprocess.check_output(("npm", "bin"), text=True).strip()".

After Googling that exact line of code on StackOverflow, I found someone who mention adding shell=True.

So I added shell=True to all the subprocesses, one at a time watching the error log.

This fixed most issues, but the whoami() function was finding "masterpc\jin" and the backslash was making the 'package.json' invalid. So, I just hardcoded "jin".

Full tw.py with changes. https://gist.github.com/Jestdie/6e526858f517a5ea4974cbe2c05ca8b3

Jestdie avatar Feb 05 '22 21:02 Jestdie

I'm guessing you somehow have your environment set up so that npm is only on the path when you're in a shell, and not on the rest of your PC – I'm not familiar enough with this part of Windows to explain exactly how that would have gotten set up, but I know it's possible (for instance, maybe it could be set up within the shell initialization file?).

shell=True can introduce security vulnerabilities, so it's not a good idea to add as a matter of course – but here you should be pretty much fine since the command to be run is hard-coded (someone could still add an alias for npm in your shell initialization file that did something nasty, but if they had access to do that, they presumably could just as well change your PATH and shell=True would be a moot point).

As for the whoami() part, you should be able to put it back to the original implementation now that you have init completed, since you'll now have an author configured within your tzk_config.py.

On Sat, Feb 5, 2022, at 15:59, Jestdie wrote:

I hacked around a bit and got tzk init and tzk listen to complete.

I don't know python, so to be honest I am not sure, what the code I added does exactly.

But, I traced the first error back to, line 17 of tw.py, "return subprocess.check_output(("npm", "bin"), text=True).strip()".

After Googling that exact line of code on StackOverflow, I found someone who mention adding `shell=True'.

So I added `shell=True' to all the subprocesses, one at a time watching the error log.

This fixed most issues, but the whoami() function was finding "masterpc\jin" and the backslash was making the 'package.json' invalid. So, I just hardcoded jin.

Full tw.py with changes. https://gist.github.com/Jestdie/6e526858f517a5ea4974cbe2c05ca8b3

— Reply to this email directly, view it on GitHub https://github.com/sobjornstad/tzk/issues/2#issuecomment-1030706189, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARUZRVYFY4X23PZQEVDFMDUZWMVDANCNFSM5NTPHSFA. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you commented.Message ID: @.***>

sobjornstad avatar Feb 06 '22 01:02 sobjornstad

I think this is related to the way subprocess works on windows, which expects an executable, or more specifically a "Win32 application". When I run the following in the python interpreter (launched from powershell or cmd):

>>> subprocess.run(("C:\\Program Files\\nodejs\\npm", "bin"))

I get:

OSError: [WinError 193] %1 is not a valid Win32 application

However, if I use run npm help npm using (Win+R) it opens the help page, so it's not a path issue. Additionally the following command is successful when run in the python interpreter:

>>> subprocess.check_output(("node", "--version"))

And node and npm are in the same folder on my computer.

Solutions

I haven't been able to figure out a solution that doesn't involve editing the tw.py file but there seems to a couple of ways to do it:

shell=True works but comes with security concerns as @sobjornstad said. It's also possible to use ("pwsh", "-c") as the first two commands, but I'm guessing that has the same security issues? (I don't actually know)

subprocess.check_output(("npm", "bin"), shell=True)

Alternatively, using npm.cmd instead of npm, as in:

return  subprocess.check_output(("npm.cmd", "bin"), text=True).strip()

However you then need to adjust the tiddlywiki init command, so it becomes:

subprocess.check_call(("npx.cmd", "tiddlywiki", "--init", "tzk"))

There are a few other things you need to change to get this all working well on windows without shell=True. I think using WSL is probably the easiest way to do this without having to change a bunch of things.

PARC6502 avatar Sep 01 '22 16:09 PARC6502

Curious, how exactly did you install npm that this isn't working for you?

sobjornstad avatar Sep 01 '22 19:09 sobjornstad

I installed the "OpenJS.NodeJS" package using winget. The problem seems common though, I found a lot of people asking online about the same error, mostly the answer/solution they found was to use shell=True.

I edited a version of tw.py that works on my Windows machine without using shell=True.

PARC6502 avatar Sep 01 '22 20:09 PARC6502

I just noticed this:

However, if I use run npm help npm using (Win+R) it opens the help page, so it's not a path issue.

The Run dialog also uses a registry key called “App Paths” in addition to the system path, so this is not a good way to test if something is on your PATH. Does it also work from cmd?

sobjornstad avatar Sep 02 '22 14:09 sobjornstad

I'm about to head out for a holiday weekend here, but I can try to play around with this on my Windows machine next week and see if I can reproduce the issue.

sobjornstad avatar Sep 02 '22 14:09 sobjornstad

It works from both cmd and powershell, and the installation folder is in the path. Plus, even when I referenced the exact path, I got that OSError. I'll admit to not understanding the underlying mechanics of that.

PARC6502 avatar Sep 02 '22 16:09 PARC6502