-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Only use console mode if run on command line? #2117
Comments
I'm not a Windows guy, so I may be wrong. AFAIK this is not possible since on Windows even the entry points differ, see the source. |
It's possible, but it requires quite a bit more trickery than I'm willing to commit to. Luckily, all of the required C functions can be called via the If you do get this approach to work, let us know. Working code for this would be welcome on the PyInstaller wiki as a new Recipe. If not, there's always |
Hmm ok, I'll take a look at that. Thanks. Our specific use case is that we have a windowed app, but you can specify some config parameters on the command line which means that being able to do --help would be useful but now the output gets lost. |
This is something I would be interested to do as well. |
Now, is anybody taking the challenge on this` |
This issue recently came up for me as I was trying to build an application to run in either command line or GUI modes depending on where it was run from. Although it is not perfect, my solution was to have pyinstaller build the application with console=True, on startup detect how it was run, and then hide the console if we want GUI mode. To hide the console I used the method suggested in this comment #1339 (comment) . The downside is that the console will flash on startup, but that didn't bother me much. Then to detect the run mode on startup I did the following. The for loop is run 3 times to get the name of the grandparent of our process. If the grandparent is explorer.exe then we would run in GUI mode because it was double clicked. But if the grandparent is cmd or powershell then we would run in CLI mode. NOTE: the decision to traverse up 2 levels is because the first parent is the bootloader exe, because I am using onefile mode. I guess if you were using onedir mode you would only need to go up one level (but I didn't test that). import wmi
cwmi = wmi.WMI()
def isCliCaller():
'''Helper function to check the grandparent process and identify if we should use cli or window'''
if getattr(sys, 'frozen', False):
pid = os.getpid()
name = ''
for x in range(3):
for process in cwmi.Win32_Process(ProcessId=pid):
name = process.name
pid = process.ParentProcessId
if 'explorer' in name.lower():
return False
return True |
This can't be done due to windows restrictions. |
An alternative that works for me: attach to a parent console if one is available, otherwise, don't show the console when the app is double clicked. Set console=False in your pyinstaller spec. |
@sbytnar I followed #2117 to find the parent pid but AttachConsole returns 0 and GetLastError returns 5 I want to redirect all stdout form this script to parent command line when the frozen exe got invoked from command line. Can you help me here... def isCliCaller():
'''Helper function to check the grandparent process and identify if we should use cli or window'''
if getattr(sys, 'frozen', False):
pid = os.getpid()
for x in range(3):
for process in cwmi.Win32_Process(ProcessId=pid):
name = process.name
pid = process.ParentProcessId
print(x, name, pid)
if 'cmd' in name.lower():
res = ctypes.windll.kernel32.AttachConsole(pid)
print(res)
print("Attach failed with error " + str(ctypes.windll.kernel32.GetLastError()))
# sys.stdout = sys.stderr = open('CONOUT$', 'wt')
# sys.stdin = open('CONIN$', 'rt')
return False
return True |
we use the @sbytnar solution, but the problem is that windows command prompt and powershell will not block when running gui programs, and the results are "messy console output". i think you need to mark the app as "console" but not actually allocate one to get the desired behavior in powershell. this would, likely, mean a custom bootloader. one that reports itself to windows as a console app, but uses a winmain entry point anyway |
This is half question and half feature request.
Let's say I build with the -w flag. Is there a way to allow the executable to still output to stdout if it's run on the command line, but not pop up a console window if the user double-clicks on the icon or starts it from a GUI?
The text was updated successfully, but these errors were encountered: