Я пытаюсь встроить приложение Office 2007/2010 в JAVA-приложении с помощью SWT использующий следующего кода:
import java.awt.Canvas;
import javax.swing.JFrame;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.ole.win32.*;
import org.eclipse.swt.widgets.*;
public class EmbeddingTest extends Canvas {
private void initOleViewer(String target) {
Display display = new Display();
Shell shell = SWT_AWT.new_Shell(display, this);
shell.setLayout(new FillLayout());
OleFrame oleFrame = new OleFrame(shell, SWT.NONE);
OleControlSite oleControlSite = new OleControlSite(oleFrame, SWT.NONE, "Word.Document");
oleControlSite.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
OleAutomation word = new OleAutomation(oleControlSite);
int[] applicationId = word.getIDsOfNames(new String[]{"Application"});
Variant property = word.getProperty(applicationId[0]);
OleAutomation application = property.getAutomation();
int[] documentId = application.getIDsOfNames(new String[]{"Documents"});
property = application.getProperty(documentId[0]);
OleAutomation documents = property.getAutomation();
shell.open();
Variant[] arguments = new Variant[] { new Variant(target) };
int[] automationIDs = documents.getIDsOfNames(new String[]{"Open", "FileName"});
documents.invokeNoReply(automationIDs[0], arguments, new int[]{automationIDs[1]});
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
public static void main(String[] args) {
JFrame jFrame = new JFrame("Embedding Test");
jFrame.setVisible(true);
EmbeddingTest viewer = new EmbeddingTest();
jFrame.add(viewer);
jFrame.setSize(600, 600);
viewer.initOleViewer(args[0]);
}
}
Когда я не пытаюсь назвать 'Открытым' на объекте документа, Word встраивает успешно в приложении, но целое меню файла отключено. Когда я называю 'Открытыми' сбои приложения со следующей ошибкой (DISP_E_EXCEPTION):
Exception in thread "main" org.eclipse.swt.SWTException: Action can not be performed. result = -2147352567 at org.eclipse.swt.ole.win32.OLE.error(Unknown Source) at org.eclipse.swt.ole.win32.OleAutomation.invokeNoReply(Unknown Source) at EmbeddingTest.initOleViewer(EmbeddingTest.java:68) at EmbeddingTest.main(EmbeddingTest.java:88)
Запросы идентификаторов для 'Открытого' и 'Имени файла' отдельно возвращают пустой указатель для 'Имени файла' так его неправильное. Я также попробовал без именованного параметра без любого успеха:
documents.invokeNoReply(automationIDs[0], arguments);
Используйте FileShare.Read
, чтобы разрешить чтение только из других приложений. Вы можете заблокировать файл, открыв поток во время работы приложения A. Вам нужен NonClosingStreamWrapper
, чтобы избежать утилизации потока при утилизации StreamWriter
(это происходит автоматически при использовании
)
NonClosingStreamWrapper
. Jon Skeet можно найти с здесь
При запуске приложения используйте это для блокировки файла
FileStream fileStream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);
При записи в файл используйте
using (StreamWriter sr = new StreamWriter(new NonClosingStreamWrapper(fileStream)))
{
// File writing as usual
}
При завершении приложения используйте это для освобождения файла
fileStream.Close();
-... 121---2827084- Почему вы не делаете никакой обработки ошибок, проверки результатов или утверждений? Помните, что getIDsOfNames(...)
будет тихо проваливаться и возвращать null
значения для нераспознанных имен.
Попробуйте распечатать значение documents.getLastError()
после поимки исключения.