Do I have to close HINTERNET on exit? - exit

Do I have to close HINTERNET handles from (wininet.h), before exiting my application?

Related

Can I manually invoke processing of window messages in the main thread in a win32 application?

I have a Win32 MFC application that does some processing in a loop. Currently the window stops redrawing while the loop is running. Can I somehow allocate time to the message queue inside my loop or will I have to move the processing to a different thread to free up the main thread for message handling?
You can use the following code snippet to process messages:
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (::GetMessage(&msg, NULL, 0, 0))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
But it is always better to have separate thread for long operations to prevent blocking of main app thread.

How to terminate a program started with ShellExecute

In MFC, I am using this code
ShellExecute(NULL, _T("open"), _T(EXTERNAL_APP), params,
_T(EXTERNAL_PATH), SW_HIDE);
to start an external program which runs in the background.
However when my app is terminated , this program is still running, as can be verified by inspecting the Windows Task Manager pane.
So my question is, how can I make the external program stop when my app stops ?
Try ShellExecuteEx instead, which can return a HANDLE hProcess of the newly-started process.
When/if you have a HANDLE hProcess then I expect you can pass it as a parameter it to the TerminateProcess function: which you would call (to terminate the child process) before your application stops.

DLL crashes app after reuse

I use an application that uses mdi and a script can be attached to, and detached from, a mdi window to be run/stopped on demand; this script loads my dll that does some work; it does fine so; however, when I detach the script still all is fine and the application should unload the dll (and it calls dllmain with the appropriate thread_attach/detach and process_attach/detach operations). Now if I try to re-attach the script to the winow, or to attach it to another window, after the dll has been in use once - the main application crashes. I have isloated the problem to a thread that is created by the dll; the tread crates a window; so, I create the thread like so:
if (!hThread) hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
and, when the script is detached it shuts down the thread like so (no matter if the commented-out lines are uncommented-out):
SendMessage(hWnd, WM_DESTROY, 0, 0);
//TerminateThread(hThread, 0);
//WaitForSingleObject(hWndThread, INFINITE);
CloseHandle(hThread);
hThread = NULL;
I'm at a loss here as to why the main app crashes. A different thread (i.e. one that would simply sleep for a second and loop, will do no harm. What gives?
Ok, here are some ideas:
You said your thread opens a window. Do you run a message loop in the thread function, or you expect your window to be serviced by some other message loop?
If you are running your own message loop in the thread, then exiting the loop may or may not happen, depending on how you have written it. If you use something like:
while(GetMessage(&msg, ...) // msg loop in the thread function
{
....
}
DestroyWindow(hWnd); // see comment below
then this requires a WM_QUIT and not WM_DESTROY to exit. Anyway, the best is to send your window a WM_QUIT and after exiting the message loop then call DestroyWindow() to destroy it properly.
Quoting from MSDN:
DestroyWindow function
Destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain
After posting WM_QUIT message to your window, your main thread should wait for the window thread to exit. Here is some relevant code:
SendMessage(hWnd, WM_QUIT, 0, 0); // send your quit message to exit the msg loop
if (WaitForSingleObject(hThread, 5000) != WAIT_OBJECT_0) // wait up to 5 seconds
{
TerminateThread(hThread, -1); // bad! try to never end here
}
I hope this helps. I use this in a threaded log viewer that uses a window to display log messages.

how to terminate a process created by CreateProcess()?

I have created a process using CreateProcess(). This is the code:
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
result = CreateProcess("C:\\AP\\DatabaseBase\\dbntsrv.exe", NULL, NULL, NULL, FALSE, 0, NULL, "C:\\ADP\\SQLBase", &si, &pi)
How can I get the Handle and processId of this specific process? And eventually use it to close this process?
Thank You.
In the struct pi you get:
typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;
The first parameter is the handle to the process.
You can use that handle to end the process:
BOOL WINAPI TerminateProcess(
__in HANDLE hProcess,
__in UINT uExitCode
);
hProcess [in]
A handle to the process to be terminated.
The handle must have the PROCESS_TERMINATE access right. For more information, see Process Security and Access Rights.
uExitCode [in]
The exit code to be used by the process and threads terminated as a result of this call. Use the GetExitCodeProcess function to retrieve a process's exit value. Use the GetExitCodeThread function to retrieve a thread's exit value.
A handle to the process is returned in the PROCESS_INFORMATION structure, pi variable.
The TerminateProcess() function can be used to terminate the process. However, you should consider why you need to kill the process and why a graceful shutdown is not possible.
Note you need to set the cb member of si before calling CreateProcess():
si.cb = sizeof(STARTUPINFO);
EDIT:
To suppress the console window specify CREATE_NO_WINDOW, as the creation flag (the sixth argument) in the CreateProcess() call.
EDIT (2):
To suppress the window try setting following members of STARTUPINFO structure prior to calling CreateProcess():
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = FALSE;
Closing the process cleanly
To close the process cleanly, you should send a close signal first:
How To Terminate an Application "Cleanly" in Win32.
If you absolutely must shut down a process, follow these steps:
Post a WM_CLOSE to all Top-Level windows owned by the process that you want to shut down. Many Windows applications respond to this message by shutting down.
NOTE: A console application's response to WM_CLOSE depends on whether or not it has installed a control handler.
Use EnumWindows() to find the handles to your target windows. In your callback function, check to see if the windows' process ID matches the process you want to shut down. You can do this by calling GetWindowThreadProcessId(). Once you have established a match, use PostMessage() or SendMessageTimeout() to post the WM_CLOSE message to the window.
Use WaitForSingleObject() to wait for the handle of the process. Make sure you wait with a timeout value, because there are many situations in which the WM_CLOSE will not shut down the application. Remember to make the timeout long enough (either with WaitForSingleObject(), or with SendMessageTimeout()) so that a user can respond to any dialog boxes that were created in response to the WM_CLOSE message.
If the return value is WAIT_OBJECT_0, then the application closed itself down cleanly. If the return value is WAIT_TIMEOUT, then you must use TerminateProcess() to shutdown the application.
NOTE: If you are getting a return value from WaitForSingleObject() other then WAIT_OBJECT_0 or WAIT_TIMEOUT, use GetLastError() to determine the cause.
By following these steps, you give the application the best possible chance to shutdown cleanly (aside from IPC or user-intervention).
See this answer for code.
Terminating the process
If you don't care about clean shutdown, you can use TerminateProcess(). However, it is important to note that TerminateProcess() is asynchronous; it initiates termination and returns immediately. If you have to be sure the process has terminated, call the WaitForSingleObject() function with a handle to the process.
Note: Access rights PROCESS_TERMINATE and SYNCHRONIZE are required.
TerminateProcess(pi.hProcess, 0);
// 500 ms timeout; use INFINITE for no timeout
const DWORD result = WaitForSingleObject(pi.hProcess, 500);
if (result == WAIT_OBJECT_0) {
// Success
}
else {
// Timed out or an error occurred
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
Not closing, just wait until finished
If the process will finish on its own, instead of terminating you can wait until it has finished.
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
This is explained thoroughly in MSDN:
If result is non-zero (which means that it succeeded) you will get the handle and processid in the pi structure.
In order to kill the process you can use TerminateProcess

prevent command line from opening on _popen

I'm opening a process in C++ like so
FILE* pipe = _popen(ss.str().c_str(), "r");
This create a cmd window which goes to the forefront of the desktop. I want to prevent the cmd window from opening, and if I can't, a way to keep it minimized.
Tried solutions:
HWND hWnd = GetConsoleWindow();
ShowWindow(hWnd, SW_HIDE);
But that only works if you are calling that function in the process that holds the cmd window.
Instead of using _popen, use CreateProcess and the CREATE_NO_WINDOW flag.