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
Related
Operating Environment: Windows 7, Visual Studio 2010, CLR GUI.
So I've been given the unglorious task of enhancing a GUI application that is started from a command prompt. Because it is. Because poor design decisions by previous implementers. Anyway, it launches one of several GUIs depending upon the input arguments.
I'd like to be able to print back to the same command prompt window if (when) the user types something that the code doesn't understand.
Here's what I've tried (none of which output anything):
int main( array<System::String^>^ args )
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
OutputDebugString("hello");
Trace::WriteLine("hello");
Debug::Trace::WriteLine("hello");
Console::WriteLine("hello");
std::cout << "hello";
printf("hello");
return 0;
}
Thanks in advance!
Update: I don't want to use AllocConsole(), as that opens a new console that disappears along with all of the data when the application exits. Similarly, a pop-up message box won't work. I'm looking for a way to make the output persistent.
The only way I can get output from the application to date is via a message box (non-persistent) or opening a new console that disappears when the application exits (via AllocConsole() ). And I'm running from a command prompt, not the debugger's "Play" button.
Update
Why the down-vote for not doing research? I spent a day trying to solve this, looking through dozens of posts trying to find a solution, and to date I've found others looking for the same answer, but not finding it. AllocConsole() or changing the project type is always the solution, but neither is a solution for me.
Update
I added the "full code", which is the 2 statements. THAT IS ALL THE CODE. So simple. I'm skipping the start of the GUI because I don't care about that right now, I just want it to print back to the console where the application was started. The most basic HelloWorld. If there are project settings I need to post, I don't know which ones would be relevant. This is where I want to print to the console, before the GUI is ever up. I can't show the GUI if there is an error in the user input.
Right click on the project, select Properties
Under Linker -> System, Change Subsystem from Windows to Console.
A Windows subsystem application cannot write to console, but by changing the subsystem to Console (which can write to the calling console), the Form part of the application can still work (tested in Visual Studio 2010).
Solved! See [SOLUTION]
Thanks for any help you can provide. It's much appreciated!
In a nutshell: I'm trying to send Ctrl+V to SSMS 2012 with SendKeys.Send("^{v}"), but it doesn't work. It's working fine with Notepad, UltraEdit, Word, Excel, Chrome, you name it. It even works in Microsoft Visual Studio 2010.
In details: I have an application that runs in the background. Using a keyboard shortcut, this application displays a popup window with options. Depending on the option I choose it saves what's related to it into the clipboard. I then close that popup window, get the new foreground window (which should be the one I had before displaying the popup) and try to paste what's in my clipboard with SendKeys.
It works with pretty much every application I try it with, except SSMS
If I manually press Ctrl+V it pastes what I have in my clipboard (text usually)
I've added some code to display the title of the window I got with the GetForegroundWindow and it does give me the correct SSMS window
What's sad about all this is that once in a while (very rarely), the text is correctly pasted in SSMS, but it doesn't work the second after.
I never get the MessageBox saying the SetForegroundWindow failed.
If I replace the single SendKey with 3 SendKeys to send "A", "B" and "C", B and C are sent but not A. Yes I've tried using a sleep thinking it needed time to write the first SendKey, but that didn't change anything.
I did try SendKeys.SendWait instead, but didn't get different results.
Here's the code from the moment I close the popup
this.Close();
IntPtr handle = GetForegroundWindow();
if (!handle.Equals(IntPtr.Zero))
{
if (SetForegroundWindow(handle))
{
//Optionnal just to show the window title
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
if (GetWindowText(handle, Buff, nChars) > 0)
{
MessageBox.Show(Buff.ToString());
}
//[SOLUTION] Sending a useless key seems to solve my SSMS problem without affecting the other applications.
SendKeys.Send("{F14}");
//Sending Ctrl+V
SendKeys.Send("^{v}");
}
else
{
MessageBox.Show("SetForegroundWindow failed");
}
}
Hope someone can help.
Thanks in advance!
See http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.aspx
...
The SendKeys class is susceptible to timing issues, which some developers have had to work around. The updated implementation is still susceptible to timing issues, but is slightly faster and may require changes to the workarounds. The SendKeys class tries to use the previous implementation first, and if that fails, uses the new implementation. As a result, the SendKeys class may behave differently on different operating systems. Additionally, when the SendKeys class uses the new implementation, the SendWait method will not wait for messages to be processed when they are sent to another process.
...
This problem I am having is very easy to reproduce. Create a basic MFC MDI application with file extension as .xyz using Visual Studio 2010. The application default code readily registers the file associations via calls:
// Enable DDE Execute open
EnableShellOpen();
RegisterShellFileTypes(TRUE);
The problem is that inside RegisterShellFileTypes(TRUE), the call below fails:
if (!_AfxSetRegKey(strFileTypeId, strFileTypeName))
continue; // just skip it
The file is obviously not being registered and it doesn't adopt the application assigned file icon. All I want is when I double click the registered file type (in this case .xyz) it should open in the application but it doesn't. What is possibly missing..how to make this work?
Microsoft has changed their concept of registering an extension over the years. Starting with Vista, it's expected that the extension will be registered at installation time with a Setup application which will have Admin privileges. The registry keys necessary to map an extension to an application are now in a protected area of the registry. What you're asking for is no longer possible.
You need administrator privileges to accomplish this. Usually, you should let your installer register your files. However, it can be done if you explicitly elevate (and re-run) your process before your file types are registered:
// In your InitInstance, do the following:
OSVERSIONINFOEX osvi;
osvi.dwOSVersionInfoSize = sizeof OSVERSIONINFOEX;
GetVersionEx((OSVERSIONINFO*)&osvi);
if (osvi.dwMajorVersion >= 6) // XP or Vista/elevated?
{
TCHAR exePath[MAX_PATH];
GetModuleFileName(NULL, exePath, MAX_PATH);
ShellExecute(NULL, _T("runas"), exePath, NULL, NULL, SW_SHOWNORMAL);
return FALSE;
}
As Parapura Rajkumar mentioned, if you put this code in your init instance:
// Enable DDE Execute open
EnableShellOpen();
RegisterShellFileTypes(TRUE);
The application should run at least one time as admin (right click and run as administrator) to register file types in windows registry.
I'm using WinLIRC with IR receiver connected to serial port COM1 on Windows 7 x64. WinLIRC is added to Startup folder (Start->All applications->Startup) so it starts every time I log in. Very often (but not all the time) I see initialization error messages from WinLIRC, which continue for some time (couple of minutes) if I retry initialization, and after some retries it initializes correctly and works fine. If I remove it from Startup and start manually at any other moment it starts without errors.
I've downloaded WinLIRC sources and added MessageBox calls here and there so I can see what happens during initialization and found out that CreateFile call fails:
if((hPort=CreateFile(
settings.port,GENERIC_READ | GENERIC_WRITE,
0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0))==INVALID_HANDLE_VALUE)
{
char buffer[256];
sprintf_s(buffer, "CreateFile(%s) failed with %d", settings.port, GetLastError());
MessageBox(NULL, buffer, "debug", MB_OK);
hPort=NULL;
return false;
}
I see message box saying "CreateFile(COM1) failed with 5", and 5 is an error code for "Access denied" error according to this link.
So the question is why opening COM-port can fail with such error right after booting Windows and proceed normally few seconds or minutes later?
Update: the COM-port is the real one.
Update2: regarding the other application that opens serial port before WinLIRC. I did the following: I put Process Explorer to the Startup folder so it start on log in also, then rebooted. As soon as process explorer started I ran "Find Handle or Dll" dialog, put "Serial0" to the input and hit "Search". By that moment WinLIRC had already shown message box saying "CreateFile(COM1) failed with 5". Then I waited till the process explorer search ends, seen that it found nothing, then tried to reinitialize WinLIRC and it failed again. So I suggest that it is not the case of serial port being opened by other application. If anyone can suggest a better way to check it, I'll happily recheck.
When I search for "Serial0" in process explorer while WinLIRC is running it finds the winlirc.exe process, so it looks like it is correct term to search.
Update3: regarding the serial mouse driver. It is not listed in device manager, so I wasn't able to disable it there, however I have found this instructions on how to disable sermouse service and it didn't help.
Update4: one more thing I forgot to mention. It happens only if I log in soon after booting PC. If I leave windows on log in screen for several minutes and log in later, then WinLIRC initializes without any problems always.
Update5: Unfortunately, I don't have access to the computer that had this problem reproducing, so I can't experiment anymore.
It takes time to initialize the port.
Your application will run absolutely fine on windows XP.
Windows7's serial ports are virtual.
You can run a small code and check it out
using System.IO.Ports;
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = System.IO.Ports.SerialPort.GetPortNames();
comboBox1.Items.Add("None");
foreach (string port in ports)
comboBox1.Items.Add(port);
comboBox1.SelectedIndex = 0;
}
This will return you the list of serial port. Check the status of it and display it on message box.
Make this code and run at startup. You'll get the root cause.
Here some links one has to visit before plunging into the magic world of serial programming in Windows :)
A detailed explanation of serial programming in Windows:
http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c5425/Serial-Communication-in-Windows.htm
a little bit outdated (the site states 1999-2003 so yes, it's outdated) but absolutely useful:
http://www.flounder.com/serial.htm
The ShellExecuteEx Win32 function call has a flag SEE_MASK_FLAG_NO_UI in its SHELLEXECUTEINFO structure, which should suppress any error dialogs which could be displayed because of an error when launching an application.
The MSDN documentation here is quite explicit about it:
SEE_MASK_FLAG_NO_UI
0x00000400. Do not display an error message box if an error occurs.
In my case, I am launching a .NET executable on a Windows XP system where no .NET is installed. I systematically receive the following message, displayed by Windows in a dialog window:
Xxx.exe - Application Error
The application failed to initialize properly (0xc0000135).
Click on OK to terminate the application.
[ OK ]
I don't want the user to have to deal with this message. I'd rather get back an error code from ShellExecuteEx and be able to handle it gracefully in my program. Here is the code snippet which I am using to start the external executable:
#include <windows.h>
int wmain(int argc, wchar_t* argv[])
{
SHELLEXECUTEINFO info;
memset(&info, 0, sizeof(SHELLEXECUTEINFO));
info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_FLAG_NO_UI;
info.lpVerb = L"open";
info.lpFile = L"Xxx.exe";
info.nShow = SW_SHOW;
return ShellExecuteEx (&info);
}
Is there an official way of suppressing the error message if .NET is not present on the system? Or do I have to check for this specific condition myself before executing the application (but I do not know in advance if it is a .NET app or a native app). And what if the app I am starting is missing some DLLs, for instance?
The flag only tells the shell to not display an error message. It doesn't affect the UI of the process that got started. The .NET .exe really did get started so ShellExecuteEx() did it's job and saw no errors. That it decided to bomb afterwards and let the user know about it is not something you can easily fix.
why don't you use the CreateProcess function