bluerobotics / ping-viewer

Ping Viewer is an open-source application to view and record data from the Blue Robotics Ping Echosounder and Ping360 Scanning Sonar.
https://docs.bluerobotics.com/ping-viewer/
GNU General Public License v3.0
40 stars 38 forks source link

Missing DLL on particular device #1018

Closed ES-Alexander closed 2 years ago

ES-Alexander commented 2 years ago

Summary

Version: 2.3.0

Operating System: Windows 10 (Dell tablet-PC)

What is happening: PingViewer errors out on opening with VCRUNTIME140.dll or VCRUNTIME140_1.dll could not be found . Only occurs on Dell tablet-PC (not occurring on same person's Desktop computer)

How to reproduce it: Open PingViewer (on relevant device)

Additional information

ES-Alexander commented 2 years ago

Two others had the same issue here, and it was apparently worked around "by downloading and installing Microsoft Visual C++ 2015 - 2019 Redistributable".

joaoantoniocardoso commented 2 years ago

Just for safety - and because this is a common concern when dealing with DLL problems - I ran a virus check on our .zip with virustotal and there is nothing wrong with it. Also there is nothing wrong with the shipped dll.

Although I assume our software is being compiled with the same dll version it is shipping, if installing (or updating?) vc_runtime has fixed the problem, I was asking myself if it could be something about dll version mismatch..

One possible scenario I can imagine is that for some reason the shipped dll is not being found, and the system dll is older than the required, so by updating the system dll the problem is 'fixed'.

To give some data, the version of the latest vc_runtime (which I believe is what they downloaded - from microsoft) is 14.30.30704.0, the classical "2015 Update 3 RC" (which is commonly linked as the solution for the "VCRUNTIME140.dll not found" - also from microsoft) is 14.0.24123.0, and the one we ship in our zip is 14.29.30038.0.

One solution is to recommend the users to update their Visual C++ distribution from the microsoft link in advance, just before they run into the problem?

patrickelectric commented 2 years ago

Thanks @joaoantoniocardoso, that's an interesting fact! A possible investigation could be done with dependency walker to check if the DLL can be found and all dependencies for it exist on the same folder. The weird thing is that we never had this problem until this year, IIRC. VCRUNTIME exists on the extracted folder and in the same path as pingviewer.exe, so it should be found without much problem.

Williangalvani commented 2 years ago

I wonder if this is why most software for windows make you install "Visual C++ redistributables" when you install them...

joaoantoniocardoso commented 2 years ago

Thanks @joaoantoniocardoso, that's an interesting fact! A possible investigation could be done with dependency walker to check if the DLL can be found and all dependencies for it exist on the same folder. The weird thing is that we never had this problem until this year, IIRC. VCRUNTIME exists on the extracted folder and in the same path as pingviewer.exe, so it should be found without much problem.

Good idea, I'll do that, and I'll also execute our software with the older C++ installed to validate the supposed scenario.

I wonder if this is why most software for windows make you install "Visual C++ redistributables" when you install them...

hah, I bet so, and actually it seems that when an installer requires administrator privileges, it is using this (recommended) approach.

Another thing that I noticed that is not exactly following Microsoft's recommendation is that we are copying the DLLs from the system's folder instead copying them from Visual Studio's redist folder, although I noticed that other softwares like Qt Creator is doing the same. Can we assume they are the same for the github image?

joaoantoniocardoso commented 2 years ago

Ok, as it is not something I have done in the past, I am detailing the way I came up with the solution:

Investigation

Fresh system install

First, by first opening the ping viewer software from a fresh Windows 10 (Stable 1809) virtual machine, the following errors occur:
image image

That's because we should be packing the VCRUNTIME_1.dll and MSVCP140_1.dll and we are not.

I renamed the VCRUNTIME140.DLL to tmp and it says it cannot find VCRUNTIME140.dll. That's because the fresh system doesn't have any version installed on the system, and it shows that in absence of system's known DLL on system's dir, the software is, as expected, searching the DLL from the same folder as the pingviewer.exe.

Quick check with Visual C++ Redistributable for Visual Studio 2015

So I installed the Visual C++ Redistributable for Visual Studio 2015 x64 and installed it to the system:
image

When running pingviewer, again it can't find VCRUNTIME140_1.dll and MSVCP140_1.dll, and indeed the Redistributable for Visual C++ Redistributable for Visual Studio 2015 don't ship these two.

Using Dependency Walker, it shows that the application is using VCRUNTIME140.dll that we are shipping, and not from the system32 folder.

The community's 'fix'

To simulate the steps the user did to fix it, I downloaded and installed the Latest Microsoft Visual C++ Redistributable:

image

And as expected, the software ran smoothly, loading the missing VCRUNTIME140_1.dll from the system, which was installed by the Latest Microsoft Visual C++ Redistributable, while using the VCRUNTIME140.dll and MSVCP140.dll that we ship:

image


The solution

The solution to our side seems to ship all required DLLs, including (VCRUNTIME140_1.dll and MSVCP140_1.dll), and to not ship the ucrtbased.dll, as it is a Windows's known DLL, which will make it to be searched on the system's folder before our application's folder, and because it is shipped with the Windows itself, we are not supposed to distribute it.

To simulate that, I moved the required DLLs (VCRUNTIME140.dll, VCRUNTIME140_1.dll, MSVCP140.dll and MSVCP140_1.dll) from our system's folder (which are the Latest Microsoft Visual C++ Redistributable) to our pingview folder and deleted the ucrtbased.dll. The software ran as expected and the Dependency Walker confirms that our software is loading them correctly:
image

For reference, Qt Creator is copying some other dlls in addition to the four commented here (VCRUNTIME140.dll, VCRUNTIME140_1.dll, MSVCP140.dll, MSVCP140_1.dll), but from my tests, just these four are enough for us.

As recommended by @patrickelectric (and also Microsoft), below I am listing the required DLLs from all the available redistributable DLLs (from \VC\Redist\MSVC\version - in my case: C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.28.29910\x64\Microsoft.VC142.CRT):

Loaded? DLL
N concrt140.dll
Y msvcp140.dll
Y msvcp140_1.dll
N msvcp140_2.dll
N msvcp140_atomic_wait.dll
N msvcp140_codecvt_ids.dll
N vccorlib140.dll
Y vcruntime140.dll
Y vcruntime140_1.dll

So, summarizing the solution in simple steps:

Patch

The patch to our build.yml should be something like:

+++        SYSTEM32_DLLS: 'VCRUNTIME140.dll VCRUNTIME140_1.dll MSVCP140.dll MSVCP140_1.dll'
---        SYSTEM32_DLLS: 'VCRUNTIME140.dll MSVCP140.dll ucrtbased.dll'

What do you think?