mtkennerly / shawl

Windows service wrapper for arbitrary commands
MIT License
495 stars 15 forks source link

Problem with childprocess #2

Closed shirshak55 closed 4 years ago

shirshak55 commented 4 years ago

If i use console then it works properly but when i use shawl nothing happens

I have created a express js which open if use click any button.

import { exec } from "child_process"

 exec(`start "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" "http://google.com"`)
mtkennerly commented 4 years ago

There are a few issues here:

All that said, can you explain your use case for running Chrome as a service? I'm wondering if there's a better way to do what you're trying to accomplish.

shirshak55 commented 4 years ago

hmm my server api downloads a pdf. But it would be convinient if i can open the pdf from chrome or any software once downloaded.

if so whats the best solution?

On Mon, Nov 4, 2019, 7:25 PM Matthew Kennerly notifications@github.com wrote:

There are a few issues here:

  • Windows services aren't really meant to run GUI applications like Chrome. It's technically possible, but Microsoft has a bunch of warnings about it, and it's being deprecated (so eventually may not work at all). If you still want to try, here's some info: https://docs.microsoft.com/en-us/windows/win32/services/interactive-services
  • start is a shell built-in, not a normal program, so I think you'd need to have your service entry point be something like cmd /C "start chrome.exe http://google.com". However, that's a bad idea because start, by design, won't wait for Chrome to exit, which means Shawl will constantly be trying to restart the start command. You'd probably just want Shawl to run Chrome directly, so that Shawl will only try to restart it when the browser closes.

All that said, can you explain your use case for running Chrome as a service? I'm wondering if there's a better way to do what you're trying to accomplish.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mtkennerly/shawl/issues/2?email_source=notifications&email_token=AB5Y4YP5UQO5DOZRD4NX3HTQSAQ4RA5CNFSM4JILCDLKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEC7IOCA#issuecomment-549357320, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB5Y4YKP2HBHTVH5FZU4ASDQSAQ4RANCNFSM4JILCDLA .

mtkennerly commented 4 years ago

Ah, so you wanted to automatically open each PDF after download? I can think of a few service-friendly alternatives:

Basically anything that leaves the graphical opening of the file outside of the service, but still gives you an easy way to tell when there's a new file. Does that help?

shirshak55 commented 4 years ago

@mtkennerly hmm my mom is not so technical. So what i am doing is running express http server.

The server accept the request and downloads pdf.

Now I want to bot to open that pdf so that my mom don't need to go to that directory find which is new pdf that is downloaded etc.

At last line of handling request i have code like this

app.get('/download-pdf',(req)=>{
... download pdf

let pdfFileName = downloaded_pdf_file_name();

exec(`start "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", pdfFileName`)
})

The problem is when i use command prompt it opens the pdf file in chrome browser directly. But if i use shawl nothing happens.

And by the way what happens to those standard output thrown to console?

mtkennerly commented 4 years ago

In that case, I think your options are:

Ultimately, this is a limitation of Windows services, not of Shawl itself :/

The command's output isn't currently logged, but I do plan to add support for that. (My original use case was running a program that already did its own logging to a file.)

shirshak55 commented 4 years ago

@mtkennerly hmm i don't know what is problem but i can run puppeteer which is headless browser properly everything. Only thing that is not working is executing shell stuff.

mtkennerly commented 4 years ago

Right, this is a Windows service limitation that only applies to GUI programs. Since Puppeteer is headless, it won't have the same problem, so that makes sense. Officially from Microsoft, running GUI programs as services is deprecated.

I did some testing on Windows 10 just to see if I could find a way to make what you're trying to do work, but no luck:

shawl add --name foo -- "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" http://www.google.com
sc config foo type= interact type= own
sc start foo

This does make Chrome show up in the Task Manager's list of processes, so it's definitely running, but the GUI just doesn't work. I tried swapping own with share, userown, and usershare, but it doesn't make a difference, and changing Shawl's internal reference to the service type doesn't have an impact either.

Some other observations:

So I really don't think there's any way to run Chrome as a Windows service. You'll need to try some other options for the GUI part of your use case (e.g., a scheduled task, or a normal script running on startup, or a directory monitor tool).

shirshak55 commented 4 years ago

headful puppeteer works fine too. its just that anything that we need to run via console is not working.

On Wed, Nov 6, 2019, 6:41 AM Matthew Kennerly notifications@github.com wrote:

Right, this is a Windows service limitation that only applies to GUI programs. Since Puppeteer is headless, it won't have the same problem, so that makes sense. Officially from Microsoft, running GUI programs as services is deprecated.

I did some testing on Windows 10 just to see if I could find a way to make what you're trying to do work, but no luck:

shawl add --name foo -- "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" http://www.google.com sc config foo type= interact type= own sc start

This does make Chrome show up in the Task Manager's list of processes, so it's definitely running, but the GUI just doesn't work. I tried swapping own with share, userown, and usershare, but it doesn't make a difference, and changing Shawl's internal reference to the service type doesn't have an impact either.

Some other observations:

  • In an interactive console, chrome.exe google.com immediately returns 0 without waiting for the browser to close.
    • When run as a service, though, Shawl doesn't appear to see the command as ever finishing, which is peculiar. When you stop the service, it's still able to kill the Chrome process like you'd expect.
  • Same thing for running notepad, whose GUI also doesn't work as a service.

So I really don't think there's any way to run Chrome as a Windows service. You'll need to try some other options for the GUI part of your use case (e.g., a scheduled task, or a normal script running on startup, or a directory monitor tool).

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mtkennerly/shawl/issues/2?email_source=notifications&email_token=AB5Y4YN5CV4DP5TOS76NEYTQSII4BA5CNFSM4JILCDLKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDE32EQ#issuecomment-550092050, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB5Y4YPN5OTL6SLDNLBKBL3QSII4BANCNFSM4JILCDLA .

mtkennerly commented 4 years ago

That's interesting about headful Puppeteer. I don't suppose you have some sample code/gist or instructions so I could see it in action myself?

However, I can confirm that it's not an issue with child_process in particular. As a test, I made a file at C:/tmp/child-proc/index.js with this content:

const { exec } = require("child_process");
exec("C:/github/mtkennerly/shawl/target/debug/shawl-child.exe");

shawl-child.exe is a dummy program that just logs forever so you know it's running as a service. Then I ran:

shawl add --name foo -- "C:/Program Files/nodejs/node.exe" C:/tmp/child-proc/index.js
sc start foo

Log output:

Which means that the JS exec call worked fine. The only issue I see here is that some GUI programs just won't work as a Windows service.