Ошибка выполнения Delphi 217 при запуске приложения (ошибка утверждения (C:\\tmssoftware\TMS VCL UI Pack\AdvXPVS.pas, строка 1536)

После обновления с «TMS ComponentPack» до «TMS VCL UI Pack» приложение, установленное в Windows 7 или Windows 8.1, после запуска вылетает с ошибкой RunTime Error 217.

Это же приложение работает на Windows 10 или Windows Server 2012.

Используя EurekaLog, я вижу, что конкретной ошибкой является ошибка утверждения в AdvXPVS.pas в строке 1536 во время процедуры вызова LOADDLL.

Я не могу отлаживать приложение, потому что моя платформа разработки установлена ​​​​в Windows 10.

procedure LoadDLL;
begin
  if DLLLoaded then Exit;

  DLLHandle := LoadLibrary('UXTHEME.DLL');
  if DLLHandle >= 32 then
  begin
    DLLLoaded := True;

    @OpenThemeDataForDpi := GetProcAddress(DLLHandle,'OpenThemeDataForDpi');
    Assert(@OpenThemeDataForDpi <> nil);

    //********************************************************* 
    // LINE 1536 START FROM HERE 
    //********************************************************* 
    @OpenThemeData := GetProcAddress(DLLHandle,'OpenThemeData');
    Assert(@OpenThemeData <> nil);

    @CloseThemeData := GetProcAddress(DLLHandle,'CloseThemeData');
    Assert(@CloseThemeData <> nil);

    @DrawThemeBackground := GetProcAddress(DLLHandle,'DrawThemeBackground');
    Assert(@DrawThemeBackground <> nil);


    ...
    ...

    @EnableTheming := GetProcAddress(DLLHandle,'EnableTheming');
    Assert(@EnableTheming <> nil);
  end
  else
  begin
    DLLLoaded := False;
    { Error: UXTHEME.DLL could not be loaded !! }
  end;

end;

Информация об ассемблере:

---------------------------------------------------------------------------
; Base Address: $1012000, Allocation Base: $400000, Region Size: 10563584
; Allocation Protect: PAGE_EXECUTE_WRITECOPY, Protect: PAGE_EXECUTE_READ
; State: MEM_COMMIT, Type: MEM_IMAGE
; 
;
; AdvXPVS.LoadDLL (Line=0 - Offset=33)
; ------------------------------------
01012459  8903            MOV  [EBX], EAX
0101245B  833B20          CMP  DWORD PTR [EBX], $20
0101245E  0F825F080000    JB   +$085F                  ; ($01012CC3) AdvXPVS.LoadDLL (Line=0)
01012464  C605CC26A60101  MOV  BYTE PTR [$01A626CC], 1
0101246B  68E82C0101      PUSH $01012CE8               ; ($01012CE8) AdvXPVS.LoadDLL (Line=0) Data as ANSI: 'O'; Data as UNICODE: 'OpenThemeDataFor...' AdvXPVS.LoadDLL (Line=0)
01012470  8B03            MOV  EAX, [EBX]
01012472  50              PUSH EAX
01012473  E864DE40FF      CALL -$BF219C                ; ($004202DC) Winapi.GetProcAddress
01012478  8BF0            MOV  ESI, EAX
0101247A  8935C844BA01    MOV  [$01BA44C8], ESI
01012480  85F6            TEST ESI, ESI
01012482  7514            JNZ  +$14                    ; ($01012498) AdvXPVS.LoadDLL (Line=0)
01012484  B900060000      MOV  ECX, $00000600
01012489  BA1C2D0101      MOV  EDX, $01012D1C          ; ($01012D1C) AdvXPVS.LoadDLL (Line=0) UNICODE: 'C:\Users\Gianluca\Documents\tmssoftware\TMS VCL UI Pack\AdvXPVS.pas' AdvXPVS.LoadDLL (Line=0)
0101248E  B8B02D0101      MOV  EAX, $01012DB0          ; ($01012DB0) AdvXPVS.LoadDLL (Line=0) UNICODE: 'Assertion failure' AdvXPVS.LoadDLL (Line=0)
;
; Line=0 - Offset=91
; ------------------
01012493  E800A53FFF      CALL -$C05B00                ; ($0040C998) System._Assert  ; <-- EXCEPTION
01012498  68D42D0101      PUSH $01012DD4               ; ($01012DD4) AdvXPVS.LoadDLL (Line=0) Data as ANSI: 'O'; Data as UNICODE: 'OpenThemeData' AdvXPVS.LoadDLL (Line=0)
0101249D  8B03            MOV  EAX, [EBX]
0101249F  50              PUSH EAX
010124A0  E837DE40FF      CALL -$BF21C9                ; ($004202DC) Winapi.GetProcAddress
010124A5  8BF0            MOV  ESI, EAX
010124A7  8935CC44BA01    MOV  [$01BA44CC], ESI
010124AD  85F6            TEST ESI, ESI
010124AF  7514            JNZ  +$14                    ; ($010124C5) AdvXPVS.LoadDLL (Line=0)
010124B1  B903060000      MOV  ECX, $00000603
010124B6  BA1C2D0101      MOV  EDX, $01012D1C          ; ($01012D1C) AdvXPVS.LoadDLL (Line=0) UNICODE: 'C:\Users\Gianluca\Documents\tmssoftware\TMS VCL UI Pack\AdvXPVS.pas' AdvXPVS.LoadDLL (Line=0)
010124BB  B8B02D0101      MOV  EAX, $01012DB0          ; ($01012DB0) AdvXPVS.LoadDLL (Line=0) UNICODE: 'Assertion failure' AdvXPVS.LoadDLL (Line=0)
010124C0  E8D3A43FFF      CALL -$C05B2D                ; ($0040C998) System._Assert
010124C5  68F02D0101      PUSH $01012DF0               ; ($01012DF0) AdvXPVS.LoadDLL (Line=0) Data as ANSI: 'C'; Data as UNICODE: 'CloseThemeData' AdvXPVS.LoadDLL (Line=0)
010124CA  8B03            MOV  EAX, [EBX]
010124CC  50              PUSH EAX
010124CD  E80ADE40FF      CALL -$BF21F6                ; ($004202DC) Winapi.GetProcAddress

Информация о стеке вызовов:

-------------------------------------------------------------------------------------------------------------------------------------
|Methods |Details|Stack   |Address |Module           |Offset  |Source       |Unit     |Class|Procedure/Method   |Line               |
-------------------------------------------------------------------------------------------------------------------------------------
|*Exception Thread: ID=596; Parent=0; Priority=0                                                                                    |
|Class=; Name=MAIN                                                                                                                  |
|DeadLock=0; Wait Chain=                                                                                                            |
|Comment=                                                                                                                           |
|-----------------------------------------------------------------------------------------------------------------------------------|
|7FFFFFFE|03     |00000000|01012493|testxHairPlus.exe|00C12493|AdvXPVS.pas  |AdvXPVS  |     |LoadDLL            |                   |
|00000060|03     |0018FF34|019F4A28|testxHairPlus.exe|015F4A28|AdvXPVS.pas  |AdvXPVS  |     |Initialization     |                   |
|00000060|03     |0018FF3C|0040C512|testxHairPlus.exe|0000C512|System.pas   |System   |     |InitUnits          |                   |
|00000060|03     |0018FF60|0040C57B|testxHairPlus.exe|0000C57B|System.pas   |System   |     |_StartExe          |                   |
|00000020|03     |0018FF64|004147CE|testxHairPlus.exe|000147CE|SysInit.pas  |SysInit  |     |_InitExe           |                   |
|00004020|03     |0018FF6C|01A2435F|testxHairPlus.exe|0162435F|xHairPlus.pas|xHairPlus|     |Initialization     |                   |
|7FFF7FFE|03     |0018FF84|75027C02|kernel32.dll     |00017C02|KERNEL32.DLL |KERNEL32 |     |BaseThreadInitThunk|                   |
-------------------------------------------------------------------------------------------------------------------------------------

person Gianluca Colombo    schedule 12.12.2019    source источник
comment
if DLLHandle >= 32 then должно быть if DLLHandle <> 0 then. Магическое значение 32 применяется только к ShellExecute(), но не к LoadLibrary(). Что касается утверждения, GetProcAddress("OpenThemeData") не имеет смысла сбой, если uxtheme.dll успешно загружен. Что говорит GetLastError(), когда GetProcAddress() терпит неудачу? Этот код не должен использовать такое утверждение, он должен просто установить DLLLoaded := False; в случае сбоя и нормально завершить работу.   -  person Remy Lebeau    schedule 12.12.2019
comment
@RemyLebeau Приложение вылетает из-за ошибки выполнения 217 GetLastError() с кодом EAssertionFailed   -  person Gianluca Colombo    schedule 12.12.2019
comment
Delphi включает удаленную отладку, docwiki.embarcadero.com/RADStudio/Rio/en/   -  person Brian    schedule 12.12.2019
comment
@GianlucaColombo Я не об этом спрашивал. EAssertionFailed — это исключение, вызванное assert(). GetLastError() возвращает код ошибки Win32, а не исключение. Пожалуйста, измените код, чтобы он вызывал GetLastError() немедленно после сбоя GetProcAddress() и перед вызовом assert(), что на самом деле возвращает GetLastError()? @OpenThemeData := GetProcAddress(DLLHandle,'OpenThemeData'); if @OpenThemeData = nil then begin {what does GetLastError() report here?} end; Assert(@OpenThemeData <> nil);   -  person Remy Lebeau    schedule 12.12.2019


Ответы (1)


Иногда мы получаем ошибки с номерами строк на единицу. В вашем случае Assert(@OpenThemeDataForDpi <> nil); не работает, потому что OpenThemeDataForDpi требуется как минимум Windows 10 1703. В качестве обходного пути вы можете написать свою собственную версию, которая просто игнорирует аргумент dpi и вызывает стандартный OpenThemeData, а затем, когда вы получаете указатель nil, устанавливаете его для своей реализации.

person Daniel Sęk    schedule 02.02.2021