What is the best way to keep a ATL service running - c++

I have created a ATL service and while testing I simply kept it running by leaving a while loop that ran forever (see code below)
HRESULT Run(_In_ int nShowCmd = SW_HIDE)
{
m_running = true;
HANDLE thread = (HANDLE)_beginthreadex(NULL, 0, &MyFunctionToRunInTheService, 0, 0, 0);
while(m_running);
return CAtlServiceModuleT::Run(nShowCmd);
}
Im now ready to actually run it as a real service but am not sure how I go about doing this? I have looked all over the next and dont seem to be able to find one example of a ATL service.
If I remove the thread code and call the method direct the service is constantly in a start status. If i remove the loop the service simply starts and stops straight away. Any sugestions?

Ive fixed the problem by changing the code to
HRESULT Run(_In_ int nShowCmd = SW_HIDE)
{
_beginthreadex(NULL, 0, &CheckForExpiredFiles, 0, 0, 0);
return CAtlServiceModuleT::Run(nShowCmd);
}
I didnt really need the while loop at all. On further investigation the code to keep the service alive comes as standard. The problem was that the PreMessageLoop method in atlbase.h was returning S_FALSE which casued the service to stop. The reason it returned S_FALSE in my case was becuase I had not added any COM objects. I have therefore overridden the PreMessageLoop method to return S_OK in this case.

Well, in my case, add _ATL_NO_COM_SUPPORT macro to C\C++ preprocessor solve the problem.
See more here...

Related

OnInitialUpdate called twice

One of our MFC legacy applications shows a behavior I do not really understand right now. I am not an MFC expert, however. The symptom that I observe and which is causing problems is that OnInitialUpdate of the views is called twice by the framework during app start-up. As I understand the documentation it should be called only once.
My investigation revealed that the app calls the following code in its InitInstance:
CMainFrame *const pMainFrame = new CMainFrame;
if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) { return FALSE; }
m_pMainWnd = pMainFrame;
This causes CFrameWnd::LoadFrame being called inside the framework. From here both calls to OnInitialUpdate originate. The first when Create is called and the second when SendMessageToDescendants is called to send WM_INITIALUPDATE.
Our app overloads CMainFrame::OnCreateClient to create a splitter window:
Splitter.CreateStatic(this, 2, 2);
Splitter.CreateView(0, 0, RUNTIME_CLASS(MyView),CSize(0,0), pContext);
// ...
The call to Splitter.CreateView is what triggers OnInitialUpdate to be called the first time. But as I could see from the documentation this implementation is as intended. So unfortunately this is where I get stuck. I don't understand if the OnInitialUpdate call from SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE) or from CSplitterWnd::CreateView is wrong.
What else could I take a look at to figure out the root cause of this problem?
Is it possible for OnInitialUpdate to be called twice and we need to make sure that our app can cope with this?
If the answer to question 2 is yes: What is the best way to archive this?
EDIT
Further investigation has shown that CSplitterWnd::CreateView only sends WM_INITIALUPDATE if the passed CCreateContext is a nullptr. So I checked CMainFrame::OnCreateClient and it is indeed called by the framework with pContext being nullptr.
EDIT2
As requested in the comments here is the code adding the DocTemplate:
CSingleDocTemplate *const pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMenuDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CMenuView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
There is also a call
Splitter.CreateView(1, 1, RUNTIME_CLASS(CMenuView),CSize(0,0), pContext);
in the CMainFrame::OnCreateClient. If I understand the comments correctly this is wrong?
The two calls of OnInitialUpdate are for the same instances of the views. If I followed the stack trace correctly the reason for the CCreateContext being a nullptr is that no context is passed to LoadFrame. The context passed to CFrameWnd::LoadFrame is just forwarded to CMainFrame::OnCreateClient. But what context should I pass?

COM Call not returning, but possibly crashing?

I have an app that is using COM to talk to another 3rd party application. Most of the time everything works great.
But once in a while the following call to OpenPage() gets some strange behavior. When this happens, the function just breaks. The thread continues, but neither one of the message boxes show up. Nothing is "thrown". And there are no indications that anything is wrong on my side.
The thread continues to run, except from here on out, the CComPtr can never return anymore, but doesn't get hung waiting for the return from the 3rd party.
I know the thread continues because the user can continue to use my app and it calls the various functions associated and is traced.
My question is 2-fold. Why would this be happening? Is it mainly due to something in the third party application?
How can I add some code to diagnose this?
m_spThirtParty is a CComPtr.
LRESULT Open()
{
HRESULT hr;
try
{
hr = m_spThirdParty->OpenPage(&pObj->m_orderNumber);
Trace(hr);
}
catch (...)
{
Error();
MessageBox(NULL, "Fail", "Fail", MB_OK);
}
if(FAILED(hr))
{
MessageBox(NULL, "Returned Fail", MB_OK);
return 0;
}
MessageBox(NULL, "Success", "Success", MB_OK);
return 0;
}
Thanks in Advance!
WhozCraig: Sorry I left some code out. I do check the hr in the try block. But it never gets to that point. When the issue happens, it exits out of the function. – Eric C 12 mins ago
MSalters: That is the issue. I'm not privy to what is happening once I call OpenPage. All I know is after I call it, I get this weird behaviour – Eric C 11 mins ago
thang: Sorry I left out some code to try to be concise. I do check the return of hr and log it in that try block, but it always skips that and exits out of the function with no other actions being taken

Should I call Release on a ID3D10Device interface after using CreateTexture2D? why?

I've this code in a directx10 project.
ID3D10Texture2D *depthStencilBuffer;
UINT a = m_device->Release();
if(FAILED(hr = m_device->CreateTexture2D( &descDepth, NULL, &depthStencilBuffer ))) {
DXGI_D3D10_ErrorExit(hr, L"CreateTexture2D");
return hr;
}
a = m_device->Release();
Now if I stop the debugger at the third line and check the value of a it says 2. And when I stop it at the line after the last one it says 3. I can't understand why. Is the CreateTexture2D function adding references to the ID3D10Device interface? And apparently it's not even adding one reference but two of them since Release() decrements one.
My problem is the documentation for ID3D10Device::CreateTexture2D doesnt specify it adds references to the ID3D10Device object. Same goes for ID3D10Device::CreateRenderTargetView for instance. How am I supposed to guess when to call Release?
I don't have the ability to have the DirectX SDK installed atm to test this, but, in general principals, when it comes to COM you should follow the COM rules and trust that other objects follow the rules too.
i.e. you shouldn't know the implementation of Texture2D but you should trust that if it needs add references to device, that it will also remove them when it is done. You shouldn't be attempting to make additional calls to Release().
Your code should read:
ID3D10Texture2D *depthStencilBuffer = NULL;
if(FAILED(hr = m_device->CreateTexture2D( &descDepth, NULL, &depthStencilBuffer ))) {
DXGI_D3D10_ErrorExit(hr, L"CreateTexture2D");
return hr;
}
depthStencilBuffer->Release();
depthStencilBuffer = NULL;
i.e. you should expect that the call returns a texture2d with a reference count of 1, this is all you need to know. When you're done, you should call release only on the depthStencilBuffer and expect it to clean up itself entirely. If during the implementation the stencil buffer needed references to the device, you should trust that it will also call release on those references correctly.

How to write simple background thread in CWorkerThread

I'm trying to asynchronously run function in my add-on for Internet Explorer (I'm writing BHO in VC++). As suggested here I'm trying to use CWorkerThread.
I've been trying to figure it out for hours but still have no idea how to do it. I don't have much experience in ATL. The lack of a good documentations or tutorials on Internet is killing me.
I'm creating class by Add->Class and choosing ATL Simple Object (that's how you add classed to ATL project right?). But how to implement this IWorkerThreadClient? I thought that choosing Add->Implement Interface in Class View would be good but there is no IWorkerThreadClient on the list.
I think I don't know ATL or COM enaugh but can't find good resource for learning this (esspessialy newest ATL7).
I even tried winapi CreateThread approach but it isn't working. I'm passing this class pointer to run static method but something is corrupting with memory later. Nevertheless if It had worked I still would rather use something else than CreateThread.
Right now I have something like this. In OnDocumentComplete there's RemoveImages(sptmlDoc) and I just want to run it asynchronously.
EDIT: What I did with CreateThread:
I tried running RemoveImages function (from here) asynchronously. I created static function in my class with signature like here. RemoveImages has parameter so I copied it to a member of a class:
if (htmlDoc2 != NULL)
{
m_tmpHtmlDocument2 = htmlDoc2;
m_hThread = CreateThread( NULL, 0, MyThreadFunction, this, 0, &m_threadId);
}
and MyThreadFunction:
static DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
CHelloWorldBHO* myClass = (CHelloWorldBHO*)lpParam;
myClass->RemoveImages(myClass->m_tmpHtmlDocument2);
return 0;
}
I get "Unhandled exception at 0x60c0da05 in iexplore.exe: 0xC0000005: Access violation reading location 0x000001b8." here in the bold line:
void CHelloWorldBHO::DontDisplayElement(CComPtr htmlElement)
{
CComPtr style;
HRESULT hr = htmlElement->get_style(&style);
if (hr == S_OK && style != NULL)
{
static const CComBSTR strNone(L"none");
style->put_display(strNone);
}
}
Your performing a naughty by trying to use a COM handle allocated in 1 thread in another. BHO environment is STA (Single Threaded Apartment) so you should be marshalling the m_tmpHtmlDocument2 object for use in your thread.
Experiance has shown that in some cases IE may let you get away with passing the Browser com object from 1 thread to another and then getting the document and elements afterwards may work. This is entirely unreliable.
Depending on IE 6/7/8 you will have different target threads to execute your actions on, thinking at the levels of per security level/frame/tab/window. basically any time IE creates a new 'Site'
Also to prevent your app from holding the pages active even after navigation away from the page, in FireFox you would use an nsWeakPointer<> , I've never found the equivelant in IE.
Suggestion: Perhaps instead of marshalling com to another thread because your interaction with the page is slow, trying to improve the way you interact with the page and improve performance in process might be a better aim.
Here is an outline using the CThreadPool which will queue up requests, and then execute them when the pool has space.
I use pvWorkerParam to tie the threads back to the site.
I have different types of ActionRequests, you could of course simplify and just pass null for the request.
Note: This doesn't resolve marshalling issues you already have
class ActionRequest{
DontDisplayElement();// define your do stuff in here
};
class ScriptWorker
{
public:
ScriptWorker(void);
virtual ~ScriptWorker(void);
public:
BOOL Initialize(void* pvWorkerParam);
void Execute(ActionRequest *request, void* pvWorkerParam, OVERLAPPED* pOverlapped){
try{
std::auto_ptr<ActionRequest> cleanupRequest(request);
request.DontDisplayElement();
} catch(...) {}
}
void Terminate(void* pvWorkerParam);
private:
boolean m_bCoUninit;
};
Site{
CThreadPool<ScriptWorker> m_scriptWorkerThread;
Site() {
void *pvWorkerParam = this;// or whatever you want to have passed to every script worker and execute in the pool.
m_scriptWorkerThread.Initialize( pvWorkerParam, 1 );
}
OnDocumentComplete() {
m_scriptWorkerThread.QueueRequest( new ActionRequest() );
}
}
and sptmlDoc - is it an IHTMLDocumet* ?
IWorkerThreadClient - never heard of it
"I even tried winapi CreateThread approach but it isn't working. I'm passing this class pointer to run static method but something is corrupting with memomory later"
Keeping it simple is the best design pattern of them all. So stick with CreateThread unless you have good reasons not to. Now, my guess is that the crash occurs because of sptmlDoc being passed to the thread for later processing. The thing is such pointers are only valid from the BeforeNavigate event until DocumentComplete event. Try to do that processing on the spot (inside your event handler) and see if it stil crashes. Some code posting would help too

I need a message pump that doesn't mess up my open window

My application (the bootstrap application for an installer that I'm working on needs to launch some other applications (my installer and third party installers for my installer's prerequisites) and wait for them to complete. In order to allow the GUI to do screen updates while waiting for an app to complete, I put a message pump in the wait loop using the 'MFC-compatible' example in the Visual Studio documentation on idle loop processing as a guideline. My code (which is in a member function of a CWinApp-derived class) is as follows:
if (::CreateProcess(lpAppName, szCmdLineBuffer, NULL, NULL, TRUE, 0, NULL, NULL,
&StartupInfo, &ProcessInfo))
{
::GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);
if (bWait)
while (dwExitCode == STILL_ACTIVE)
{
// In order to allow updates of the GUI to happen while we're waiting for
// the application to finish, we must run a mini message pump here to
// allow messages to go through and get processed. This message pump
// performs much like MFC's main message pump found in CWinThread::Run().
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!PumpMessage())
{
// a termination message (e.g. WM_DESTROY)
// was processed, so we need to stop waiting
dwExitCode = ERROR_CANT_WAIT;
::PostQuitMessage(0);
break;
}
}
// let MFC do its idle processing
LONG nIdle = 0;
while (OnIdle(nIdle++))
;
if (dwExitCode == STILL_ACTIVE) // was a termination message processed?
{
// no; wait for .1 second to see if the application is finished
::WaitForSingleObject(ProcessInfo.hProcess, 100);
::GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);
}
}
::CloseHandle(ProcessInfo.hProcess);
::CloseHandle(ProcessInfo.hThread);
}
else
dwExitCode = ::GetLastError();
The problem that I'm having is that, at some point, this message pump seems to free up window and menu handles on the window that I have open at the time this code is run. I did a walk through in the debugger, and at no time did it ever get into the body of the if (!PumpMessage()) statement, so I don't know what's going on here to cause the window and menu handles to go south. If I don't have the message pump, everything works fine, except that the GUI can't update itself while the wait loop is running.
Does anyone have any ideas as to how to make this work? Alternatively, I'd like to launch a worker thread to launch the second app if bWait is TRUE, but I've never done anything with threads before, so I'll need some advice on how to do it without introducing synchronization issues, etc. (Code examples would be greatly appreciated in either case.)
I've also posted this question on the Microsoft forums, and thanks to the help of one Doug Harris at Microsoft, I found out my problem with my HWND and HMENU values was, indeed due to stale CWwnd* and CMenu* pointers (obtained using GetMenu() and GetDialogItem() calls. Getting the pointers again after launching the second app solved that problem. Also, he pointed me to a web site* that showed a better way of doing my loop using MsgWaitForMultipleObjects() to control it that doesn't involve the busy work of waiting a set amount of time and polling the process for an exit code.
My loop now looks like this:
if (bWait)
{
// In order to allow updates of the GUI to happen while we're
// waiting for the application to finish, we must run a message
// pump here to allow messages to go through and get processed.
LONG nIdleCount = 0;
for (;;)
{
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
PumpMessage();
else //if (!OnIdle(nIdleCount++))
{
nIdleCount = 0;
if (!PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
DWORD nRes = ::MsgWaitForMultipleObjects(1, &ProcessInfo.hProcess,
FALSE, INFINITE, QS_ALLEVENTS);
if (nRes == WAIT_OBJECT_0)
break;
}
}
}
}
::GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);
*That Web site, if you're curious, is: http://members.cox.net/doug_web/threads.htm
I think your problem is in WaitForSingleObject
Looking in MSDN you see this
Use caution when calling the wait functions and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. Two examples of code that indirectly creates windows are DDE and the CoInitialize function. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForSingleObject.
In my code in the message pump use use MsgWaitForMultipleObjects (doc).
With a call this call.
MsgWaitForMultipleObjects(1, &ProcessInfo.hProcess, FALSE, 100, QS_ALLEVENTS);
This should stop your problem with the resources dissapearing.
When you say that window and menu handles seem to be being freed, do you mean that you've got actual HWND and HMENU values that no longer seem to work, or have you got MFC CWnd* and CMenu* variables that fail?
If the latter, the problem is most likely that you're getting the CWnd* pointers by calling CWnd::FromHandle() (or CMenu::FromHandle()) somewhere (or calling something that calls them), and OnIdle() is discarding them.
The underlying reason is that MFC maintains a map from window (or menu, etc.) handles to CWnd* objects in the system. When CWnd::FromHandle() is called, it looks for a match in the map: if one is found, it's returned. If not, a new, temporary CWnd is created, added to the map, and returned. The idea behind OnIdle() is that when it's called all message processing is done, so OnIdle() discards any of these temporary CWnd objects that still exist. That's why the CWnd::FromHandle() documentation warns that the returned pointer may be temporary.
The "correct" solution to this is to not hang onto the CWnd* pointers returned from CWnd::FromHandle(). Given the simplicity of your application, it might be easier to just remove the call OnIdle(): this shouldn't have any negative effects on an installer.
Of course, this is all something of a guess, but it sounds plausible...
There is a Windows function called DisableProcessWindowsGhosting (see http://msdn.microsoft.com/en-us/library/ms648415(v=vs.85).aspx) that prevents Windows from 'ghosting' your window, and continue updating the window (your animation).