Word имеет функцию отключенных надстроек (Справка | О программе | Отключенные элементы).
Как добавить надстройку в список отключенных без сбоя надстройки и ожидания появления ошибки?
Word имеет функцию отключенных надстроек (Справка | О программе | Отключенные элементы).
Как добавить надстройку в список отключенных без сбоя надстройки и ожидания появления ошибки?
Я пытался выяснить двоичный формат значений в ключе DisabledItems, и ваш пост заставил меня пойти по правильному пути. Однако я думаю, что формат немного отличается от того, как вы его видите, по крайней мере, в Office 2010.
Насколько я могу судить, формат такой:
Первые четыре байта являются 32-разрядным целым числом. Обычно кажется, что имеет значение 1. Я не уверен, для чего это нужно.
Следующие четыре байта представляют собой 32-разрядное целое число, которое сообщает нам длину пути dll в байтах, включая завершающий символ (ноль или 0x0000).
Следующие четыре байта представляют собой 32-разрядное целое число, которое сообщает нам длину понятного имени в байтах, включая завершающий символ (ноль или 0x0000).
Следующая последовательность байтов является строкой юникода с большим порядком байтов в конце с нулевым символом в конце, содержащей путь к dll надстройки. По какой-то причине этот путь всегда содержит только строчные буквы.
Следующая последовательность байтов является строкой юникода с большим порядком байтов в конце с нулевым символом в конце, содержащей понятное имя надстройки.
Я смог успешно жестко отключить надстройку, используя следующий код C #:
string path = "<full path to add-in dll>".ToLower();
string friendlyName = "<add-in friendly name>";
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
writer.Write(1); // Unknown
writer.Write((path.Length * 2) + 2); // Path length, 2 bytes per character
writer.Write((friendlyName.Length * 2) + 2); // Friendly name length
writer.Write(Encoding.Unicode.GetBytes(path)); // Path
writer.Write(Convert.ToInt16(0)); // null terminator
writer.Write(Encoding.Unicode.GetBytes(friendlyName)); // Friendly name
writer.Write(Convert.ToInt16(0)); // null terminator
writer.Close();
// Version numbers: 11.0 = Office 2003, 12.0 = Office 2007, 14.0 = Office 2010
RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Office\14.0\Word\Resiliency\DisabledItems", true);
key.SetValue("63CB962", stream.ToArray(), RegistryValueKind.Binary);
key.Close();
Аналогичный подход может быть использован для декодирования пути DLL существующего значения, например так:
// Let 'bytes' be a byte array containing the binary registry value
BinaryReader binaryReader = new BinaryReader(new MemoryStream(bytes));
binaryReader.ReadInt32(); // Read the first four bytes and ignore
int pathLength = binaryReader.ReadInt32(); // The next four bytes are the length of the path
binaryReader.Close();
if (bytes.Length >= 12 + pathLength)
{
string path = Encoding.Unicode.GetString(bytes, 12, pathLength - 2);
}
Отвечая на мой собственный вопрос.
Он находится в реестре, в разделе HKCU\Software\Microsoft\Office [версия]>\Word\ Resilidity \ DisabledItems (где [версия] - 10.0 для XP, 11.0 для 2003 и 12.0 для 2007).
Ключи - это двоичные ключи с именами из шести (насколько я могу судить случайных) шестнадцатеричных символов.
Значение:01,00,00,00, x, 00,00,00, y, [путь], 00,00, [имя], 00,00,00 x - это число байтов в пути (включая два завершающих байта) и y - это количество байтов в имени (которое является "дружественным именем"). x+y должно быть общим числом байтов минус десять. х и у оба в гексе. Я предполагаю, что они на самом деле DWORD, но мне нужен только LSB.
Путь закодирован в UCS-2, little-endian, поэтому, для примера, «c:\» - это 00,63,00,3a, 00,5c
Да, бинарная кодировка выглядит потрясающе блестящей кодировкой «Возьмите ASCII-строку с нулевым символом в конце, преобразуйте ее в Unicode, затем возьмите байты этого и завершите нулевым результатом»
Обратите внимание, что x и y - это количество байтов, а не символов; в UCS-2 есть 2 байта на символ.
Если вы хотите заблокировать шаблон (т.е. .dot, а не .dll), тогда поставьте 00 для y и пропустите элемент name и завершение (поэтому он заканчивается тремя нулевыми байтами, а не пятью).
Обратите внимание, что код Eirikur работает только в том случае, если установлен подраздел Resilidity \DisabledItems. Похоже, что Word будет добавлять / удалять весь этот подраздел, когда он отключает / включает. Так что, если вы получаете исключение, запускающее код, вам, вероятно, нужно сначала добавить подраздел.
(Мой пост здесь, вероятно, должен быть модерирован, он принадлежит как комментарий, но мне не хватает очков! Плохое начало)
Согласно этому сайту MS, чтобы отключить надстройку в Word 2007, сделайте следующее: