Share via

How to implement ICustomGameControllerFactory?

you74674 40 Reputation points
2026-03-24T03:03:46.73+00:00
	internal class Program
	{
		static void Main(string[] args)
		{
			Test().Wait();
		}
		class CustomGameController: IGameController
		{
			public Headset Headset { get; set; }
			public bool IsWireless => true;
			public User User { get; set; }
			public event TypedEventHandler<IGameController, Headset> HeadsetConnected;
			public event TypedEventHandler<IGameController, Headset> HeadsetDisconnected;
			public event TypedEventHandler<IGameController, UserChangedEventArgs> UserChanged;
		}
		class CustomFactory : ICustomGameControllerFactory
		{
			public object CreateGameController(IGameControllerProvider provider)
			{
				Console.WriteLine($"CreateGameController: {provider.HardwareVendorId} {provider.HardwareProductId}");
				return new CustomGameController();
			}
			public void OnGameControllerAdded(IGameController value)
			{
				Console.WriteLine("OnGameControllerAdded");
			}
			public void OnGameControllerRemoved(IGameController value)
			{
				Console.WriteLine("OnGameControllerRemoved");
			}
		}
		async static Task Test()
		{
			var factory = new CustomFactory();
			GameControllerFactoryManager.RegisterCustomFactoryForHardwareId(factory, 0x57e, 0x2006);
			while (true)
			{
				await Task.Delay(100);
			}
		}
	}

I'm trying to implement a ICustomGameControllerFactory and use GameControllerFactoryManager.RegisterCustomFactoryForHardwareId.

After I called GameControllerFactoryManager.RegisterCustomFactoryForHardwareId, CreateGameController is called if I already have the device connected or when I connect a new device. And since OnGameControllerAdded accept IGameController as parameter, I assume I will get the IGameController created by CreateGameController in OnGameControllerAdded, but it never get called. Is it supposed to be called by the system or I should just manually called it in CreateGameController and manage the event and a collection of controllers by myself? If so, how do I detect and fire OnGameControllerRemoved event? Just manually monitor it by DeviceWatcher?

Also, how do I get the id of the device? In CreateGameController, I get a HidGameControllerProvider, but it doesn't provide the id of the device, so I cannot distinguish two controllers with same VendorId and ProductId. It does provide usagePage and usageId, so am I supposed to just manually gather DeviceInformation(either by DeviceInformation.FindAllAsync or use DeviceWatcher) and manually map devices and IGameController?

I know from the document that this api is for OEM, but let's just pretent I'm one. Is this interface supposed to be implemented only in cpp but not in csharp? What am I missing?

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments

Answer accepted by question author
  1. Jack Dang (WICLOUD CORPORATION) 16,115 Reputation points Microsoft External Staff Moderator
    2026-03-24T07:49:46.3733333+00:00

    Hi @you74674 ,

    Thanks for reaching out.

    After you register your factory using GameControllerFactoryManager.RegisterCustomFactoryForHardwareId, the system can call CreateGameController when it detects a matching device, so it makes sense that you’re seeing that part triggered.

    https://dori-uw-1.kuma-moon.com/en-us/uwp/api/windows.gaming.input.custom.gamecontrollerfactorymanager.registercustomfactoryforhardwareid

    The part that’s less clear in the docs is around OnGameControllerAdded and OnGameControllerRemoved. Based on the current documentation and observed behavior, these methods do not appear to be invoked automatically by the platform in this scenario.

    https://dori-uw-1.kuma-moon.com/en-us/uwp/api/windows.gaming.input.custom.icustomgamecontrollerfactory

    Because of that, you may need to maintain your own controller collection and handle add/remove logic on your side based on device enumeration.

    To do that, you could look into using DeviceWatcher, which lets you listen for devices being added or removed: https://dori-uw-1.kuma-moon.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher

    This can help you notice when a device is no longer available, so you can update your controller list accordingly.

    On the device identity side, the provider you get in CreateGameController doesn’t seem to expose a unique ID. If you need to distinguish multiple devices with the same VendorId/ProductId, you may need to pull the Device Id from DeviceInformation and map it yourself: https://dori-uw-1.kuma-moon.com/en-us/uwp/api/windows.devices.enumeration.deviceinformation

    Also, just to clarify on language support, this API under Windows.Gaming.Input does have a C# projection (you can see C# listed in the API page above), so it can be used from C#. The main challenge here is more around lifecycle handling and limited documentation, rather than the language itself.

    Hope this clarifies! If my answer was helpful, I would greatly appreciate it if you could follow the instructions here so others with the same problem can benefit as well.


1 additional answer

Sort by: Most helpful
  1. Q&A Assist
    2026-03-24T03:04:13.38+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    ICustomGameControllerFactory is a low‑level OEM extension point. The behavior in the question aligns with how the API is defined: the platform calls CreateGameController when a matching device is discovered, but the OnGameControllerAdded/OnGameControllerRemoved methods are not controller‑lifecycle events raised by the system.

    From the API definitions:

    • ICustomGameControllerFactory is just an interface that represents a factory for creating a custom controller type.
    • CreateGameController(IGameControllerProvider provider) is the method the system uses to create an instance of the controller for a given provider.
    • OnGameControllerAdded(IGameController value) and OnGameControllerRemoved(IGameController value) are described as “Event raised when the controller is added/removed”, but there is no additional contract text in the documentation that says the system will automatically call them for you.

    The documented system integration points for custom controllers are the static registration methods on GameControllerFactoryManager:

    • GameControllerFactoryManager.RegisterCustomFactoryForHardwareId(ICustomGameControllerFactory factory, ushort hardwareVendorId, ushort hardwareProductId)
    • GameControllerFactoryManager.RegisterCustomFactoryForGipInterface(ICustomGameControllerFactory factory, Guid interfaceId)

    These methods register the factory so that the platform can:

    1. Match devices by hardware vendor/product ID or GIP interface ID.
    2. Call CreateGameController on the factory when a matching device is present.

    The other key integration point is GameControllerFactoryManager.TryGetFactoryControllerFromGameController(ICustomGameControllerFactory factory, IGameController gameController), which is used to obtain a controller instance of a particular factory type for an existing underlying device. The remarks explicitly state that this is how FromGameController methods are implemented for built‑in controller types, and that custom controller classes must inherit from IGameController.

    From this, the supported pattern is:

    • Implement a controller class that implements IGameController.
    • Implement ICustomGameControllerFactory for that controller type.
    • Register the factory with GameControllerFactoryManager.RegisterCustomFactoryForHardwareId or RegisterCustomFactoryForGipInterface.
    • Let the system call CreateGameController when it discovers a matching device.
    • Use GameControllerFactoryManager.TryGetFactoryControllerFromGameController to obtain the correct representation of a device when starting from another IGameController instance.

    The documentation does not describe any system behavior that would:

    • Automatically call OnGameControllerAdded or OnGameControllerRemoved.
    • Provide a device‑unique identifier through IGameControllerProvider beyond the vendor/product and related information.

    Because there is no documented system contract for those two methods beyond their signatures, any additional lifecycle tracking (such as maintaining a collection of controllers, raising higher‑level events, or mapping to device IDs) must be implemented in the app or OEM layer on top of the provided APIs. The documentation also does not describe a built‑in mechanism for obtaining a unique per‑device ID from IGameControllerProvider or for mapping multiple identical devices; any such mapping would need to be implemented externally (for example, by correlating with other device‑enumeration APIs), but those details are not covered in the provided context.

    For headset tracking specifically, the documented pattern is to use the IGameController.Headset property and the HeadsetConnected/HeadsetDisconnected events on IGameController implementations. The system raises those events when a headset is connected or disconnected to a controller, and the app can register handlers to enable or disable capture/playback accordingly.


    References:

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.