Меню

Eoleexception ошибка при вызове метода processdata интерфейса

Обновлено 27.08.2022

ошибка

Добрый день! Уважаемые читатели IT блога Pyatilistnik.org, в прошлый раз мы с вами разобрали за, что отвечает библиотека vcruntime140.dll и на сколько она важна для работы многих программ. Сегодня я хочу вам рассказать, об интересном случае, когда специализированный софт может не получить доступ к удаленному компьютеры по RPC протоколу из-за новых политик безопасности DCOM. В логах будет фигурировать событие об ошибке DCOM ID 10036 «политика уровня проверки подлинности на стороне сервера не разрешает пользователю». Давайте смотреть в чем дело.

❌Описание ошибки DCOM ID 10036 (EOleException)

Обратился ко мне мой коллега с просьбой показать ему, как отправлять сообщение всем пользователям терминального хоста. Я предложил ему бесплатную утилиту Terminal Services Manager и подумал, что задача выполнена, но не тут то было. Коллега сказал, что у него не подключается к RDSH хосту и высвечивается ошибка доступа. Я решил так же проверить данную ситуацию.

Запустив Terminal Services Manager, в логе я увидел вот такую ошибку подключения:

EOleException

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

ID 10036: Политика уровня проверки подлинности на стороне сервера не разрешает пользователю ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) с адреса 10.11.11.210 для активации DCOM-сервера. Повысьте уровень проверки подлинности активации, чтобы RPC_C_AUTHN_LEVEL_PKT_INTEGRITY в клиентском приложении. («The server-side authentication level policy does not allow the user ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) from address 10.11.11.210 to activate DCOM server. Please raise the activation authentication level at least to RPC_C_AUTHN_LEVEL_PKT_INTEGRITY in client application.»)

ID 10036

Давайте выяснять в чем дело и как это можно обойти.

⚙️Причина ошибки DCOM ID 10036

Первое, что я стал изучать, что такое RPC_C_AUTHN_LEVEL_PKT_INTEGRITY. В итоге я наткнулся на статью Microsoft о константах уровня аутентификации.

Константы уровня аутентификации представляют собой уровни аутентификации, передаваемые различным функциям времени выполнения. Эти уровни перечислены в порядке возрастания аутентификации. Каждый новый уровень добавляет к аутентификации, обеспечиваемой предыдущим уровнем. Если библиотека времени выполнения RPC не поддерживает указанный уровень, она автоматически обновляется до следующего более высокого поддерживаемого уровня.

В итоге есть вот такой список констант:

  • RPC_C_AUTHN_LEVEL_DEFAULT — Использует уровень проверки подлинности по умолчанию для указанной службы проверки подлинности.
  • RPC_C_AUTHN_LEVEL_NONE — Не выполняет аутентификацию.
  • RPC_C_AUTHN_LEVEL_CONNECT — Аутентифицируется только тогда, когда клиент устанавливает связь с сервером.
  • RPC_C_AUTHN_LEVEL_CALL — Выполняет аутентификацию только в начале каждого вызова удаленной процедуры, когда сервер получает запрос. Не применяется к удаленным вызовам процедур, выполненным с использованием последовательностей протоколов на основе соединения (тех, которые начинаются с префикса «ncacn»). Если последовательность протокола в дескрипторе привязки представляет собой последовательность протокола на основе соединения, и вы указываете этот уровень, эта процедура вместо этого использует константу RPC_C_AUTHN_LEVEL_PKT.
  • RPC_C_AUTHN_LEVEL_PKT — Аутентифицирует только то, что все полученные данные получены от ожидаемого клиента. Не проверяет сами данные.
  • RPC_C_AUTHN_LEVEL_PKT_INTEGRITY — Аутентифицирует и проверяет, что никакие данные, передаваемые между клиентом и сервером, не были изменены.
  • RPC_C_AUTHN_LEVEL_PKT_PRIVACY — Включает все предыдущие уровни и гарантирует, что данные в открытом виде могут быть видны только отправителю и получателю. В локальном случае это предполагает использование безопасного канала. В удаленном случае это включает шифрование значения аргумента каждого удаленного вызова процедуры.

Теперь стало понятно, за что отвечает RPC_C_AUTHN_LEVEL_PKT_INTEGRITY и видимо Microsoft, ужесточила какую-то политику безопасности, я стал изучать вопрос дальше. Поиск ошибки DCOM ID 10036 привел меня ну обсуждение нового обновления KB5004442, которое как я выяснил и вызывает эту ситуацию.

KB5004442 призвана усилить защиту DCOM объектов. Удаленный протокол модели распределенных компонентов (DCOM) — это протокол для предоставления объектов приложений с помощью удаленных вызовов процедур (RPC). DCOM используется для связи между программными компонентами сетевых устройств. Многие из нас на самом деле не понимают этого, и мы не можем диагностировать ошибки DCOM в наших журналах событий, которые, по-видимому, не оказывают серьезного влияния на наши сети. Эта технология представляет собой протокол для предоставления объектов приложения с помощью удаленных вызовов процедур (RPC).

RPC являются ключевой частью Windows. RPC — это клиент-серверный протокол, который разработчики приложений могут использовать для вызова процедур на локальном или удаленном узле в сети. Детали подключения и сортировка данных выполняются за кулисами на уровне RPC, что дает разработчикам средства для прямого подключения клиентских приложений к удаленному компьютеру. Это позволяет разработчикам не беспокоиться о знании деталей того, как данные передаются между двумя машинами и как вызываются процедуры.

С обновлениями безопасности от 14 июня 2022 г. RPC_C_AUTHN_LEVEL_PKT_INTEGRITY на серверах DCOM теперь включен по умолчанию. Клиент, которому это необходимо, может отключить его с помощью раздела реестра RequireIntegrityActivationAuthenticationLevel.

Согласно бюллетеню, злоумышленник сначала воспользуется уязвимостью, предложив клиенту DCOM каким-либо образом подключиться к специально созданному серверу, как правило, отправив пользователю фишинговое электронное письмо, чтобы завладеть системой. Затем злоумышленник использует эту информацию для доступа к серверу DCOM, а затем скомпрометирует его. Патч исправляет и усиливает аутентификацию, используемую между клиентами и серверами DCOM.

Я проверил RDSH хосты и действительно там прилетело данное обновление. Microsoft пока полностью не закрутило данную политику безопасности и ее еще можно обойти, но самое правильное, это доделать приложение, чтобы оно при обращении к серверу и запросе данных выполняло все требования вендора. На текущий момент есть вот такой график внедрения:

  1. 8 июня 2021 г. — Изменения защиты отключены по умолчанию, но с возможностью включить их с помощью ключа реестра.
  2. 14 июня 2022 г. — Защитные изменения включены по умолчанию, но с возможностью отключить их с помощью ключа реестра.
  3. 14 марта 2023 г.Усиление изменений включено по умолчанию, отключить их невозможноК этому моменту вы должны решить все проблемы совместимости с усиливающими изменениями и приложениями в вашей среде.

Еще список обновлений несущих данное изменение: Windows Server 2022 — KB5005619, KB5005568. Windows 10, version 2004, Windows 10, version 20H2, Windows 10, version 21H1 — KB5005101. Windows Server 2019, Windows 10, version  1809 — KB5005102. Windows Server 2016, Windows 10, version 1607 — KB5005573. Windows Server 2012 R2 and Windows 8.1 — KB5006714. Данный список всегда меняется, так что смотрите в каталоге центра обновлений, что чем заменяется (https://www.catalog.update.microsoft.com/).

Сведения об обновлении

Так же помимо события ID 10036, есть еще два:

ID 10037: «Приложение %1 с PID %2 запрашивает активацию CLSID %3 на компьютере %4 с явно заданным уровнем аутентификации %5. Минимальный уровень аутентификации активации, требуемый DCOM, — 5 (RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). Чтобы повысить уровень аутентификации активации, пожалуйста, обратитесь к поставщику приложения». («Application %1 with PID %2 is requesting to activate CLSID %3 on computer %4 with explicitly set authentication level at %5. The lowest activation authentication level required by DCOM is 5(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). To raise the activation authentication level, please contact the application vendor.»)

ID 10038: «Приложение %1 с PID %2 запрашивает активацию CLSID %3 на компьютере %4 с уровнем аутентификации активации по умолчанию %5. Минимальный уровень аутентификации активации, требуемый DCOM, — 5 (RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). Чтобы повысить уровень аутентификации активации, пожалуйста, обратитесь к поставщику приложения». («Application %1 with PID %2 is requesting to activate CLSID %3 on computer %4 with default activation authentication level at %5. The lowest activation authentication level required by DCOM is 5(RPC_C_AUTHN_LEVEL_PKT_INTEGRITY). To raise the activation authentication level, please contact the application vendor.»)

  • %1 — путь к приложению
  • %2 — PID приложения
  • %3 — CLSID класса COM, который приложение запрашивает для активации
  • %4 — имя компьютера
  • %5 — значение уровня аутентификации

💡Как устранить ошибку ID 10036

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

ID 10036: Политика уровня проверки подлинности на стороне сервера не разрешает пользователю ROOTsem SID (S-1-5-21-551888299-3078463796-123456789-46162) с адреса 10.11.11.210 для активации DCOM-сервера. Повысьте уровень проверки подлинности активации, чтобы RPC_C_AUTHN_LEVEL_PKT_INTEGRITY в клиентском приложении.

Тут IP-адрес откуда идет подключение 10.11.11.210, там и нужно установить все возможные обновления безопасности.

Установка обновлений Windows 10

Как только я обновился, ошибка EOleException ушла и мой Terminal Services Manager успешно подключился к серверу.

Terminal Services Manager успешное подключение

Если по каким, то причинам ваше приложение не заработало, а вам нужно, то есть лазейка до 2023 года в виде ключа реестра, который вы должны добавить на сервере, куда вы пытаетесь производить подключение. Запустите реестр Windows и перейдите в раздел:

HKEY_LOCAL_MACHINESOFTWARE MicrosoftOleAppCompat

И создайте там ключ реестра с типом REG_DWORD (32-бита) с именем RequireIntegrityActivationAuthenticationLevel.

  • RequireIntegrityActivationAuthenticationLevel = 0x00000000 выключает политику
  • RequireIntegrityActivationAuthenticationLevel = 0x00000001 включает политику

не забываем после создания ключа в реестре Windows произвести перезагрузку сервера

RequireIntegrityActivationAuthenticationLevel

Если и данный метод вам не помог, то как крайняя мера может быть, это удаление обновления. Посмотрите список установленных обновлений командой:

wmic qfe list

После чего просто прочитайте инструкцию, как это сделать. Надеюсь, что вам оказалась полезна данная статья, и вы устранили ошибку EOleException. Если остались вопросы, то пишите их в комментариях. С вами был Иван Сёмин, автор и создатель IT портала Pyatilistnik.org.

Дополнительные ссылки

  • https://docs.microsoft.com/en-us/windows/win32/rpc/authentication-level-constants
  • https://support.microsoft.com/en-us/topic/kb5004442-manage-changes-for-windows-dcom-server-security-feature-bypass-cve-2021-26414-f1400b52-c141-43d2-941e-37ed901c769c
  • https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26414

 
Василич
 
(2002-09-19 19:16)
[0]

Здравствуйте ! Подскажите, пожалуйста, вследствие чего появляется ошибка «EOLEException. Не удается найти строку для обновления. Некоторые значения могли быть изменены со времени ее последнего чтения». Ошибка выдается после метода Post или Requery. Везде искал, не могу найти даже описания ошибки.


 
Василич
 
(2002-09-20 10:29)
[1]

Ребята, ну неужто никто не знает ?


 
Johnmen
 
(2002-09-20 10:40)
[2]

Так поищи в этой конфе…

Данный вопрос задается с завидной регулярностью…:))))


 
Василич
 
(2002-09-20 11:35)
[3]

Подобный вопрос отсутствует. Самое интересное, что трассировка запроса с помощью SQL Profiler ничего не дает !


 
Юрий Жуков
 
(2002-09-20 13:09)
[4]

Я так понимаю ты на ADO пишеь?

Тогда тебе идти на королевство Дельфи.

Читать здесь:

http://www.delphikingdom.com/helloworld/ado01.htm

http://www.delphikingdom.com/helloworld/ado02.htm

http://www.delphikingdom.com/helloworld/ado03.htm

Тригера в таблицах есть?


 
Василич
 
(2002-09-20 15:25)
[5]

Recordset.Properties[«Update Resync»].Value := adResyncNone;;

Recordset.Properties[«Update Criteria»].Value := adCriteriaAllCols;

Все равно не работает !!!


 
Юрий Жуков
 
(2002-09-20 16:00)
[6]

А тригера в таблицах есть? А автоинкрементные поля?

А первичный ключ? А подумай сам чего ты еще утаил?

И лучше используй так:

Recordset.Properties[«Update Criteria»].Value := adCriteriaKey

А еще лучше пропиши

Recordset.Properties[«Resync Command»].Value := » бла — бла…»


 
Василич
 
(2002-09-20 16:04)
[7]

Триггеров нет, автоинкрементное поле есть. Таблица представляет из себя кучу полей типа ID, связана с другими, дочерними таблицами. Редактирование делается простым присваиванием FieldByName(«FieldName»).AsString :=»бла-бла»

Recordset.Properties[«Update Resync»].Value := adResyncAutoIncrement + adResyncInserts;;

Recordset.Properties[«Update Criteria»].Value := adCriteriaAllCols;

if not InTransaction then

BeginTrans;

Edit;

FieldByName(«Field1»).AsString := ComboBox1.Text;

………………………

Post;

CommitTrans;

Requery();

и после Post вылетает эта ошибка.


 
Юрий Жуков
 
(2002-09-20 16:40)
[8]

Ну я тебе почти правильно сказал:

Recordset.Properties[«Update Criteria»].Value := adCriteriaKey

Обовлять запись будет по первичным ключам

Если это не поможет, то ставь

Recordset.Properties[«Resync Command»].Value := » бла — бла…»

Ну если это не поможет то разве что можно на запрос посмотреь..


 
Василич
 
(2002-09-20 16:47)
[9]

И что мне писать в это «bla-bla» ?


 
Василич
 
(2002-09-20 18:06)
[10]

Это все, к сожалению, не помогает.


 
Юрий Жуков
 
(2002-09-20 19:15)
[11]

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

http://www.delphikingdom.com/helloworld/ado03.htm

Цитата:

в этом свойстве задается команда, с помощью которой должна быть обновлена текущая строка, основываясь на значении колонок из таблицы, имя которой заданно свойством «Unique Table»

Ну а апдейты к D6 стоят? Что еще посоветовать не знаю, может сам еще чего скажешь?


 
Василич
 
(2002-09-23 09:45)
[12]

DataModule1.ADODataset1.Properties["Update Resync"].Value := adResyncInserts + adResyncUpdates;

DataModule1.ADODataset1.Properties["Update Criteria"].Value := adCriteriaKey;

DataModule1.ADODataset1.Properties["Unique Table"].Value := "Computers";

DataModule1.ADODataset1.Properties["Resync Command"].Value := ResyncCommand;

ResyncCommand := "SELECT C.ComputerID AS "


 
Василич
 
(2002-09-23 10:40)
[13]

Я немного понял. Для того, чтобы Update отрабатывался нормально,
ВСЕ поля в таблице должны быть заполнены (не равны NULL). Может, следует каким-то образом изменить запрос ?


 
Василич
 
(2002-09-23 11:15)
[14]

А это результат трассировки запроса. Никаких ошибок, никаких предупреждений…

exec sp_executesql N"UPDATE "Mspi"."dbo"."Computers" SET "ComputerID"=@P1,"Address"=@P2,"Cabinet"=@P3 WHERE "KeyField"=@P4", N"@P1 bigint,@P2 nvarchar(10),@P3 int,@P4 int", 545445, N"Ленина, 57", 21, 12

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Xeroxes" SET "Xerox"=@P1 WHERE "XeroxID" IS NULL", N"@P1 varchar(1)", ""

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Scanners" SET "Scanner"=@P1 WHERE "ScannerID"=@P2", N"@P1 varchar(4),@P2 int", "UMAX", 6

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Printers" SET "Printer"=@P1 WHERE "PrinterID"=@P2", N"@P1 varchar(29),@P2 int", "Hewlett-Packard LaserJet 1100", 4

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Monitors" SET "Monitor"=@P1 WHERE "MonitorID"=@P2", N"@P1 varchar(19),@P2 int", "SAMSUNG Samtron 75E", 3

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."EtherCards" SET "EtherCard"=@P1 WHERE "EtherCardID"=@P2", N"@P1 varchar(16),@P2 int", "Surecom 100 Mbit", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."SoundBlasters" SET "SoundBlaster"=@P1 WHERE "SoundBlasterID" IS NULL", N"@P1 varchar(1)", ""

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."CDROMs" SET "CDROM"=@P1 WHERE "CDROMID"=@P2", N"@P1 varchar(8),@P2 int", "ASUS 50x", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."HDDs" SET "HDD"=@P1 WHERE "HDDID"=@P2", N"@P1 varchar(14),@P2 int", "IBM DTLA 30 Gb", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."VideoCards" SET "VideoCard"=@P1 WHERE "VideoCardID"=@P2", N"@P1 varchar(22),@P2 int", "GeForce 4 Ti4600 64 Mb", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."RAMs" SET "RAM"=@P1 WHERE "RAMID"=@P2", N"@P1 smallint,@P2 int", 32, 5

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Motherboards" SET "Motherboard"=@P1 WHERE "MotherboardID"=@P2", N"@P1 varchar(4),@P2 int", "Abit", 2

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Processors" SET "Processor"=@P1 WHERE "ProcessorID"=@P2", N"@P1 varchar(35),@P2 int", "Intel Celeron 333 Mhz", 16

go

exec sp_executesql N"UPDATE "Mspi"."dbo"."Faculties" SET "Faculty"=@P1 WHERE "FacultyID"=@P2", N"@P1 nvarchar(29),@P2 int", N"Кафедра, 18

go

SELECT N"Testing Connection..."

go

EXECUTE msdb.dbo.sp_sqlagent_get_perf_counters

go

Блин, что делать-то ?


 
MOA
 
(2002-09-23 13:05)
[15]

1.А вот это:

exec sp_executesql N»UPDATE «Mspi».»dbo».»Xeroxes» SET «Xerox»=@P1 WHERE «XeroxID» IS NULL», N»@P1 varchar(1)», «»

нормально («XeroxID» IS NULL)?

2. У Вас действительно при апдейте детайл-таблицы должны обновляться ВСЕ мастер-таблицы? Так и задумано?


 
Юрий Жуков
 
(2002-09-23 13:22)
[16]

Ну по крайней мере видно, что вот здесь точно будет ошибка:

exec sp_executesql N»UPDATE «Mspi».»dbo».»Xeroxes» SET «Xerox»=@P1 WHERE «XeroxID» IS NULL», N»@P1 varchar(1)», «»

Да ты прав, в этом результирующем запросе все поля должны быть заполнены, что-бы АДО мог пострить по ним SQL для Update для всех подчиненных таблиц (ты ведь нигде не указал UniqueTable). Насколько я знаю нельзя указать несколько уникальных таблиц для ADODATASET.

Думаю тебе следует исользовать Uniquetable:=»Faculties»;

А редактирование всех остальных датасетов оформить в виде справочников


 
Василич
 
(2002-09-23 14:53)
[17]

Редактирование остальных датасетов и так оформлено в виде справочников. Я же на самом деле редактирую не справочник (т.е. не таблицу Xeroxes), а сводную, в которой находится XeroxID.

>MOA

По идее, мастер-таблицы обновляться не должны. Пытался снять у таблицы опцию Enforce relationship for INSERTS and UPDATES, толку никакого.

Как бы там ни было, мне все-таки требуется, чтобы в некоторые поля можно было воткнуть NULL (не во всех кабинетах есть ксероксы, образно говоря). Не подскажете ли Вы, как избавиться от принудительного обновления мастер-таблиц и уничтожить в корне эту проклятую ошибку ?


 
MOA
 
(2002-09-23 15:22)
[18]

>уничтожить в корне эту проклятую ошибку

Я бы сделал так:

1.Запрос:

«SELECT C.ComputerID AS «


 
Юрий Жуков
 
(2002-09-23 15:42)
[19]

очень странно…

так ты говоришь поставил свойство

Properties[«Unique Table»].Value := «Computers»?

Но судя по логу профайлера ADO все равно пытается апдейтить все таблицы.


 
Василич
 
(2002-09-26 14:05)
[20]

Ничего у меня не получается. Для интереса создал уникальный индекс во всех родительских таблицах, последовал всем советам MOA, и ничего не работает !!! Судя по вылетающей в этот раз ошибке («Cannot insert duplicate key») SQL Server действительно пытается засунуть записи в родительские таблицы, хотя ясно указаны все динамические свойства типа Resync Command и Unique Table. Подскажите, как избавиться от этой нездоровой тенденции SQL-сервера апдейтить таблицы, которые совершенно не нужно апдейтить !


 
Юрий Жуков
 
(2002-09-26 14:32)
[21]

Эт тебе не SQL сервер надо укрощать, а ADO.

И бороть нужно свойство «Unique table».

Попробуй компонент TBetterAdoDataSet (
http://web.orbitel.bg/vassil/), там можно его disign-time задать.


 
MOA
 
(2002-09-26 15:10)
[22]

Может, так:?

1. Если не хочется отказываться от VIEW — добавить отдельные DataSet-ы на вставку — обновление — удаление и перехватывать соответсвующие события, не давая «основному» датасету вставлять-удалять-обновлять

Или

2. В «Основном» датасете обращаться к детайл-таблице, оформив поля из мастер-таблиц как Lookup поля. Понадобится дополнительно столько датасетов, сколько мастер-таблиц — но обновления-удаления-вставки будут работать как ожидается + бонус — автоматом появится возможность юзеру выбирать нужные значения из Lookup-ов.

Любая таблица должна иметь PRIMARY KEY. И мастер — тоже. И это — ключ для ссылки из детайл.

А дублирующиеся ключи — это точно не ключи в детайл-таблице?

Удачи!


 
MOA
 
(2002-09-26 15:25)
[23]

И еще.

1.У Вас пользователи вводят НАЗВАНИЯ? Из, возможно, формируемого программой списка? — Если так, то так не надо бы…

2.У Вас стоит у VIEW опция VIEW_METADATA?

Удачи!


 
MOA
 
(2002-09-26 16:04)
[24]

Sorry, забыл, что у Вас не VIEW, a SELECT.

НО все же — попробуйте в SELECT выбирать только ссылки на мастер-таблицы (ID), а не названия.

Удачи!


 
Василич
 
(2002-09-26 16:08)
[25]

Похоже, этот кошмар никогда не кончится. Сделал все по вашим советам: lookup-поля, куча датасетов, по одному на каждую таблицу, даже не датасеты, а BetterADODataSets, черт бы их побрал. Насмотрелся на кучу новых ошибок, как например, сверхинформативное сообщение «Не удается вставить или обновить столбцы из нескольких таблиц», или, «При вызове ITransaction::Commit или ITransaction::Abort объект не отвечает на запросы». Короче, пора переквалифицироваться в дворники, всем спасибо за оказанную помощь.


 
MOA
 
(2002-09-26 16:13)
[26]

Покажите, пожалуйста, Ваш новый «основной» запрос.


 
Василич
 
(2002-09-26 16:16)
[27]

>MOA

Не совсем понятно, что в данном контексте означает «Названия» , вот запрос для сводной таблицы:

SELECT TOP 100 PERCENT C.ComputerID AS [Серийный номер компьютера], F.Faculty AS [Факультет/Отдел], P.Processor AS Процессор,

M.Motherboard AS [Материнская плата],

R.RAM AS [Оперативная память], V.VideoCard AS Видеоадаптер,

H.HDD AS [Жесткий диск], D.CDROM AS [Привод компакт-дисков],

S.SoundBlaster AS [Звуковая карта],

E.EtherCard AS [Сетевая карта], O.Monitor AS Монитор,

N.Printer AS Принтер, A.Scanner AS Сканер, X.Xerox AS Ксерокс,

B.Address AS Адрес, Cabinet AS Кабинет

FROM dbo.Computers C LEFT OUTER JOIN

dbo.Faculties F ON F.FacultyID = C.FacultyID LEFT OUTER JOIN

dbo.Processors P ON P.ProcessorID = C.ProcessorID LEFT OUTER JOIN

dbo.Motherboards M ON M.MotherboardID = C.MotherBoardID LEFT OUTER JOIN

dbo.RAMs R ON R.RAMID = C.RAMID LEFT OUTER JOIN

dbo.VideoCards V ON V.VideoCardID=C.VideoCardID LEFT OUTER JOIN

dbo.HDDs H ON H.HDDID = C.HDDID LEFT OUTER JOIN

dbo.CDROMs D ON D.CDROMID = C.CDROMID LEFT OUTER JOIN

dbo.SoundBlasters S ON S.SoundBlasterID = C.SoundBlasterID LEFT OUTER JOIN

dbo.EtherCards E ON E.EtherCardID = C.EtherCardID LEFT OUTER JOIN

dbo.Monitors O ON O.MonitorID = C.MonitorID LEFT OUTER JOIN

dbo.Printers N ON N.PrinterID = C.PrinterID LEFT OUTER JOIN

dbo.Scanners A ON A.ScannerID = C.ScannerID LEFT OUTER JOIN

dbo.Xeroxes X ON X.XeroxID=C.XeroxID LEFT OUTER JOIN

dbo.Addresses B ON B.AddressID = C.AddressID

ORDER BY F.Faculty

Сначала это был VIEW, потом я от него отказался и впихнул этот чудовищный запрос прямо в CommandText. Пытаюсь вставлять/редактировать его обычными методами типа Append/Edit/Post, и вылетают вышеназванные ошибки. От названий полей в данном случае отказаться не могу, а то получится не нормальный пользовательский интерфейс, а черт знает что.


 
MOA
 
(2002-09-26 16:35)
[28]

1. Русские названия полей = приключения. Воспользуйтесь Display label в свойстве поля.

2. Попробуйте такой запрос:

SELECT TOP 100 PERCENT C.ComputerID, C.FacultyID, C.ProcessorID,

C.MotherboardID, C.RAMID, C.VideoCardID, C.HDDID, C.CDROMID, C.SoundBlasterID, C.EtherCardID, C.MonitorID, C.PrinterID, C.ScannerID, C.XeroxID, C.AddressID, C.Cabinet

FROM dbo.Computers CORDER BY F.Faculty

Русские названия полей сделайте через Display label. Добавьте в получившийся датасет дополнительно Lookup поля для Faculity, Processor и т.д., поля с ID, соответственно, скройте от юзера (Display=False).

Всё должно поехать. Именно это я и имел в виду.

Удачи!


 
MOA
 
(2002-09-26 16:36)
[29]

Русские названия, конечно же, Вам понадобятся только для созданных Вами Lookup полей. Наверное, не нужно юзеру знать русское название поля ProcessorID, например.

Удачи!


I have a Delphi 6 professional program that is calling COM object methods belonging to an MSVC 2008 COM DLL. The DLL’s Type Library imported without error into Delphi. I can call one of the method’s without error, but most of the others lead to an EOleException error with the message «An unexpected exception was raised», which corresponds to the EOleException error code: 0x80040205,
EVENT_E_INTERNALEXCEPTION:

http://msdn.microsoft.com/en-us/library/cc704587(v=prot.10).aspx

I am calling CoInitialize before making the call:

var
    intfMsvcComObj: IMsvcComObject;

begin
    if not Succeeded(CoInitialize(nil)) then
        raise Exception.Create('Coinitialize failed.');

    intfMsvcComObj := CoMsvcComObject.Create;

    try
        // EOleException occurs when I make this call.
        intfMsvcComObj.doSomething;
    finally
        CoUninitialize;
    end;
end;

Next I tried turning of FPU exceptions because that sometimes is an issue when calling into MSVC DLLS using Set8087CW($133f) and then I tried again with Set8087CW(Get8087CW or $3f), but neither of those operations helped.

Any ideas on how to fix/diagnose this?

I have a Delphi 6 professional program that is calling COM object methods belonging to an MSVC 2008 COM DLL. The DLL’s Type Library imported without error into Delphi. I can call one of the method’s without error, but most of the others lead to an EOleException error with the message «An unexpected exception was raised», which corresponds to the EOleException error code: 0x80040205,
EVENT_E_INTERNALEXCEPTION:

http://msdn.microsoft.com/en-us/library/cc704587(v=prot.10).aspx

I am calling CoInitialize before making the call:

var
    intfMsvcComObj: IMsvcComObject;

begin
    if not Succeeded(CoInitialize(nil)) then
        raise Exception.Create('Coinitialize failed.');

    intfMsvcComObj := CoMsvcComObject.Create;

    try
        // EOleException occurs when I make this call.
        intfMsvcComObj.doSomething;
    finally
        CoUninitialize;
    end;
end;

Next I tried turning of FPU exceptions because that sometimes is an issue when calling into MSVC DLLS using Set8087CW($133f) and then I tried again with Set8087CW(Get8087CW or $3f), but neither of those operations helped.

Any ideas on how to fix/diagnose this?

Я сделал два компонента ActiveX в Delphi XE2 в отдельных проектах. Один из компонентов работает отлично, и каждое исключение, которое он выдает, маскируется как EOleException. На другом компоненте ActiveX исключения не маскируются, они генерируются как исходный тип. Клиент представляет собой программу delphi XE.

Когда компонент ActiveX выдает исходное исключение, следующий вызов любого другого метода из компонента выдает исключение нарушения прав доступа в тех местах, где он не должен, например, установка локальной строковой переменной со значением. Это очень странное поведение.

Я сравнил оба проекта: файл .ridl, параметры компиляции, файл .dproj и не смог найти виновника.

Кто-нибудь знает причину этой разницы/странного поведения?

благодаря

Изменить: какой-то код

Компонент 1, который работает (маскирует все исключения для EOleException)

TspdMyClassX = class(TActiveXComponent, MyInterface)

initialization


TActiveXComponentFactory.Create(
    ComServer,
    TspdMyClassX,
    CLASS_spdMyClassX,
    1,
    '',
    0,
    tmBoth);

Другой компонент, который не генерирует EOleException, имеет другой интерфейс, но остальная часть кода такая же (инициализация, родительский класс TActiveXComponent).

A Windows service when trying to access the .Body property of a MSMQ message object throws an EOleException — but only when the Xml document contained in this message has an empty list node.

The EOleException message complains about insufficient memory (exception code -2147024882). Since the exception only occurs with the smallest possible Xml document, memory cannot be the real issue. The next thing that comes to mind is a problem with access rights but then again all «good» messages (as described below) are processed without problems.

The exception can be reproduced under any thinkable condition («bad» message first, many «good» messages first — then «bad» message, run in debugger or just logging the exception); it doesn’t matter if the code shown below is run as a service or as a simple excecutable.

Using the same COM object (MSMQ.MSMQQueueInfo) from within a VBScript on the same machine does not produce any errors.

Accessing any other properties apart from .Body doesn’t throw an exception so the message object instance seems to be received sucessfully. Also the transaction receiving the message can be comitted sucessfully if the .Body property is not accessed.


Windows Service code

//...
qInfo    := CreateOleObject('MSMQ.MSMQQueueInfo');
qTxDisp  := CreateOleObject('MSMQ.MSMQTransactionDispenser');
//...
qTx := qTxDisp.BeginTransaction;
qMessage := qQueue.Receive(qTx, False, True, 0);
//...
sBody := qMessage.Body; //throws EOleException

The qMessage.BodyLength property returns the value 165 for «bad» messages as shown below.

«Bad» message

<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
    <query>
        <entrylist count="0">
        </entrylist>
    </query>
</response>

This message reliably makes the service code throw an EOleExecption.

«Good» message

<?xml version="1.0" encoding="Windows-1252"?>
<response space="" Message="Entry_7">
    <query>
        <entrylist count="2">
            <entry>
                <abc>123</abc>
                <def>456</def>
            </entry>
            <entry>
                <abc>789</abc>
                <def>000</def>
            </entry>
        </entrylist>
    </query>
</response>

This message is reliably processed without problems.

The problem first occured when moving the service from a Win2003 machine to a Win2008 (32-bit Standard).

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Eof when reading a line python ошибка input
  • Eof in multi line statement ошибка