It's no secret that I've always been a huge fan of Windows Media Center, probably the best digital/personal video recorder out there and definitely one of the most impressive Microsoft applications developed using the .NET Framework.
As an avid WMC user, I have built 3 HTPC machines and recorded thousands of TV programs (movies, series, documentaries, etc.). As such, when Microsoft announced in May 2015 that Windows Media Center would no longer be developed (almost 6 year after disbanding the development team!) – and thus would not be part of Windows 10 – I refused to migrate to Windows 10, despite Microsoft's offers encouraging users to upgrade their OS for free.
While investigating, I discovered that the issue was caused by a change in MSVidCtl.dll, the system-wide DLL containing the DirectShow components needed by WMC for all its TV-related features. After replacing the faulty DLL by an older version, WMC was able to play old recordings like a charm.
This phenomenom, that occurs every time API or functional changes are introduced in a DLL a program depends on, has a name: DLL Hell.
You shall not replace system DLLs
The thing is, replacing a system-owned DLL is far from ideal: while it solves the initial problem quite easily, it's not future-proof as any major Windows update will end up overwriting the replaced DLL. The same thing will happen if the user (or the system on his behalf) runs the sfc.exe utility, that will detect the modification and revert it. It may also cause issues in other applications depending on new APIs that are only part of the newest version of the replaced DLL.
Since replacing a system DLL was not a good option, I eventually opted for the other approach: forcing Windows Media Center to load its own version of MSVidCtl.dll instead of the global one stored in System32.
Typically, you'd achieve that by simply dropping the DLL in the application's root folder (in our case, C:\Windows\ehome). This usually works because the DLL loader first looks for the DLL in the directory the application was loaded from.
Enter the marvelous world of COM
In this case, this didn't work: Windows Media Center kept loading the MSVidCtl DLL contained in the System32 folder. Why? Because MSVidCtl.dll is actually a very special DLL: it's a Component Object Model DLL. Unlike other DLLs, COM DLLs are almost never loaded via LoadLibrary (at least, not directly): instead, they are assigned a GUID that corresponds to a special entry in the registry that contains the absolute path of the COM DLL. When an application wants to instantiate a COM component, it usually imports Ole32.dll and calls CoCreateInstance with the unique GUID: the COM loader locates the entry in the registry and loads the DLL from the associated path.
Since the path is absolute, trying to add a MSVidCtl.dll in the ehome folder was completely pointless: the loader would never look for it.
DLL redirection and side-by-side assemblies
To mitigate this issue, Microsoft offers 2 mechanisms that allow overriding the default search order used by Windows' DLL loader even when the specified path is absolute:
DLL redirection: by creating an empty .local file/folder whose name is the same as the executable (in our case, ehshell.exe.local), one can easily force the OS to load DLLs from the application folder: it's dead simple and works flawlessly, even for COM DLLs. Unfortunately, it has a major caveat: it doesn't work when the application has an application manifest (there's a registry switch to override that but turning it on would impact the entire system, certainly not a good thing to do).
Side-by-side assemblies: first introduced in Windows 98 Second Edition, it allows an application to define its dependencies in its application manifest (and explicitly opt for a specific DLL version). DLL dependencies can be either stored in the same directory as the application (in this case, they are known as private assemblies) or in a special shared directory called winsxs. Starting with Windows XP, it also allows defining registration-free COM components: unlike classical COM components, they don't have an entry in the registry and thus are not registered globally. Instead, they are defined in the application manifest: when the COM loader finds an entry in the manifest for the specified GUID, it loads the corresponding DLL and doesn't apply the default registry loading routine.
An application manifest is a special XML file that is either embedded in the executable or provided separately and that defines some core aspects of the application (e.g does it need to be executed with administrator rights?).
In our case, the first option is sadly not applicable: all the Windows Media Center executables come with an embedded manifest used to enable the DPI-aware mode. For instance, here's the manifest embedded in ehshell.exe:
Removing the manifest to make the .local approach work would be very easy, but we'd loose all the benefits of the DPI-aware mode: definitely not an option.
Defining registration-free COM components
While powerful, defining registration-free COM components is far from being trivial and is rather error-prone.
Extracting the TypeLib tables
First, you need to extract the TypeLib table from the COM DLL you want to use. For convenience, it's almost always embedded as a binary resource in the COM DLLs themselves. To extract these resources, you can use the popular Resource Hacker tool. In some cases, a single COM DLL might expose multiple TypeLib tables: you'll have to extract them all and merge them later. MSVidCtl.dll is one of them:
Generating assembly manifests
Then, you need to use the Manifest Tool coming with Visual Studio to generate the manifest files from the COM definitions.
For that, open a VS command prompt and run the following commands:
var path = @"[path pointing to the merged XML manifest file]"; var document = XDocument.Load(path);
foreach (var stub in document.Root.Elements(XName.Get("comInterfaceExternalProxyStub", "urn:schemas-microsoft-com:asm.v1")).ToList()) { var name = stub.Attribute("name"); if (string.IsNullOrEmpty(name?.Value)) { thrownew InvalidOperationException(); }
if (duplicates.Length > 1) { duplicates[0].SetAttributeValue("tlbid", null);
for (var index = 1; index < duplicates.Length; index++) { duplicates[index].Remove(); } } }
document.Save(path);
Fixing the resulting manifest
This is not done yet: if you try to use the resulting manifest as-is, Windows Media Center will simply crash as the mt utility misses an important part of the COM definitions: the threading model of the COM classes.
The good news is that this information can be retrived from the registry of a Windows 7 machine (or on Windows 10 pre-1803). To make that process much easier, I wrote a second tiny script updating the manifest from the data found in the registry:
var path = @"[path pointing to the merged XML manifest file]"; var document = XDocument.Load(path);
foreach (var file in document.Root.Elements(XName.Get("file", "urn:schemas-microsoft-com:asm.v1"))) { foreach (var component in file.Elements(XName.Get("comClass", "urn:schemas-microsoft-com:asm.v1"))) { var id = component.Attribute("clsid");
using (var root = Registry.ClassesRoot.OpenSubKey("CLSID")) using (var clsid = root.OpenSubKey(id.Value)) using (var ipc = clsid?.OpenSubKey("InprocServer32")) { var model = ipc?.GetValue("ThreadingModel").ToString(); if (string.IsNullOrEmpty(model)) { continue; }
<filename="MSVidCtl.dll"> <comClassclsid="{1C15D484-911D-11D2-B632-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Analog TV Tuner Device Class"threadingModel="Apartment" /> <comClassclsid="{A2E3074E-6C3D-11D3-B653-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control BDA Tuner Device Class"threadingModel="Apartment" /> <comClassclsid="{37B0353C-A4C8-11D2-B634-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control File Playback Device Class"threadingModel="Apartment" /> <comClassclsid="{011B3619-FE63-4814-8A84-15A194CE9CE3}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MSVidWebDVD Class"threadingModel="Apartment" /> <comClassclsid="{FA7C375B-66A7-4280-879D-FD459C84BB02}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MSVidWebDVDAdm Class"threadingModel="Apartment" /> <comClassclsid="{37B03543-A4C8-11D2-B634-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Video Renderer(DX7/8) Class"threadingModel="Apartment" /> <comClassclsid="{24DC3975-09BF-4231-8655-3EE71F43837D}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Video Renderer 9(DX9) Class"threadingModel="Apartment" /> <comClassclsid="{C45268A2-FA81-4E19-B1E3-72EDBD60AEDA}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Enhanced Video Renderer(DX10) Class"threadingModel="Apartment" /> <comClassclsid="{37B03544-A4C8-11D2-B634-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Audio Renderer Class"threadingModel="Apartment" /> <comClassclsid="{4A5869CF-929D-4040-AE03-FCAFC5B9CD42}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Stream Buffer Engine Sink Class"threadingModel="Apartment" /> <comClassclsid="{9E77AAC4-35E5-42A1-BDC2-8F3FF399847C}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Stream Buffer Engine Sink Class"threadingModel="Apartment" /> <comClassclsid="{AD8E510D-217F-409B-8076-29C5E73B98E8}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Stream Buffer Engine Playback Device Class"threadingModel="Apartment" /> <comClassclsid="{FD351EA1-4173-4AF4-821D-80D4AE979048}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Stream Buffer Engine V2 Playback Device Class"threadingModel="Apartment" /> <comClassclsid="{BB530C63-D9DF-4B49-9439-63453962E598}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Encoder"threadingModel="Apartment" /> <comClassclsid="{5740A302-EF0B-45CE-BF3B-4470A14A8980}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control iTV Capture"threadingModel="Apartment" /> <comClassclsid="{9E797ED0-5253-4243-A9B7-BD06C58F8EF3}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control iTV Playback"threadingModel="Apartment" /> <comClassclsid="{86151827-E47B-45EE-8421-D10E6E690979}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Closed Captions Analysis"threadingModel="Apartment" /> <comClassclsid="{7F9CB14D-48E4-43B6-9346-1AEBC39C64D3}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Standard Closed Captioning"threadingModel="Apartment" /> <comClassclsid="{92ED88BF-879E-448F-B6B6-A385BCEB846D}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control CCSI Closed Captioning"threadingModel="Apartment" /> <comClassclsid="{334125C0-77E5-11D3-B653-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Standard Data Services for Broadcast IP through NDIS stack"threadingModel="Apartment" /> <comClassclsid="{0149EEDF-D08F-4142-8D73-D23903D21E90}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Encoder"threadingModel="Apartment" /> <comClassclsid="{C5702CD6-9B79-11D3-B654-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Analog Capture to Data Services"threadingModel="Apartment" /> <comClassclsid="{38F03426-E83B-4E68-B65B-DCAE73304838}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Data Services to Stream Buffer Sink"threadingModel="Apartment" /> <comClassclsid="{0429EC6E-1144-4BED-B88B-2FB9899A4A3D}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for DataServices To XDS"threadingModel="Apartment" /> <comClassclsid="{3540D440-5B1D-49CB-821A-E84B8CF065A7}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for TV Tuner to XDS"threadingModel="Apartment" /> <comClassclsid="{B0EDF163-910A-11D2-B632-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Class"threadingModel="Apartment" /> <comClassclsid="{C5702CCC-9B79-11D3-B654-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Input Device Collection Class"threadingModel="Apartment" /> <comClassclsid="{C5702CCD-9B79-11D3-B654-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Output Device Collection Class"threadingModel="Apartment" /> <comClassclsid="{C5702CCE-9B79-11D3-B654-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Video Renderer Device Collection Class"threadingModel="Apartment" /> <comClassclsid="{C5702CCF-9B79-11D3-B654-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Audio Renderer Device Collection Class"threadingModel="Apartment" /> <comClassclsid="{C5702CD0-9B79-11D3-B654-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Feature Collection Class"threadingModel="Apartment" /> <comClassclsid="{2764BCE5-CC39-11D2-B639-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Generic Composition Class"threadingModel="Apartment" /> <comClassclsid="{E18AF75A-08AF-11D3-B64A-00C04F79498E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Analog Capture to Overlay Mixer"threadingModel="Apartment" /> <comClassclsid="{267DB0B3-55E3-4902-949B-DF8F5CEC0191}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for WebDVD to Overlay Mixer"threadingModel="Apartment" /> <comClassclsid="{8D04238E-9FD1-41C6-8DE3-9E1EE309E935}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for WebDVD to Audio Renderer"threadingModel="Apartment" /> <comClassclsid="{6AD28EE1-5002-4E71-AAF7-BD077907B1A4}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Mpeg2 Decoder to Closed Captioning"threadingModel="Apartment" /> <comClassclsid="{9F50E8B1-9530-4DDC-825E-1AF81D47AED6}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Analog Capture to Stream Buffer Sink"threadingModel="Apartment" /> <comClassclsid="{ABE40035-27C3-4A2F-8153-6624471608AF}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Digital Capture to Stream Buffer Sink"threadingModel="Apartment" /> <comClassclsid="{92B94828-1AF7-4E6E-9EBF-770657F77AF5}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for iTV to Stream Buffer Sink"threadingModel="Apartment" /> <comClassclsid="{3EF76D68-8661-4843-8B8F-C37163D8C9CE}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for CCA to Stream Buffer Sink"threadingModel="Apartment" /> <comClassclsid="{A0B9B497-AFBC-45AD-A8A6-9B077C40D4F2}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Encoder to Stream Buffer Sink"threadingModel="Apartment" /> <comClassclsid="{B401C5EB-8457-427F-84EA-A4D2363364B0}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for File Playback to Video Renderer"threadingModel="Apartment" /> <comClassclsid="{CC23F537-18D4-4ECE-93BD-207A84726979}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for File Playback to Audio Renderer"threadingModel="Apartment" /> <comClassclsid="{28953661-0231-41DB-8986-21FF4388EE9B}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for TV Tuner to Encoder"threadingModel="Apartment" /> <comClassclsid="{3C4708DC-B181-46A8-8DA8-4AB0371758CD}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for SBE Source to Video renderer"threadingModel="Apartment" /> <comClassclsid="{942B7909-A28E-49A1-A207-34EBCBCB4B3B}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for TV Tuner to CCA"threadingModel="Apartment" /> <comClassclsid="{73D14237-B9DB-4EFA-A6DD-84350421FB2F}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Digital Capture to CCA"threadingModel="Apartment" /> <comClassclsid="{5D8E73F7-4989-4AC8-8A98-39BA0D325302}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Digital Capture to ITV"threadingModel="Apartment" /> <comClassclsid="{2291478C-5EE3-4BEF-AB5D-B5FF2CF58352}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Stream Buffer Source to ITV"threadingModel="Apartment" /> <comClassclsid="{9193A8F9-0CBA-400E-AA97-EB4709164576}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for Stream Buffer Source to CC"threadingModel="Apartment" /> <comClassclsid="{991DA7E5-953F-435B-BE5E-B92A05EDFC42}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Stream Buffer Source to Generic Sink Composition Class"threadingModel="Apartment" /> <comClassclsid="{C4BF2784-AE00-41BA-9828-9C953BD3C54A}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for CC to Video Renderer"threadingModel="Apartment" /> <comClassclsid="{D76334CA-D89E-4BAF-86AB-DDB59372AFC2}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MS Video Control Custom Composition for CC to Audio Renderer"threadingModel="Apartment" /> <comClassclsid="{577FAA18-4518-445E-8F70-1473F8CF4BA4}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MSEventBinder Class"threadingModel="Apartment" /> <comClassclsid="{CAAFDD83-CEFC-4E3D-BA03-175F17A24F91}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="MSVidStreamBufferRecordingControl"threadingModel="Apartment" /> <comClassclsid="{CB4276E6-7D5F-4CF1-9727-629C5E6DB6AE}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="Automation compliant scalable rectangle Class" /> <comClassclsid="{6E40476F-9C49-4C3E-8BB9-8587958EFF74}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="dummy class to expose base interface to VB" /> <comClassclsid="{30997F7D-B3B5-4A1C-983A-1FE8098CB77D}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="dummy class to expose base interface to VB" /> <comClassclsid="{AC1972F2-138A-4CA3-90DA-AE51112EDA28}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="dummy class to expose base interface to VB" /> <comClassclsid="{95F4820B-BB3A-4E2D-BC64-5B817BC2C30E}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="dummy class to expose base interface to VB" /> <comClassclsid="{1990D634-1A5E-4071-A34A-53AAFFCE9F36}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="dummy class to expose base interface to VB" /> <comClassclsid="{7748530B-C08A-47EA-B24C-BE8695FF405F}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="dummy class to expose base interface to VB" /> <comClassclsid="{87EB890D-03AD-4E9D-9866-376E5EC572ED}"tlbid="{B0EDF154-910A-11D2-B632-00C04F79498E}"description="dummy class to expose base interface to VB" /> <comClassclsid="{D02AAC50-027E-11D3-9D8E-00C04F72D980}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="SystemTuningSpace Class"threadingModel="Both" /> <comClassclsid="{5FFDC5E6-B83A-4B55-B6E8-C69E765FE9DB}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="dummy class to expose base tuning space i/f to VB" /> <comClassclsid="{CC829A2F-3365-463F-AF13-81DBB6F3A555}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Channel ID Tuning Space Class"threadingModel="Both" /> <comClassclsid="{A2E30750-6C3D-11D3-B653-00C04F79498E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="ATSC Digital Broadcast Tuning Space Class"threadingModel="Both" /> <comClassclsid="{D9BB4CEE-B87A-47F1-AC92-B08D9C7813FC}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Digital Cable Tuning Space Class"threadingModel="Both" /> <comClassclsid="{8A674B4C-1F63-11D3-B64C-00C04F79498E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Analog Radio Tuning Space Class"threadingModel="Both" /> <comClassclsid="{F9769A06-7ACA-4E39-9CFB-97BB35F0E77E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Auxiliary Inputs Tuning Space Class"threadingModel="Both" /> <comClassclsid="{8A674B4D-1F63-11D3-B64C-00C04F79498E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Analog TV Tuning Space Class"threadingModel="Both" /> <comClassclsid="{C6B14B32-76AA-4A86-A7AC-5C79AAF58DA7}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DVB Tuning Space Class"threadingModel="Both" /> <comClassclsid="{B64016F3-C9A2-4066-96F0-BD9563314726}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DVB Satellite Tuning Space Class"threadingModel="Both" /> <comClassclsid="{A1A2B1C4-0E3A-11D3-9D8E-00C04F72D980}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Component Types Collection Class"threadingModel="Both" /> <comClassclsid="{823535A0-0318-11D3-9D8E-00C04F72D980}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="ComponentType Class"threadingModel="Both" /> <comClassclsid="{1BE49F30-0E1B-11D3-9D8E-00C04F72D980}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="LanguageComponentType Class"threadingModel="Both" /> <comClassclsid="{418008F3-CF67-4668-9628-10DC52BE1D08}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="MPEG2ComponentType Class"threadingModel="Both" /> <comClassclsid="{A8DCF3D5-0780-4EF4-8A83-2CFFAACB8ACE}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="ATSCComponentType Class"threadingModel="Both" /> <comClassclsid="{809B6661-94C4-49E6-B6EC-3F0F862215AA}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Components Collection Class"threadingModel="Both" /> <comClassclsid="{59DC47A8-116C-11D3-9D8E-00C04F72D980}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Component Class"threadingModel="Both" /> <comClassclsid="{055CB2D7-2969-45CD-914B-76890722F112}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="MPEG2 Component Class"threadingModel="Both" /> <comClassclsid="{28AB0005-E845-4FFA-AA9B-F4665236141C}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Analog Audio Component Class"threadingModel="Both" /> <comClassclsid="{B46E0D38-AB35-4A06-A137-70576B01B39F}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="dummy class to expose base tune request i/f to VB" /> <comClassclsid="{3A9428A7-31A4-45E9-9EFB-E055BF7BB3DB}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Channel Tune Request"threadingModel="Both" /> <comClassclsid="{0369B4E5-45B6-11D3-B650-00C04F79498E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Channel Tune Request"threadingModel="Both" /> <comClassclsid="{0369B4E6-45B6-11D3-B650-00C04F79498E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="ATSC Channel Tune Request"threadingModel="Both" /> <comClassclsid="{26EC0B63-AA90-458A-8DF4-5659F2C8A18A}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Digital Cable Channel Tune Request"threadingModel="Both" /> <comClassclsid="{0955AC62-BF2E-4CBA-A2B9-A63F772D46CF}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="dummy class to expose mpeg2 request i/f to VB"threadingModel="Both" /> <comClassclsid="{2C63E4EB-4CEA-41B8-919C-E947EA19A77C}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Factory for creating IMPEG2TuneRequest"threadingModel="Apartment" /> <comClassclsid="{0888C883-AC4F-4943-B516-2C38D9B34562}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="dummy class to expose base locator i/f to VB" /> <comClassclsid="{6E50CC0D-C19B-4BF6-810B-5BD60761F5CC}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="dummy class to expose base digital locator i/f to VB" /> <comClassclsid="{49638B91-48AB-48B7-A47A-7D0E75A08EDE}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Analog Locator"threadingModel="Both" /> <comClassclsid="{8872FF1B-98FA-4D7A-8D93-C9F1055F85BB}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="ATSC Locator"threadingModel="Both" /> <comClassclsid="{03C06416-D127-407A-AB4C-FDD279ABBE5D}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Digital Cable Locator"threadingModel="Both" /> <comClassclsid="{9CD64701-BDF3-4D14-8E03-F12983D86664}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DVB-Terrestrial Locator"threadingModel="Both" /> <comClassclsid="{EFE3FA02-45D7-4920-BE96-53FA7F35B0E6}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DVB-Terrestrial 2 Locator"threadingModel="Both" /> <comClassclsid="{1DF7D126-4050-47F0-A7CF-4C4CA9241333}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DVB-Satellite Locator"threadingModel="Both" /> <comClassclsid="{C531D9FD-9685-4028-8B68-6E1232079F1E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DVB-Cable Locator"threadingModel="Both" /> <comClassclsid="{6504AFED-A629-455C-A7F1-04964DEA5CC4}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="ISDB-Satellite Locator"threadingModel="Both" /> <comClassclsid="{15D6504A-5494-499C-886C-973C9E53B9F1}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DVB Tune Request"threadingModel="Both" /> <comClassclsid="{8A674B49-1F63-11D3-B64C-00C04F79498E}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Create property bag backed by registry"threadingModel="Both" /> <comClassclsid="{0B3FFB92-0919-4934-9D5B-619C719D0202}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="DShow Broadcast Event Service Object"threadingModel="Both" /> <comClassclsid="{6438570B-0C08-4A25-9504-8012BB4D50CF}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="BDA ITuner Marshaling utility object"threadingModel="Both" /> <comClassclsid="{E77026B0-B97F-4CBB-B7FB-F4F03AD69F11}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Utility object for Tuning Model Object Xml deserialization or serialization"threadingModel="Both" /> <comClassclsid="{C20447FC-EC60-475E-813F-D2B0A6DECEFE}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Extensible Eventing Service object"threadingModel="Both" /> <comClassclsid="{8E8A07DA-71F8-40C1-A929-5E3A868AC2C6}"tlbid="{9B085638-018E-11D3-9D8E-00C04F72D980}"description="Eventing Service object(used for unmarshal)" />
This is the last step: writing the application manifest and importing the assembly manifest we just created.
For that, I took the original manifest embedded in ehshell.exe, cleaned it up a bit, added the necessary parts and created ehshell.exe.manifest with the resulting XML:
The Microsoft.Windows.Video.Tagging dependency was generated using the same exact procedure, but using EncDec.dll instead of MSVidCtl.dll.
At this stage, it's important to note that external manifest files are NOT loaded if the executable already contains an embedded manifest. Since I preferred having an external manifest, I used Resource Hacker to remove the embedded manifest from ehshell.exe and the other WMC executables.
Conclusion
Creating registration-free COM manifests to work around a breaking change in a system DLL is definitely a painful process (after all, it's called DLL Hell for a reason!). Fortunately, the result is worth it, as it makes an application safe from future DLL changes introduced in minor or major Windows versions.
Since I don't expect anyone to reproduce this painful process to fix their Windows Media Center setup, I decided to release an updated 8.8.2 installer that includes the precious manifest and the MSVidCtl/EncDec DLLs needed for Windows Media Center to work properly with recent versions of Windows 10: https://mega.nz/file/nfIixSoC#dXgwWW9mg3DIe_CoIJMElusn6fFOD-5Pv-Xv5VIv7AU