1

I wrote a large VBA program which, in a nutshell, calculates the energy need of buildings. It would be way to much code to post here but firstly it reads a configuration file for each building, then loads some heat load profiles from the disk and then dynamically calculates for 35040 quarter hours which heat producers generates what amount of heat.

On Windows 7 with Windows Defender it just runs smooth and fine, no matter what Excel Version (2007, 2010, 2013, 365 tested).

Now, if I'm running the same code on my computer with Windows 10 and Windows Defender (Excel 365), it is slower by an incredible amount (factor 1000 or so it feels). And strangely, everything is way slower, it is not a certain procedure or event. Loading the files and profiles from the disk takes forever, but calculating the energy needs in the loop (where nothing is transferred from/to the drive) is way slower aswell. The GUI isn't refreshing at all and the whole application just seems frozen.

At the same time MsMpEng.exe is on full load, suggesting Windows Defender has a problem. And surprise, having turned off Windows Defender, everything runs fine.

Now, because there are so many classes/modules/etc. it is hard to say, what may be the problem and I can't upload the code. But at least I have a suspicion. Every class has a Parent Property, implemented as depicted here. The parent property is called very often and all over the code so the extreme slow down would make sense if there was a problem with the CopyMemory-API/Function.

Update 1: I removed the CopyMemory-Function and replaced all the Parents with Circular References. This is no long term solution, but it solved part of the problem. When I wait long enough the calculation starts at some point and is as fast as it's supposed to be. So the problem could be related to API-Functions in general because I use quite a lot for the GUI, namely

Public Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr

Public Declare PtrSafe Function GetDeviceCaps Lib "Gdi32" (ByVal hDC As LongPtr, ByVal _
    nIndex As Long) As Long

Public Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal _
    hDC As LongPtr) As Long

Public Declare PtrSafe Function GetSystemMetrics32 Lib "user32" _
    Alias "GetSystemMetrics" (ByVal nIndex As Long) As Long

Public Declare PtrSafe Function SetWindowPos Lib "user32" _
        (ByVal hWnd As LongPtr, ByVal hWndInsertAfter As LongPtr, _
        ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
        ByVal cy As Long, ByVal wFlags As Long) As Long

Public Declare PtrSafe Function DrawMenuBar Lib "user32" (ByVal hWnd As LongPtr) As Long

Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
    (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr

Public Declare PtrSafe Sub ReleaseCapture Lib "user32" ()

Public Declare PtrSafe Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" _
    (ByVal hInst As LongPtr, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As LongPtr

Public Declare PtrSafe Function GetActiveWindow32 Lib "user32" Alias "GetActiveWindow" () As Integer

#If Win64 Then
    Public Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Public Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
    Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long) As LongPtr
    Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" _
        (ByVal hWnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If

Update 2 (which makes the topic in a way solved):

The reason for the loading-part of the program took so long is because I used the JSON-Converter. And as it turns out there was a similar problem. Since I updated the module and removed every other API-Call everything runs fine and smooth. So it is definitly caused by the API-Calls though I don't know why there aren't that many other people complaining about the huge performance issues. And now I can't tweak the GUI in the way I wan't to and I don't really know how to implement the parent property properly.

John Doe
  • 91
  • 7
  • You say it runs faster if you turn off defender. Does it also run faster if you define a exception for your folder/files in defender (instead of turning it off)? – Pᴇʜ Sep 11 '19 at 09:25
  • I've had similar issues. To get round it I had to remove/rewrite all references to any `*32` libraries. Windows Defender flags all of these whether they are actual code or even just commented. – Tom Sep 11 '19 at 09:28
  • @Pᴇʜ I didn't try that though I tried putting the file itself and/or the Excel-Application itself on the exception list without any success. – John Doe Sep 11 '19 at 11:38
  • @Tom Somehow glad to hear I'm not the only one. But you didn't find any way around that except not using API-calls, did you? – John Doe Sep 11 '19 at 11:38
  • @JohnDoe I found alternate ways using WMI or shell calls - You may benefit from reading this paper [link](http://blog.sevagas.com/IMG/pdf/bypass_windows_defender_attack_surface_reduction.pdf) – Tom Sep 11 '19 at 12:20
  • @Tom thank you, I will have a look at that paper! – John Doe Sep 12 '19 at 06:12
  • @Tom I read the paper now and it is quite interesting! Though unfortunately it is not of any help because Windows Defender is just slowing down the code execution, there is nothing actually blocked by ASR related to the API calls. – John Doe Sep 17 '19 at 07:48
  • For anyone interested, [this](https://github.com/cristianbuse/VBA-WeakReference) repo solves the weak reference problem. It relies on [this](https://github.com/cristianbuse/VBA-MemoryTools) repo to do the memory copying. I've created them precisely to work around the API speed issue – Cristian Buse Jan 16 '23 at 17:09

0 Answers0