2013-05-25 2 views
2

(Delphi XE2 обновление 4)Как отследить _AddRef/_Release требует объекты OLE Automation

Я пытаюсь получить большой блок автоматизации Microsoft Word OLE Я унаследованного (на основе раннего связывания TWordApplication и интерфейсов от WordXP/Word2010 единиц), чтобы закрыть WINWORD.EXE, когда все ссылки были выпущены.

До сих пор, похоже, я действительно поймал пару эталонных утечек: большинство ссылок являются свойствами или локальными переменными.

Некоторые сценарии использования, тем не менее, сохраняют WINWORD.EXE открытыми.

Несколько исправлений указывают мне в пользу локальных переменных вместо цепочек из

procedure TOffice_10_XP_WordInterface.AddDocument; 
var 
    WordApplicationDocuments: Documents; 
begin 
    WordApplication_Documents.Add(EmptyParam, EmptyParam, EmptyParam, EmptyParam); 
end; 

в

procedure TOffice_10_XP_WordInterface.AddDocument; 
var 
    WordApplicationDocuments: Documents; 
begin 
    WordApplicationDocuments := WordApplication_Documents; 
    WordApplicationDocuments.Add(EmptyParam, EmptyParam, EmptyParam, EmptyParam); 
end; 

основано на свойстве WordApplication_Documents, который вызывает эту функцию:

function TOffice_10_XP_WordInterface.GetWordApplication_Documents: Documents; 
begin 
    Result := WordApplicationReference.Documents; 
    if not Assigned(Result) then 
    raise EAccessViolation.Create('Documents'); 
end; 

Свойства, необходимые для получения сообщений EAccessViolation чем ошибки $ C0000005, которые вы получаете в отладчике.

Мне интересно узнать об общем (так как мне, вероятно, понадобится это и для других проектов автоматизации), способы отслеживания вызовов _AddRef и _Release.

я взглянуть на эти ссылки:

+2

будет немного сложнее. COM-сервер не работает, поэтому код, который вы хотите использовать, находится в другом процессе. –

+0

Я надеялся, что есть яркий способ сломать локальный прокси. –

+0

Вы можете это сделать, но это только часть истории. Ссылки будут рассмотрены в другом процессе. –

ответ

0

утомительный путь, который получает вы собираетесь это:

Помещенных точек останова всех _AddRef и _Release вызовов в блоке Delphi System, которые не являются внутри TInterfacedObject конкретные методы.

Теперь устраните (используя условные выражения) все интерфейсы, которые не являются частью Delphi (EAX содержит указатель vTable для каждого интерфейса).

  1. Начать отладку приложения с помощью простого запуска/выхода, не делая много фактических функциональность:
  2. Перед трассировку в каждом вызове, запишите значения EAX.
  3. Если вы в конечном итоге в любой из этих методов: NopRelease, NopAddref, TInterfacedObject._AddRef, TInterfacedObject._Release, MemRelease, MemAddRef затем добавить значение EAX к условной инструкции точки останова для всех точек останова, как показано ниже.

Пример условного выражения точки останова для моего приложения:

(EAX <> $401E58) and (EAX <> $54AD14) and (EAX <> $4A7C88) ... 

Этот метод имеет много недостатков, но он получает вы собираетесь.

Недостатки:

  • Существуют ограничения на длину условной точки останова выражения. Это означает, что если вы продолжаете добавлять and (EXA <> $xxxx) частей, отладчик будет игнорировать те, которые не указали предупреждение.
  • Вы потеряете настройки, если выйти из Delphi без сохранения рабочего стола
  • Это занимает много времени для установки
+0

Я понятия не имею, о чем вы говорите. –

+0

@DavidHeffernan 'EAX' имеет ссылку на интерфейс в каждом методе. В основном вы хотите исключить все ссылки на интерфейс, которые не являются ссылками COM. –

Смежные вопросы