Delphi XE7动态虚拟通道新增接口注册失败及查询异常求助
Troubleshooting DVC Interface Registration & Query Issues in Delphi XE7
Let’s break down actionable steps to fix your registration errors and interface compatibility problems, tailored to your RDP Dynamic Virtual Channel (DVC) scenario:
1. Fix Manual Registration Gaps
Your manual registry edits were a good start, but you might have missed critical details:
- Validate GUID Consistency: Double-check that the IID of your new interface matches exactly across your
.idlfile, Delphi implementation, and registry entries (case doesn’t matter, but consistency avoids silent failures). - Complete Interface Registry Entries: For your new interface’s GUID key (under
HKEY_CLASSES_ROOT\Interface\{YOUR_NEW_IID}andHKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\{YOUR_NEW_IID}—don’t forget theWow6432Nodepath for 32-bit DLLs on 64-bit Windows), ensure you have:- A
(Default)value set to your interface’s friendly ProgID (e.g.,MyDVCDLL.INewDVCInterface). - A
ProxyStubClsid32value pointing to the CLSID of your proxy-stub DLL (more on this next).
- A
- Register the Proxy-Stub DLL: When you compile your
.idlwith Midl, it generates proxy-stub source files (like_yourtlb_p.c). You need to compile these into a DLL (using Visual Studio’s compiler) and register it withregsvr32.exe your_proxy_stub.dll. This is critical for cross-apartment (STA/MTA) interface communication via Agile References—without it, COM can’t marshal your interface between processes. - Verify DLL Threading Model: In your DLL’s CLSID registry entry (
HKEY_CLASSES_ROOT\CLSID\{YOUR_DLL_CLSID}\InprocServer32), set theThreadingModelvalue toBothorFree. Agile References require the DLL to support free-threading or dual-threading models to work correctly.
2. Address IWTSPlugin2 Compatibility
Your hunch about upgrading to IWTSPlugin2 is spot-on:
- RDP’s
mstsc.exeprioritizes queryingIWTSPlugin2first when loading DVC plugins. If your plugin only implementsIWTSPlugin, it will fall back, but this can cause issues if your new interface relies on the extended plugin contract. - Update your Delphi class to implement both
IWTSPlugin(for backward compatibility) andIWTSPlugin2(add theOnLogoffmethod required by the interface). - Ensure your
.idlcorrectly declares your plugin interface as inheriting fromIWTSPlugin2if you’re fully upgrading, and recompile the type library. - Confirm your plugin’s CLSID is registered under the RDP plugin category: Add a subkey
{7390F3D8-0439-4C05-91E3-C5CBFC15831A}underHKEY_CLASSES_ROOT\CLSID\{YOUR_DLL_CLSID}\Implemented Categories—this tellsmstscyour DLL is a valid DVC plugin.
3. Debug Interface Query Failures
To get to the root of the "interface not supported" error:
- Use OleView.exe: This Windows SDK tool lets you load your DLL directly to inspect its registered interfaces, type library, and proxy-stub associations. It’s invaluable for catching mismatched IIDs or missing registrations.
- Enable COM Logging: Create a
LogToFileDWORD value set to1and aLogFilePathstring value pointing to a log file (e.g.,C:\COMlog.txt) underHKEY_LOCAL_MACHINE\Software\Microsoft\Ole\AppCompat. Runmstscto load your plugin, then check the log for detailed errors about interface marshaling or query failures. - Add Debug Logging to QueryInterface: Modify your Delphi plugin’s
QueryInterfacemethod to log which IIDs are being requested, ensuring your new interface is properly handled:
Use DebugView to monitor these debug messages and confirm your interface is being queried.function TMyDVPlugin.QueryInterface(const IID: TGUID; out Obj): HResult; begin if IsEqualGUID(IID, IID_INewDVCInterface) then begin OutputDebugString('New DVC interface requested'); Obj := Self as INewDVCInterface; Result := S_OK; Exit; end; Result := inherited QueryInterface(IID, Obj); end;
4. Replace tregsvr with a Custom Registration Tool
Since tregsvr gives no useful error details, build a simple Delphi registration program to get clear feedback:
program RegMyDVCDLL; uses ComServ, ComObj, Windows, SysUtils; begin try if ParamCount <> 1 then begin Writeln('Usage: RegMyDVCDLL /REGSERVER or /UNREGSERVER'); Exit; end; if UpperCase(ParamStr(1)) = '/REGSERVER' then begin RegisterServer; Writeln('DLL registered successfully.'); end else if UpperCase(ParamStr(1)) = '/UNREGSERVER' then begin UnregisterServer; Writeln('DLL unregistered successfully.'); end else Writeln('Invalid parameter.'); except on E: Exception do Writeln('Registration failed: ', E.Message); end; end.
Compile this, run it as administrator, and it will show you exact errors (like missing dependencies or invalid registry writes) that tregsvr hides.
内容的提问来源于stack exchange,提问作者David Bolton
相关产品推荐
相关产品推荐

