C++/WinRT GetGattServicesAsync() not responding in MFC app - c++

C++, WinRT, VS2017 MFC, Win10
I have a C++/WinRT VS2017 console app as a test platform to find my Bluetooth LE device, enumerate the services and characteristics, and then write a value to the Tx characteristic, etc. I have all of that working and now I am trying to move that code to an existing VS2017 MFC app.
In the console app the BluetoothLEAdvertisementWatcher and callback to the watcher.Received() were done in the main.cpp. Once my BLE device was found, a separate function was called to create the device object from the deviceAddress and then enumerate the services and characteristics.
In the MFC app I created a separate function run in a separate thread to establish the watcher and attach the callback. That all works fine up to the point that it needs to GetGattServicesAsync(). In the console app the function OpenDevice() used to create the device object and get the services was done with a get() as in:
OpenDevice(deviceAddress).get();
The first thing OpenDevice() does is create the device object using
auto device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(deviceAddress);
If the device object is created, then the next thing it did was get the Services with:
auto services = co_await device.GetGattServicesAsync();
Here is where my MFC code fails. In the function thread that creates the watcher and watcher.Received callback my MFC code does the same call to OpenDevice(). In OpenDevice the device object is indeed created but then the call to GetGattServicesAsync() will never finish so matter how long I wait. If I enter the GetGattServicesAsync() in Debug mode, however, then it works fine.
For testing I have also put the OpenDevice() code within the watcher thread but, again, it stalls on GetGattServicesAsync().
In this case, however, I cannot use the co_await but had to use
auto services = device.GetGattServicesAsync().get();
Regardless, the GetGattServicesAsync() never finished.
Any suggestions of what I need to do or what I am doing wrong?

Since running in Debug was working I was trying to solve why this was not working in Release mode. I was relying on my log file entries to track the progress after the fact. For the halibut I put in some Beeps() to let me hear the progress and I was hearing beeps but not seeing log entries after that GetGattServicesAsync(). Apparently what was happening is that, for what ever reason, the GetGattServicesAsync() was NULLing out the handle to my log file so no writes were taking place. I did a check for NULL after the GetGattServicesAsync() and, if it was, re-established the log file. All of a sudden my log file was showing the progress that I thought was not happening. Sometime I think it is just me...:-(

Related

Can an application run the code of another application?

Hi,
I'm relatively new to C++ and WinAPI. So far I've managed to create an application, that is using the CreateProcess function and a STARTUPINFO structure to create a new desktop, launch inside that new desktop a new explorer.exe process and switch to it.
Next, because I wanted to be able to switch at any time between these two desktops, at a press of a key (LCTRL in my case), I've made another application that uses the SetWindowsHookEx function to create a global hook for the keyboard.
Because the hook is active only in the calling destkop, in the first app, using CreateProcess, before creating the explorer.exe process and switching to the new desktop, i've launched the executable of the second app twice: once in the current desktop and once in the new one.
Everything is working fine, I'm able to make the switch between desktops at any time, but now I've been asked to do something about the structure of the processes launched, somehow, to make the seconds app code run inside the first one, without creating a new process. Because this is my first post, I can't upload a snippet of the process tree, but the procexp application from live.systernals is showing the following structure:
---FirstApp.exe:
-------------SecondApp.exe (original desktop)
-------------explorer.exe (new desktop)
-------------SecondApp.exe (new desktop)
So basically, my question is: can I make the code of the application that hooks the keyboard run in the same thread as the FirstApp? This implementation, an app that starts these three processes, and the second app that hooks the keyboard, was my idea (I was not requested to do it this way, I was only asked to create a new desktop and switch between them), so I am open to suggestions towards making a better implementation for this problem too.
It could be possible since there is little difference between a DLL and an EXE on Windows, so I think you could try to export the routines from SecondApp and then import them in FirstApp with LoadLibrary.
But IMHO the clean way to do that is to break SecondApp in two pieces : a DLL containing code that actually does the job and an EXE that would be a simple frontend calling routines from the DLL.
That way, it will be trivial (and portable across different versions of Windows and SDK) to call the routines of the DLL from FirstApp.

Intercept signal / event when 'Stop Debugging' button is pressed in Visual Studio

Background: I am writing a QA automation platform for an API which outputs formatted results to a specified directory. In addition, I have developed a GUI application for analyzing these results. A user may run the second application trying to analyze test results while our automated build system is running the first application modifying / generating new test data. To avoid thrashing, I have each application acquire file locks when making modifications, and releasing them when they are done. Upon normal program termination, if the running application has acquired a lock on the data directory it is released.
Problem: I need to be able to release the aforementioned file locks when either tool exists prematurely (user pressing CTRL-C, user stopping the application in debugger, or due to buggy API / application logic being tested). To handle this, I have implemented a signal handler using sigaction which handles intercepting fatal signals (tested and working), and have implemented a ctrl-c handler via the Win32 function SetConsoleCtrlHandler. However, I cannot seem to find a way to intercept the event of a user pressing the Stop Debugging button in Visual Studio. I assume this event generates something like SIGKILL / SIGSTOP (which cannot be handled through sigaction) but I would also hope there is some std library or Win32 functionality to intercept this event and perform some cleanup. Do you guys know of a way to handle this event or even what exactly this button does to kill a running application?
If you're using boost, you can use boost::interprocess::windows_shared_memory.
It is guaranteed to be released when the process ends.
Boost is just a neat wrapper around the windows API in this case. It wraps the Windows Named Shared Memory API.

Why wont my windows service write to a file continuously?

I have created a windows service that checks installed printers and updates a file currently located at "C:\App\Data\info" (no file extension) Very simple, all it does is call EnumPrinters with the correct flags and dumps PRINTER_INFO_2 to a file.
Everything works exactly as expected in Visual Studio 2010, in the "testing" project leading me to believe the issue is not in my service. As soon as I install this as a windows service it stops looping. It will run through the loop once and never again.
Code Reference:
I am using the template from here: http://www.kencotutorials.com/WindowsService.aspx
and have only changed the service class file.
Initial thoughts are either security permissions or the wait function not returning.
Edit: I have already checked the whole file system to see if its being written elsewhere and confirmed that it is not.
This is the service loop function that is called by the template.
void CMyService::MyServiceLoop(void)
{
CheckPrinters(); // updates a PRINTER_INFO_2 struct with all installed printers
WritePrinterFile(); // writes the file (i know there's no issue with the actual writing)
Sleep(10000);
OutputDebugString("Done sleeping");
Return;
}
I have added OutputDebugString("Shell loop entered") at the start of the shell app loop.
I have also added OutputDebugString("Waiting for object") in front of the call to WaitForSingleObject()
The loop seems to hang on the WaitForSingleObject. Last message in DbgView is "Waiting for object".
Could be a lot of reasons. I'd recommend you add some OutputDebugString() calls (Win32 API function) and get DbgView.exe from Microsoft to see what is going on. Also, doesn't sound like you are doing this, but make sure you aren't writing to a mapped drive or network location, since your service most likely doesn't have access to those.
When you set up your Windows Service, did you specify an account on the Log On tab?
http://www.coretechnologies.com/WindowsServices/FAQ.html#AppNotWorkingFromService
The default Local System account almost surely doesn't have the rights to use the printers so be sure to set an account that can access the printers normally.

Windows Shell Extension Not Calling Initialize

I was hoping somebody here had some insight into what could be causing this problem. I've implemented several COM extensions for Explorer that provide ShellIconOverlays and a ContextMenu, and the overlays work perfectly. The Context Menu works fine when I click on the desktop but when I right click in any explorer instance, I can see the interface being queried in the debugger and an instance of IShellExtInit being generated but the initialize function doesn't get called in the explorer instances, but it is called fine from the desktop and a ContextMenu item is queried immediately after.
Has anybody here seen anything like this before?
If you're debugging a shell extension, chances are that you've had occasions to terminate the running explorer.exe process and start a new one. When you started a new one, was it running with the same integrity level as the original?
Do your Explorer settings say to browse files in a new process? If so, is that process running with the same integrity level as the original?
Also, since you're running a debugger, chances are that you built a debug build. Does explorer.exe sometimes try to load the debug build of your DLL and sometimes try to load the release build of your DLL?
OK, I run into the exact same problem here, and it turns out that the issue has to do with
ThreadingModel = Apartment
Basically, what I think you are experiencing, is that the second thread of explorer.exe (desktop runs in STA thread) uses the default (legacy) ThreadingModel - and expects your COM to implement IMarshal to do IPC. Apartment ThreadingModel allows multiple instances of your IShellExt class to co-exist.
Caveat - If you are using ActiveQt to develop Context Menu Shell Extensions, there are few more tricks to use.

Detecting multiple launches of a Windows application

What's the approved way to handle second, third, etc launches of application in Windows (C++) application? I need the running (first) instance to take some special action (pop up a dialog) in this case, but for the secondary instances to terminate.
On Mac, AppleEvents sends you a 're-open' message in this scenario. Mozilla on Windows uses DDE to check for an existing instance and pass the command line through. It feels like a pretty nasty solution, all the same.
The windows way is to open a named mutex and, if you can acquire it, it means you're the first instance, if not, there is another one. At this point you can register a windows message (the function is literally RegisterWindowsMessage) which gives you a WM_ msg you can send to all windows and only your app would know to catch it, which allows you to tell your initial copy to open a dialog box or w/e.
How to limit 32-bit applications to one instance in Visual C++
"The method that is used in this article is the one that is described in MSDN under the WinMain topic. It uses the CreateMutex function to create a named mutex that can be checked across processes. Instead of duplicating the same code for every application that you will use as a single instance, the code that you must have is in a C++ wrapper class that you can reuse across each application."
SendMessage Function
"Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message."
"Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication."
RegisterWindowMessage
"The RegisterWindowMessage function defines a new window message that is guaranteed to be unique throughout the system. The message value can be used when sending or posting messages."
On windows there is not really solution for that at least not out of the box.
You can use mutex to do such things, basically the app check for the mutex at startup create it if it doesn't exist.
There is one issue with CreateMutex method that you might need to consider - the named mutex might have been created by a third party. Now, most of the time, this won't be an issue, there would be no reason for someone else to block your application. However, if you're making a program that does something important, it may be an issue. Consider, if your program was a virus scanner, a virus could disable it by creating the mutex.
Usually, CreateMutex should do the job, but you should be aware of the limits of this method.