我试图按照这个答案https://stackoverflow.com/a/47295752/1237135,以获取IIS Express网站列表,其中涉及引用Microsoft.Web.dll(这是一个.NET程序集,但可能是它使用COM调用)并调用此代码
using (var runtimeStatusClient = new RuntimeStatusClient())
{
var workerProcess = runtimeStatusClient.GetWorkerProcess(19464);
//there's more but this is all that is needed for failure
}
它确实有效,代码运行并且包含有意义的数据,但是在完成后几秒钟我得到了这个错误
System.InvalidCastException:
'Unable to cast COM object of type 'System.__ComObject'
to interface type 'Microsoft.Web.RuntimeStatus.IRsca2_WorkerProcess'.
This operation failed because the QueryInterface call on the COM component
for the interface with IID '{B1341209-7F09-4ECD-AE5F-3EE40D921870}' failed
due to the following error: No such interface supported (Exception from
HRESULT: 0x80004002 (E_NOINTERFACE)).'
E_NOINTERFACE
通常与不使用STAThread模型相关联,但我已经验证该线程是STA。
代码在Console应用环境中无错误地工作,但不能在WPF中运行。
上面的答案提到
我也查看过RegisteredUrlsInfo(在Microsoft.Web.dll中) 发现它使用了两个COM接口,
IRsca2_Core(F90F62AB-EE00-4E4F-8EA6-3805B6B25CDD) IRsca2_WorkerProcess(B1341209-7F09-4ECD-AE5F-3EE40D921870)
我看到了另一个回答https://stackoverflow.com/a/1058978/1237135的回答
尝试将此添加到App.exe.manifest:
IID =" {C677308A-AC0F-427D-889A-47E5DC990138}"
proxyStubClsid32 =" {00020424-0000-0000-C000-000000000046}"
baseInterface =" {00000000-0000-0000-C000-000000000046}" tlbid = " {PUT-YOUR-TLB-GUID-HERE}" />在哪里可以找到TLBID Visual Studio生成Native.Namespace.Assembly.Name.manifest, 看起来像这样:
但我不清楚这是否适用于此。
我也想知道它是不是它的DLL地狱但是它无法解释为什么它可以从控制台运行,是吗?
编辑:最小的复制。
创建一个WPF项目(我使用4.6.1运行时),并在我使用的MainWindow的代码隐藏中
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
using (var runtimeStatusClient = new Microsoft.Web.RuntimeStatus.RuntimeStatusClient())
{
var workerProcess = runtimeStatusClient.GetAllWorkerProcesses();
}
}
}
}
唯一困难的部分是您需要查找并引用Microsoft.Web.DLL(如果您的计算机上有IIS Express,则应该在您的GAC中)。你可以在你的C:\驱动器上进行Windows搜索,它可能在某个地方,如C:\ Windows \ assembly \ GAC_MSIL \ Microsoft.Web \ 7.1.0.0__31bf3856ad364e35
这样做,你就会发现问题。
答案 0 :(得分:0)
显然我做了两个致命的假设:
控制台应用使用STA。然而,这不是真的,默认情况下它们似乎是MTA。我想这些数字,因为桌面应用程序必须在Main方法中明确声明STA。
要做COM互操作,你必须使用STA。我之所以这么认为是因为使用STA是网络上E_NOINTERFACE问题的首选解决方案。但是正如我现在所理解的,一些COM可以使用MTA。它出现在Microsoft.Web.DLL中,您需要MTA。
所以我的解决方案是创建一个新线程(默认情况下将使用MTA),例如
public MainWindow()
{
InitializeComponent();
//Do use ThreadPool instead of this...
Thread thread = new Thread(new ThreadStart(() => { GetWebsites(); }));
thread.Start();
}
void GetWebsites()
{