Здравствуйте, vuder, Вы писали:
V>Добрый день! V>Подскажите есть ли возможность запустить сервер Word(CreateOleObject('Word.Application') ) так, V>чтобы к нему можно было приконектиться только из моего приложения. V>А открытие пользователем Word'a из винды приводило бы к созданию V>нового процесса WINWORD.
сделать singleton, отдающий IDispatch единственного экзмпляра Word.Application
Добрый день!
Подскажите есть ли возможность запустить сервер Word(CreateOleObject('Word.Application') ) так,
чтобы к нему можно было приконектиться только из моего приложения.
А открытие пользователем Word'a из винды приводило бы к созданию
нового процесса WINWORD.
Заранее спасибо!
Здравствуйте, ssm, Вы писали:
ssm>Здравствуйте, vuder, Вы писали:
V>>Добрый день! V>>Подскажите есть ли возможность запустить сервер Word(CreateOleObject('Word.Application') ) так, V>>чтобы к нему можно было приконектиться только из моего приложения. V>>А открытие пользователем Word'a из винды приводило бы к созданию V>>нового процесса WINWORD.
ssm>сделать singleton, отдающий IDispatch единственного экзмпляра Word.Application
ssm>
Столкнулся точно с такой же проблемой. Нужно изолировать мой экземпляр Word от пользователей.
Объясните что такое сделать singleton – куда это вставить ???
Создаю Word так:
_Application objWord;
// Convenient values declared as ColeVariants.
COleVariant covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
// Get the IDispatch pointer and attach it to the objWord object.if (!objWord.CreateDispatch("Word.Application"))
{
AfxMessageBox("Couldn't get Word object.");
return;
}
objWord.SetVisible(FALSE);
Здравствуйте, MaIron, Вы писали:
MI>Столкнулся точно с такой же проблемой. Нужно изолировать мой экземпляр Word от пользователей. MI>Объясните что такое сделать singleton – куда это вставить ???
Для решения этой проблемы singleton не поможет. И изолировать Word просто так нельзя... возможно гуру меня поправят.
Вообще проблема довольно распространённая. Но ответа я так и не нашёл.
Кто то предлагает открывать ещё одну копию Word для того что бы в неё загружался пользовательский документ.
Кто то предлагает удалять запись о текущем Word из таблицы приложений и т.д. ...
Здравствуйте, MaIron, Вы писали:
MI>Вообще проблема довольно распространённая. Но ответа я так и не нашёл.
MI>Кто то предлагает открывать ещё одну копию Word для того что бы в неё загружался пользовательский документ. MI>Кто то предлагает удалять запись о текущем Word из таблицы приложений и т.д. ...
а если запускать первоначальный вариант под другим пользователем?
Здравствуйте, izekia, Вы писали:
I>Здравствуйте, MaIron, Вы писали:
MI>>Вообще проблема довольно распространённая. Но ответа я так и не нашёл.
MI>>Кто то предлагает открывать ещё одну копию Word для того что бы в неё загружался пользовательский документ.
Делал. Непомогает. Т.к. Если пользователь откроет и закроет эту копию, а потом откроет ещё одну. То тогда всё рушится.
MI>>Кто то предлагает удалять запись о текущем Word из таблицы приложений и т.д. ... I>а если запускать первоначальный вариант под другим пользователем?
Делал. Тоже как то не особо получилось... Почему именно не разбирался.
Сейчас пробую удалить Word из ROT но незнаю как получить DWORD код, для Revoke(?) — Там всего то и нужен один этот код.
Здравствуйте, MaIron, Вы писали:
MI>Сейчас пробую удалить Word из ROT но незнаю как получить DWORD код, для Revoke(?) — Там всего то и нужен один этот код.
Не получится. Решение — сложное — в том, чтобы подписаться на события Word и отрабатывать их. Для Word у меня нет примера, но для Excel — есть.
Dim WithEvents ExcelApp As Excel.Application
Const workbookname As String = "c:\tmp\x.xls"
Private Sub ExcelApp_WorkbookBeforeClose(ByVal Wb As Excel.Workbook, Cancel As Boolean)
Dim wb2 As Excel.Workbook
If ExcelApp.Visible Then
If UCase(Wb.FullName) = UCase(workbookname) Then
Cancel = True
ExcelApp.Visible = False' Закрываем все остальные документыFor Each wb2 In ExcelApp.Workbooks
If Not wb2 Is Wb Then wb2.Close
Next
End If
End If
End Sub
Private Sub Form_Load()
Set ExcelApp = CreateObject("Excel.application")
ExcelApp.Workbooks.Open workbookname
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim ea2 As Excel.Application, wb2 As Excel.Workbook
Set ea2 = ExcelApp
Set ExcelApp = Nothing
If ea2.Workbooks.Count = 1 Then' Закрываем приложение
ea2.Visible = False
ea2.Quit
Else' Закрываем только свой документFor Each wb2 In ea2.Workbooks
If UCase(wb2.FullName) = UCase(workbookname) Then
wb2.Close
Exit For
End If
Next
End If
End Sub
Я могу подключиться к событиям MS Word, как своего так и текущего открытого.
Но что это мне даст ?
Как это поможе препядсвовать открытию документа пользователя в моём сервере автоматизации.
Создать ещё один сервер ? Но проблема в том, что его могут закрыть.
Можно это отследить, но дальше то что ? Создавать новый смылса нет.
Т.к. мой текущий активный сервер, перемиститься в ROT выше и именно к нему будут присасываться
оттрываемые пользователем документы...
Здравствуйте, MaIron, Вы писали:
MI>Идея то в чём ? Я не пойму код что этот делает ?
MI>Я могу подключиться к событиям MS Word, как своего так и текущего открытого. MI>Но что это мне даст ?
Идея проста: создаешь Excel (Word) (смотри Form_Load),
в нем открываешь свой документ (он не отображается и не будет отображаться для визуального пользователя) (смотри Form_Load),
подключаешься к его событиям, отслеживая открытие/закрытие документов в твоем экземпляре Excel (Word) и не давая серверу закрыть твой документ (смотри Form_Load и ExcelApp_WorkbookBeforeClose),
при завершении клиента корректно уничтожаешь твой экземпляр Excel (Word) (смотри Form_Unload).
MI>Как это поможет препятствовать открытию документа пользователя в моём сервере автоматизации.
Никак.
MI>Создать ещё один сервер ? Но проблема в том, что его могут закрыть. MI>Можно это отследить, но дальше то что ? Создавать новый смысла нет. MI>Т.к. мой текущий активный сервер, переместиться в ROT выше и именно к нему будут присасываться MI>открываемые пользователем документы...
Другой сценарий, который может быть проще реализовать: создаешь первый экземпляр Excel (Word) — для открываемых пользователем документов, — который контролируешь и не даешь ему завершиться,
создаешь второй экземпляр Excel (Word) — для своего приложения.
Здравствуйте, MaIron, Вы писали:
MI>Каким образом не дать ему завершиться, когда пользователь закрывает документ ?
Событие DocumentBeforeClose имеет параметр Cancel для остановки закрытия документа и выгрузки сервера. Если Word не держится без документов, можно открыть и не закрывать свой фиктивный документ в нем.
MI>И я пишу на С++. Там многое иначе...
Здравствуйте, Vi2, Вы писали:
Vi2>Здравствуйте, MaIron, Вы писали:
MI>>Каким образом не дать ему завершиться, когда пользователь закрывает документ ?
Vi2>Событие DocumentBeforeClose имеет параметр Cancel для остановки закрытия документа и выгрузки сервера. Если Word не держится без документов, можно открыть и не закрывать свой фиктивный документ в нем.
MI>>И я пишу на С++. Там многое иначе...
Vi2>Иначе не значит не доступно.
А как скрыть документ ? По молчанию он показывается в развёрнутом виде.
Наверное через класс CWindow0 ? И метод put_Visible() ?
Здравствуйте, MaIron, Вы писали:
MI>А как скрыть документ ? По умолчанию он показывается в развёрнутом виде.
А каким способом открывается документ? Я, конечно, досконально не знаю, какие там умолчания. Но помнится, если документ создается СОМ клиентом, то документ изначально невидим, если документ открывается конечным пользователем, то документ открывается видимым.
MI>Наверное через класс CWindow0 ? И метод put_Visible() ?
Наверное, способов масса, но в итоге идет обращение или к методу приложения (Application), показывая/скрывая все видимые окна приложения, или к конкретному окну документа (Window).