Я создал приложение.NET C#, которое использует Adobe ActiveX control для отображения PDF.
Это полагается на пару DLLs, который поставляется с приложением. Эти DLLs взаимодействуют с локально установленной Adobe Acrobat или Adobe Acrobat Reader, установленным на машине.
Это приложение уже используется некоторым клиентом и работает отлично почти для всех пользователей (я проверяю, чтобы видеть, что локальная машина уже выполняет, по крайней мере, версию 9 или Acrobat или Читателя).
Я нашел 3 случая, куда приложение возвращает сообщение об ошибке "Ошибка, HRESULT E_FAIL был возвращен от вызова до COM-компонента" при попытке загрузиться (когда элемент управления ActiveX загружается).
Я проверил одну из машин этого пользователя, и ему установили Acrobat 9 и использует его часто без проблем. Действительно кажется, что Acrobat 7 и 8 был установлен когда-то, так как существуют записи для них в реестре наряду с Acrobat 9.
Я не могу воспроизвести эту проблему локально, таким образом, я не уверен точно который направление пойти.
Ошибка наверху stacktrace: Система. Время выполнения. InteropServices. COMException (0x80004005): Ошибка HRESULT E_FAIL была возвращена от вызова до COM-компонента.
Некоторое исследование этой ошибки указывает, что это - проблема реестра.
У кого-либо есть подсказка относительно того, как зафиксировать или работать вокруг этой проблемы или определить, как добраться до базового корня проблемы?
Полное содержание сообщения об ошибке - это:
Система. Время выполнения. InteropServices. COMException (0x80004005): Ошибка HRESULT E_FAIL была возвращена от вызова до COM-компонента. в System. Windows. Формы. UnsafeNativeMethods. CoCreateInstance (Guid& clsid, Объект punkOuter, контекст Int32, Guid& iid) в System. Windows. Формы. AxHost. CreateWithoutLicense (Гуид clsid) в System. Windows. Формы. AxHost. CreateWithLicense (Строковая лицензия, Гуид clsid) в System. Windows. Формы. AxHost. CreateInstanceCore (Гуид clsid) в System. Windows. Формы. AxHost. CreateInstance () в Системе. Windows. Формы. AxHost. GetOcxCreate () в Системе. Windows. Формы. AxHost. TransitionUpTo (состояние Int32) в System. Windows. Формы. AxHost. CreateHandle () в Системе. Windows. Формы. Управление. CreateControl (булевская переменная fIgnoreVisible) в System. Windows. Формы. Управление. CreateControl (булевская переменная fIgnoreVisible) в System. Windows. Формы. AxHost. EndInit () в AcrobatChecker. Средство просмотра. InitializeComponent () в AcrobatChecker. Средство просмотра.. ctor () в AcrobatChecker. Form1.btnViewer_Click (Объектный отправитель, EventArgs e) в System. Windows. Формы. Управление. OnClick (EventArgs e) в Системе. Windows. Формы. Кнопка. OnClick (EventArgs e) в Системе. Windows. Формы. Кнопка. OnMouseUp (MouseEventArgs mevent) в System. Windows. Формы. Управление. WmMouseUp (Message& m, кнопка MouseButtons, щелчки Int32) в Системе. Windows. Формы. Управление. WndProc (Message& m) в Системе. Windows. Формы. ButtonBase. WndProc (Message& m) в Системе. Windows. Формы. Кнопка. WndProc (Message& m) в Системе. Windows. Формы. Управление. ControlNativeWindow. OnMessage (Message& m) в Системе. Windows. Формы. Управление. ControlNativeWindow. WndProc (Message& m) в Системе. Windows. Формы. NativeWindow. Обратный вызов (IntPtr hWnd, сообщение Int32, IntPtr wparam, IntPtr lparam)
Хорошо, возвращаюсь к ответу на свой вопрос.
Проблема была напрямую связана с настройкой «Отображать PDF в браузере» в разделе «Настройки»> «Интернет». Если этот флажок установлен, проблема исчезнет. Когда он не отмечен, он возвращается.
Вот как мы предлагаем обрабатывать это программно:
private string defaultPdfProg()
{ //Returns the default program for opening a .pdf file; On Fail returns empty string.
// (see notes below)
string retval = "";
RegistryKey pdfDefault = Registry.ClassesRoot.OpenSubKey(".pdf").OpenSubKey("OpenWithList");
string[] progs = pdfDefault.GetSubKeyNames();
if (progs.Length > 0)
{
retval = progs[1];
string[] pieces = retval.Split('.'); // Remove .exe
if (pieces.Length > 0)
{
retval = pieces[0];
}
}
return retval;
}
private void browserIntegration(string defaultPdfProgram)
{ //Test if browser integration is enabled for Adobe Acrobat (see notes below)
RegistryKey reader = null;
string[] vers = null;
if (defaultPdfProgram.ToLower() == "acrobat")
{ //Default program is Adobe Acrobat
reader = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe").OpenSubKey("Adobe Acrobat");
vers = reader.GetSubKeyNames();
}
else if (defaultPdfProgram.ToLower() == "acrord32")
{ //Default program is Adobe Acrobat Reader
reader = Registry.LocalMachine.OpenSubKey("Software").OpenSubKey("Adobe").OpenSubKey("Acrobat Reader");
vers = reader.GetSubKeyNames();
}
else
{
//TODO: Handle non - adobe .pdf default program
}
if (vers.Length > 0)
{
string versNum = vers[vers.Length - 1].ToString();
reader = reader.OpenSubKey(versNum);
reader = reader.OpenSubKey("AdobeViewer",true);
Boolean keyExists = false;
Double keyValue = -1;
foreach(string adobeViewerValue in reader.GetValueNames())
{
if (adobeViewerValue.Contains("BrowserIntegration"))
{
keyExists = true;
keyValue = Double.Parse(reader.GetValue("BrowserIntegration").ToString());
}
}
if (keyExists == false || keyValue < 1)
{
string message = "This application requires a setting in Adobe to be changed. Would you like to attempt to change this setting automatically?";
DialogResult createKey = MessageBox.Show(message, "Adobe Settings", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
if (createKey.ToString() == "OK")
{
reader.SetValue("BrowserIntegration", 1, RegistryValueKind.DWord);
//test to make sure registry value was set
}
if (createKey.ToString() == "Cancel")
{
//TODO: Provide instructions to manually change setting
}
}
}
}
Несколько моментов, на которые следует обратить внимание:
Кто-нибудь знает, являются ли эти местоположения взаимозаменяемыми во всех версиях или в зависимости от конкретных версий Acrobat ключ реестра находится в разных местах? Следует ли Reader той же логике, что и Acrobat?
Для моей системы (Windows XP, Adobe Reader 9.3.2) ваше решение не сработало (но дало мне достаточно вдохновения, СПАСИБО!!!)
private void browserIntegration(string defaultPdfProgram)
{
try
{
RegistryKey reader = null;
string[] vers = null;
#region Walters Versuch
reader = Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Adobe");
reader = reader.OpenSubKey("Acrobat Reader");
vers = reader.GetSubKeyNames();
if (vers.Contains<string>("9.0"))
{
reader = reader.OpenSubKey("9.0");
reader = reader.OpenSubKey("Originals", true);
if (reader.GetValueNames().Contains<string>("bBrowserIntegration"))
reader.SetValue("bBrowserIntegration", 1, RegistryValueKind.DWord);
// wenn der Key fehlt ist Browserintegration auch angeschaltet
// alternativ: reader.DeleteSubKey("bBrowserIntegration", false);
}
else
MessageBox.Show(
"In case you run into problems later, please make sure yourself to select\n'Show PDF in Browser' in Acrobat Reader's Settings"
, "Unknown Version of Acrobat Reader");
#endregion
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\n" + ex.StackTrace
+ "\nIn case you run into problems later, please make sure yourself to select\n'Show PDF in Browser' in Acrobat Reader's Settings"
, "Error while switching on 'Browserintegration' in 'Acrobat Reader'");
}
}