В попытке ответить на ваш актуальный вопрос четыре года назад (на момент публикации этого ответа) я предоставляю рабочее решение. Я не удивлюсь, если вы найдете другой способ сделать это, так что это в основном для других людей, которые ищут подобное решение. Имейте в виду, однако, что это считается
- несколько устарел (фактическое использование
HtmlDocument
)
- не самый лучший способ обработки HTML DOM (предпочтительное решение - использовать HtmlAgilityPack или CsQuery или какой-либо другой метод с использованием фактического анализа, а не регулярных выражений)
- чрезвычайно хакерский и, следовательно, не самый безопасный / самый совместимый способ сделать это
- Вы действительно не должны делать то, что я собираюсь показать
Кроме того, имейте в виду, что HtmlDocument
на самом деле является просто оболочкой для mshtml.HTMLDocument2
, поэтому она технически на медленнее, чем просто использование COM-оболочки напрямую, но я полностью понимаю вариант использования просто для простота кодирования.
Если вы круты со всем вышеперечисленным, вот как выполнить то, что вы хотите.
public class HtmlDocumentFactory
{
private static Type htmlDocType = typeof(System.Windows.Forms.HtmlDocument);
private static Type htmlShimManagerType = null;
private static object htmlShimSingleton = null;
private static ConstructorInfo docCtor = null;
public static HtmlDocument Create()
{
if (htmlShimManagerType == null)
{
// get a type reference to HtmlShimManager
htmlShimManagerType = htmlDocType.Assembly.GetType(
"System.Windows.Forms.HtmlShimManager"
);
// locate the necessary private constructor for HtmlShimManager
var shimCtor = htmlShimManagerType.GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null
);
// create a new HtmlShimManager object and keep it for the rest of the
// assembly instance
htmlShimSingleton = shimCtor.Invoke(null);
}
if (docCtor == null)
{
// get the only constructor for HtmlDocument (which is marked as private)
docCtor = htmlDocType.GetConstructors(
BindingFlags.NonPublic | BindingFlags.Instance
)[0];
}
// create an instance of mshtml.HTMLDocument2 (in the form of
// IHTMLDocument2 using HTMLDocument2's class ID)
object htmlDoc2Inst = Activator.CreateInstance(Type.GetTypeFromCLSID(
new Guid("25336920-03F9-11CF-8FD0-00AA00686F13")
));
var argValues = new object[] { htmlShimSingleton, htmlDoc2Inst };
// create a new HtmlDocument without involving WebBrowser
return (HtmlDocument)docCtor.Invoke(argValues);
}
}
Чтобы использовать это:
var htmlDoc = HtmlDocumentFactory.Create();
htmlDoc.Write("<html><body><div>Hello, world!</body></div></html>");
Console.WriteLine(htmlDoc.Body.InnerText);
// output:
// Hello, world!
Я не тестировал этот код напрямую - я перевел его из старого скрипта Powershell, который нуждался в той же функциональности, которую вы запрашивали. Если не получится, дайте мне знать. Функциональность есть, но для работы кода может потребоваться небольшая настройка.