I am creating a program in GoLang that has an optional console window. During normal operation, the window will be completely hidden (including the task bar) and I the user will interact with it through the system tray. I want to have an option that shows / hides the console window when the user presses a button in the tray. I've done this before in C# by doing this:
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
const int SW_HIDE = 0;
const int SW_SHOW = 5;
var handle = GetConsoleWindow();
// Hide
ShowWindow(handle, SW_HIDE);
// Show
ShowWindow(handle, SW_SHOW);
In order to do this in Go, I used this package: https://github.com/lxn/win. This package is a WinAPI wrapper for Go that will let me use all the same commands. Here is the code I used to do the same thing as the C# code above:
win.ShowWindow(win.GetConsoleWindow(), win.SW_SHOW)
Now this actually worked perfectly as intended on Windows 10, which does NOT use Windows Terminal by default. I'm running Windows 11 which does use Windows terminal, so I assume that's the reason this is not hiding. Instead, it simply minimizes the window instead of hiding it. Is it possible for me to either force my Go program to NOT use Windows Terminal or preferably get the Windows Terminal to hide like it does with Command Prompt?
Thank you for any help
EDIT: In Windows Terminal, you can go to the settings and set the default terminal application to "Windows Console Host" and that will use command prompt, but this is computer wide. This does fix the problem though. I would like this to just be for my program alone, so the problem still stands, but just making note of it.
Related
I am using custom file dialog which is extended from the CFileDialog.
The problem is that, OninitDialog() does not get called before DoModal().
I have customized the CFileDialog in the OninitDialog().
I am using VS 2012 with Win7 OS.
I could not find out, what is going wrong.
I just run into same issue today; I think I found a valid solution, in constructor of your class just set m_bVistaStyle = FALSE;
After doing this, I got OnInitDialog and I was able to customize this dialog just fine.
CMyOpenDlg::CMyOpenDlg(LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
CFileDialog(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
m_bVistaStyle = FALSE;
The Microsoft documentation says that OnInitDialog is not supported on Windows Vista.
The same is true for Windows 7 (and probably also for Windows 8).
Does anyone have an example of building a complete WIN32 Windows app as a dll?
I'd like to export a function, call it via rundll32, and have a complete Windows app with decorations, a menu, accelerators, and everything pop up.
I know about the calling convention for rundll32:
void CALLBACK TestEntryW(HWND hWnd, HINSTANCE hInst, LPWSTR pszCmdLine, int nCmdShow);
I can pull up a MessageBox from that function via the command: rundll32.exe test3.dll,TestEntry other params and args
I can load resources from my DLL by getting the DLL's handle via GetModuleHandle("test3.dll") and using that as hInst in my LoadString calls. That seems to be working for LoadIcon and LoadAccelerators as well, but I don't have working yet (baby steps..).
I can register a Windows class via RegisterClassEx using those strings and icons, but I must use the parent hInst or I get ERROR_CANNOT_FIND_WND_CLASS when calling CreateWindow. I think that's expected.
However, When I try to use that class in CreateWindow, it returns NULL, and so does GetLastError.
I can retrieve the window class of the hInst passed from rundll32 using GetWindowsLong(hWnd, GWL_ATOM). Using that for lpClassName, I can pull up a decorated window minus menus and accelerators, but it's a bit funky, as rundll's window class is normally only used for its message queue. I tried subclassing the window using SetWindowsLong to replace the WndProc and calling CallWindowProc instead of DefWindowProc in my dll's WndProc.
I'm hampered by being unable to debug it in MSVC++ 2010 Express. I replaced the project's command and command arguments with the appropriate entries so it launches it correctly, but it complains about no debugging info for rundll32.exe, and breakpoints etc. don't work.
Any ideas? Am I on the right track?
Sometimes, setup programs shows the Windows file copy dialog, like this one:
This often appears during driver-level application installation, either on Windows XP or Windows 7.
Which API can perform that?
EDIT
Actually, there is no Cancel button at all on the real dialog box.
The Windows API is called SHFileOperation.
Its signature in C# language is
[DllImport("shell32.dll",CharSet = CharSet.Unicode)]
static extern int SHFileOperation([In] ref SHFILEOPSTRUCT lpFileOp);
If you like an example you could look at this page on PInvoke
This instead is the link to the MSDN documentation on SHFileOperation
The Windows API SHFileOperation is declared as follows:
[DllImport("shell32.dll",CharSet = CharSet.Unicode)]
static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
Specifying [In] for ref SHFILEOPSTRUCT lpFileOp prevents receiving the pointer to any remapped files in ref SHFILEOPSTRUCT.hNameMappings when FOF_WANTMAPPINGHANDLE flag is set.
Is there a command I can put into a Windows XP .bat file to bring the command shell to the front?
nircmd will do this, though it involves a little scripting.
nircmd win activate "titleofwindow"
You basically need to know the title of the cmd window you are executing (you can set this via the TITLE command in windows)
thus:
TITLE %SOME_UNIQUE_VALE%
nircmd win activate %SOME_UNIQUE_VALE%
should do the trick.
Note some malware tools make use of the NirCmd executable (it requires no deployment and is very powerful); this may cause you problems.
Another way to get the cmd prompt window to show in front is by ending file1.bat with a command to call a second file2.bat file, followed by an exit command.
EXAMPLE using
file1.bat
....
[your code here]
start C:\file2.bat
exit
This closes file1.bat and opens a second .bat file where you can continue with your code. This second .bat command prompt will open in front of other windows
I had a similar problem and I had to develop a simple C# console application that brings to front a Window. The windows is selected using the window title pass as argument.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
class Program
{
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(String lpClassName, String lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
private static extern bool IsIconic(IntPtr handle);
[DllImport("User32.dll")]
private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
const int SW_RESTORE = 9;
public static void bringToFront(string title)
{
// Get a handle to the Calculator application.
IntPtr handle = FindWindow(null, title);
// Verify that Calculator is a running process.
if (handle == IntPtr.Zero)
{
return;
}
if (IsIconic(handle))
{
ShowWindow(handle, SW_RESTORE);
}
Console.WriteLine("Founded ");
SetForegroundWindow(handle);
}
static void Main(string[] args)
{
if (args.Length > 0)
bringToFront(args[0]);
else
Console.WriteLine("specify program window title");
}
}
}
the code of my batch script is then something similar to
tasklist /FI "IMAGENAME eq program.exe" | find "program.exe"
if errorlevel 1 (program.exe) else (BringToFront.exe "Program Window Title")
From a batch file, no. If you want to activate a window you have to use SetActiveWindow(). If you don't want to get dirty with windows programming but still want to activate windows and simple stuff like that, I highly recommend checking out Autoit. You could always call this program from your batchfile to have it do the task.
CMDOW is also useful for this and for other DOS programming tasks where a little added functionality is needed. Simple to use and well documented. Mind your anti-virus program, though - CMDOW has the ability to hide windows which your anti-virus program will pick up as a possible virus. Just add it to your exception list. CMDOW is completely portable, is definitely NOT a virus and if you have any concerns about it being used by a third party to hide something, simply tuck it away in some non obvious folder somewhere.
Try with focusOn.bat
call focusOn.bat "My Title"
Another quick way to switch to a window by name is via Ctrl+Shift+Esc, which opens Task Manager. Then just type the first few letters of the windows title to select the process, then hit Enter.
When an application crashes on Windows and a debugger such as Visual Studio is installed the following modal dialog appears:
[Title: Microsoft Windows]
X has stopped working
A problem caused the program to stop
working correctly. Windows will close
the program and notify you if a
solution is available.
[Debug][Close Application]
Is there a way to disable this dialog? That is, have the program just crash and burn silently?
My scenario is that I would like to run several automated tests, some of which will crash due to bugs in the application under test. I don't want these dialogs stalling the automation run.
Searching around I think I've located the solution for disabling this on Windows XP, which is nuking this reg key:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
However, that did not work on Windows Vista.
To force Windows Error Reporting (WER) to take a crash dump and close the app, instead of prompting you to debug the program, you can set these registry entries:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]
"ForceQueue"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\Consent]
"DefaultConsent"=dword:00000001
After this is set, when your apps crash, you should see *.hdmp and *.mdmp files in:
%ALLUSERSPROFILE%\Microsoft\Windows\WER\
See here:
http://msdn.microsoft.com/en-us/library/bb513638.aspx
regedit
DWORD HKLM or HKCU\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI = "1"
will make WER silently report. Then you can set
DWORD HKLM or HKCU\Software\Microsoft\Windows\Windows Error Reporting\Disabled = "1"
to stop it from talking to MS.
I'm not sure if this refers to exactly the same dialog but here is an alternative approach from Raymond Chen:
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
I had to disable this for release automation work on Windows 64-bits for Firefox and I did the following:
gpedit.msc
Computer configuration -> Administrative Templates
Windows Components -> Windows Error Reporting
Set "Prevent display of the user interface for critical errors" to Enabled
It is similar what was accomplished for Customer Experience reporting in:
http://www.blogsdna.com/2137/fix-windows-installer-explorer-update-has-stopped-working-in-windows-7.htm
In my context, I only want to suppress the popup for my unit tests and not for the entire system. I've found that a combination of functions are needed in order to suppress these errors, such as catching unhandled exceptions, suppressing run time checks (such as the validity of the stack pointer) and the error mode flags. This is what I've used with some success:
#include <windows.h>
#include <rtcapi.h>
int exception_handler(LPEXCEPTION_POINTERS p)
{
printf("Exception detected during the unit tests!\n");
exit(1);
}
int runtime_check_handler(int errorType, const char *filename, int linenumber, const char *moduleName, const char *format, ...)
{
printf("Error type %d at %s line %d in %s", errorType, filename, linenumber, moduleName);
exit(1);
}
int main()
{
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&exception_handler);
_RTC_SetErrorFunc(&runtime_check_handler);
// Run your tests here
return 0;
}
In WPF application
[DllImport("kernel32.dll", SetLastError = true)]
static extern int SetErrorMode(int wMode);
[DllImport("kernel32.dll")]
static extern FilterDelegate SetUnhandledExceptionFilter(FilterDelegate lpTopLevelExceptionFilter);
public delegate bool FilterDelegate(Exception ex);
public static void DisableChashReport()
{
FilterDelegate fd = delegate(Exception ex)
{
return true;
};
SetUnhandledExceptionFilter(fd);
SetErrorMode(SetErrorMode(0) | 0x0002 );
}
You have to implement an unhandled exception filter which simply quits your application, then set that filter function with SetUnhandledExceptionFilter().
If you're using the secure CRT, you also have to provide your own invalid parameter handler and set this with _set_invalid_parameter_handler().
This blog post has some information too:
http://blog.kalmbachnet.de/?postid=75
During test you can run with a 'debugger' like ADPlus attached which can be configured in many useful ways to collect data (minidumps) on errors and yet prevent the modal dialog problems you state above.
If you want to get some useful information when your app crashes in production you can configure Microsoft Error reporting to get something similar to ADPlus data.
This isn't a direct answer to the question since this is a workaround and the question is about how to disable that feature, but in my case, I'm a user on a server with limited permissions and cannot disable the feature using one of the other answers. So, I needed a workaround. This will likely work for at least some others who end up on this question.
I used autohotkey portable and created a macro that once a minute checks to see if the popup box exists, and if it does, clicks the button to close the program. In my case, that's sufficient, and leaves the feature on for other users. It requires that I start the script when I run the at-risk program, but it works for my needs.
The script is as follows:
sleep_duration = 60000 ; how often to check, in milliseconds.
; 60000 is a full minute
Loop
{
IfWinExist, ahk_class #32770 ; use autohotkey's window spy to confirm that
; ahk_class #32770 is it for you. This seemed to be consistent
; across all errors like this on Windows Server 2008
{
ControlClick, Button2, ahk_class #32770 ; sends the click.
; Button2 is the control name and then the following
; is that window name again
}
Sleep, sleep_duration ; wait for the time set above
}
edit: A quick flag. When other things are up, this seems to attempt to activate controls in the foreground window - it's supposed to send it to the program in the background. If I find a fix, I'll edit this answer to reflect it, but for now, be cautious about using this and trying to do other work on a machine at the same time.
After trying everything else on the internet to get rid of just in time debugger, I found a simple way that actually worked and I hope will help someone else.
Go to Control Panel
Go to Administrative Tools
Go to Services
Look down the list for Machine Debug Manager
Right Click on it and click on Properties
Under the General Tab, look for Start Up Type
Click on Disable.
Click on Apply and OK.
I haven't seen the debugger message since, and my computer is running perfectly.
Instead of changing values in the registry you can completly disable the error reporting on Windows Server 2008 R2, Windows Server 2012 and Windows 8 with: serverWerOptin /disable
https://technet.microsoft.com/en-us/library/hh875648(v=ws.11).aspx