On the MCU side, the DFU almost the simplest thing to implement (as simple as usb gets), just control transfers and that's it. So it's a good choice for built-in roms, failsafe recovery (debricking) interfaces etc, I've used it a lot for those; for those use cases, the multi-platform compatibility and driver signing is not an issue anymore. Also having a standard dfu-util helps, I don't need write yet another tool.
For customer-used update, the device should implement something device-specific usually anyway inside the normal communication flow the device uses - typically the fw update shall be buffered into local storage and uses encrypted images etc. Once the device has received the update, it will boot into bootloader and then do the update locally.
Sadly, the non-class driver USB in Windows is hard; there is no good generic and simple libusb-like functionality. It is possible to use Microsoft os descriptors and WinUSB, but that is almost as bad as rolling out real driver. You can't just enumerate using vid/pid without having a driver installed - the winusb insists on providing a GUID (ie using the descriptor) for the application to find the device... There's even a in-browser webusb for web-based usb device control apps, but that's no good until Windows doesn't support simple direct access.
At least, they provided serial port class driver in win10, so no more usbser.sys inf files... That works actually quite well, better than in some older windows version.