Semicolon in windows folder name prevents application from loading its dlls - windows

My application (C++) loads its dll by linking against the stub library, the dll is then expected to reside in the same directory as the executable.
However I've had a report from a user who received the error message "System Error - The program can't start because xyz.dll is missing from your computer".
It turns out the reason is that he had my application installed in a path that contains a semicolon (which is supposed to be a valid character in ntfs file names)
I went on to try with a couple of other applications I have installed on my System and some (audacity, git, python, vlc) exhibit the same behaviour (append semicolon to folder name -> dlls can't be loaded) but most don't.
So now I'm wondering: Is this an error on my part? If so: what am I doing wrong? What would I have to do for the dll to be discovered even if its in a path with a semicolon?

Related

Delphi 10.4 Firedac Error 314 on OSX Catalina

How do I correctly provide the libfbclient.dylib for running Firedac/Firebird in OSX to avoid crashing with this message (here in German):
EFDException: [FireDAC][Phys][FB]-314. Laden der Herstellerbibliothek [libfbclient.dylib or libfbembed.dylib] nicht möglich.
To avoid some questions upfront: The software I am compiling already runs fine on Windows and Linux, in OSX it just wouldn't find the libfbclient.dylib. Also all non DB related unit tests run fine on all three platforms. And I made sure that the dylibs have 64 bitness like the executable, I took them from a fresh firebird 3 installation on the same Mac. The project is an application server (Windows service or Linux/OSX daemon).
I create all components dynamically and usually store the fbclient and other required libraries in the a folder together with the executable as I never write things into customers system folders and try to avoid changing things like the system path whenever possible.
const
{$IFDEF MSWINDOWS}
CLIENTNAME = 'fbclient.dll';
{$ENDIF}
{$IFDEF LINUX}
CLIENTNAME = 'libfbclient.so';
{$ENDIF}
{$IFDEF OSX}
CLIENTNAME = 'libfbclient.dylib';
{$ENDIF}
...
fDBLink := TFDPhysFBDriverLink.create(nil);
fDBLink.vendorLib := IncludeTrailingPathDelimiter(extractFilePath(paramstr(0))) + CLIENTNAME;
The Embacadero documentations states the executable searches in the application folder first, so I also tried to omit setting the expicit verndorLib - no difference. I also tried the subfolder Contents/MacOS and the parent folder, also no difference.
As I am not very used to the Unix platform I have no idea if there are system commands that can help finding out why(!) Firedac cannot load the library.
UPDATE 1
Meanwhile I discovered that I instanciated a TFDPhysFBDriverLink Object with every database instance what caused the VendorLib path being detected as empty in FDDriver. After correction the error message contains the complete path to libfbclient.dylib and I verified that it really lives there. I debugged into the Firedac code to where the Library is loaded with LoadLibrary: The path is correct and still it returns 0 in OSX.
Finally I solved it.
The problem remaining after fixing the VendorLib path seems to be the libtommath.dylib dependency. Inspecting libfbclient.dylib with otool -L shows fulfilled depedencies to files living in the standard folders and one special one:
#rpath/lib/libtommath.dylib
To my knowledge rpath default is the path where the executable is living, so I tried this approach:
create a subfolder lib for the dylibs I bundle with my application
deploy libfbclient.dylib and libtommath.dylib in subfolder lib
change TFDPhysFBDriverLink's VendorLib to the new path (including /lib)
This works fine and is a solution easy to implement. In Linux this Problem did not arise as one of my installation dependencies is the libtommath package.

What's special about "c:\windows\system32" in the %PATH%? [duplicate]

My VBA code can't access to my DLL in the C:\Windows\System32 folder on Windows 7 64bit and Word 2010 32bit.
Private Declare Function my_func Lib "mydll.dll" (ByVal param As String) As Long
Public Sub MyFuncTest
n = my_func("a")
End
I copied mydll.dll into C:\Windows\System32 and called MyFuncTest but got an error message like "Error 53: 'mydll.dll' not found".
However, I changed the declaration in code to:
Private Declare Function my_func Lib "C:\Users\myname\Documents\mydll.dll" (ByVal param As String) As Long
then I copied mydll.dll into C:\Users\myname\Documents, my account's Documents folder, and MyFuncTest successfully executed.
Changing "mydll.dll" to "C:\Windows\System32\mydll.dll" in the declaration did not work. And I tried accessing C:\Windows\System32\mydll.dll with FileSystemObject#FileExists method on the same VBA environment, but it returned False (not found).
There was no problem on Windows XP and Word 2003.
Can anyone help?
This is a 32 bit DLL and a 32 bit process running in the WOW64 emulator on 64 bit Windows. File redirection is in play and so when a 32 bit process looks in system32 it is actually redirected to the 32 bit system directory SysWOW64.
The simple and quick solution is to move the DLL to C:\Windows\SysWOW64. However, as Cody Gray points out in a comment, it is not recommended for you to place application DLLs in the system directory. Normal practice is to place the DLLs in your application folder in the program files directory and make sure that folder is in the DLL search path when the DLL needs to be loaded.
Seems like UAC is the problem. Try running the VBA script as Administrator. It may help you.
A recent developer suggested the following fix which allowed a 32bit .dll to be registered on a 64 bit machine
1) Open a DOS command window.
2) Navigate to C:\Windows\Microsoft.NET\Framework64\v2.0.50727
3) Enter the following and press enter.
regasm /codebase "C:\Users\myname\Documents\mydll.dll"
I have had exactly the same problem yesterday. The program run on my machine, but not on others.
In fact, the message fron Excel is wrong. He obviously find lhe dll file, but this dll is calling orher dll, missing in the system : MSVCR100D.dll and NTDLL.dll.
I found that by using Dependency Walker free software, able to examine which dll are call by a dll.

Qt 5.3.1: macdeployqt tries to include everything on my hard drive; how to fix?

I'm running Qt 5.3.1 on Mac OS X 10.8 and 10.9 I'm trying to use the macdeployqt tool to bundle libraries and plugins with my executable, but it's apparently trying to include everything on my hard drive.
I invoke it with:
/Applications/Qt/5.3.1/5.3/clang_64/bin/macdeployqt /Users/adamwilt/Desktop/temp/DesktopPixie.app -verbose=2
-qmldir=/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/DesktopPixie
and get lots of normal, expected log messages like:
Log: copy: "/Applications/Qt/5.3.1/5.3/clang_64/qml/QtQuick/Controls/Styles/Base/images" "/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/QtQuick/Controls/Styles/Base/images"
...and all runs fine until I start getting messages like:
Log: copy: "" "/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/MessageBoxUI/Enums"
ERROR: file copy failed from "/do-gst"
ERROR: to "/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/MessageBoxUI/Enums/do-gst"
ERROR: file copy failed from "/rescuepro.properties"
ERROR: to "/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/MessageBoxUI/Enums/rescuepro.properties"
ERROR: file copy failed from "/rescuepro34act.lic"
and then the fun begins:
Log: copy: "/Applications" "/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/MessageBoxUI/Enums/Applications"
Log: copied: "/Applications/License.rtf"
Log: to "/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/MessageBoxUI/Enums/Applications/License.rtf"
Log: copy: "/Applications/0xED-1.0.7.app" "/Users/adamwilt/Desktop/temp/DesktopPixie.app/Contents/Resources/qml/MessageBoxUI/Enums/Applications/0xED-1.0.7.app"
It appears it's trying to copy everything (that is, "") into the app, but I ^C out of it while I still have disk space left!
It didn't do this at first; then it did so for a week; then it stopped; now it's back. This is a distributed development project; I'm doing the QML stuff and folks elsewhere are doing the C++. It's possible the other folks are changing a configuration somewhere that's causing this to occur, but I'm the only one doing Mac deployments, so I'm the only one who sees this.
Is there a config file of some sort for macdeployqt where this might be getting triggered? Or is it more likely a problem related to the C++ object MessageBoxUI, which defines several Q_ENUMs (apparently correctly, as it compiles without warnings or errors, and appears to run properly), since that's the target directory when it starts going mad?
Sussed it (well enough that I can go on):
The Qt app I'm trying to deploy lives in ~/Desktop/temp. If I set my current directory to ~/Desktop or ~/Desktop/temp before I run macdeployqt, it runs as expected.
If I run it from from my home directory ~, or ~/Documents, macdeployqt tries to pull in everything it finds in /Applications, /opt, and/or other directories unassociated with the app.
Setting cwd to most other paths, including ~/Downloads, /Applications, subdirectories of ~/Documents, etc. also seems to work; it's only running macdeployqt from ~ and ~/Documents that causes the problem.
No proper explanation as to why this is happening, but just a warning in case someone else sees this sort of weird behavior: try changing to the apps's location before running macdeployqt.

QT 5.2 app cannot start (Bad allocation error) when Qt5Core.dll is in app directory

I have a funny problem on my machine
Windows 7 x64, using QT 5.2 for the GUI
I'm not able to start the app I always receive the error
First I thought I had a broken dll, so through some trial and error I found a solution:
I add the QT5Core.dll via enviroment path, and NOT directly to the app folder. Then the programm works. If I copy the dll back to the app Folder, Same problem as before!?!?!?1
I'm really confused, because the error only occurs on my machine?
Debugging doesn't really help,
In code, the error occures here:
MyApplication::MYApplication(int argc, char** argv, int version)
: QApplication(argc, argv, version) // <<< this call fails!
{ }
somebody can help me?
Why is the location of the qt5core.dll a problem?!?!?
UPDATE
I used the profiling function of depends and found the following behaviour:
Failing
GetProcAddress(0x76800000 [c:\windows\syswow64\KERNEL32.DLL], "CreateSymbolicLinkW") called from > "dirone\xxxx.EXE" at address 0x00FF2877 and returned 0x7688CCE9.
First chance exception 0xE06D7363 (Microsoft C++ Exception) occurred in "c:\windows\syswow64\KERNELBASE.DLL" at address 0x765CC41F.
Exception: "bad allocation"
Working
LoadLibraryW("C:\BuildPackages\QT\plugins\platforms\qwindows.dll") called from "dirtwo\QT5CORE.DLL" at address 0x66AA5154.
Loaded "c:\buildpackages\qt\plugins\platforms\QWINDOWS.DLL" at address
0x0F380000. Successfully hooked module.
somehow the path to the qwindows.dll is hardcoded into the dll (there is no environment path to this directory)
If I rename the qwindows.dll or delete it, startup failes again.
BUT the qwindows.dll is bundeld with our product. It is in a subdirectory ./platforms/
AND the files are the same (diff returns equal)
Somebody have some clue what I should try next?
Check if you already have some qt related environmental variables.
Crashes are usually due to this, remove those envronmental variables first. Check whether you have any other qt installed libraries.
it would be better if you can post the cal stacks.
Some other dlls are needed that reside in the directory of the qt5core.dll. When you add this path to the search path the dlls are found. When you simply copy the dll these dlls can not be found. You can check dependencies with the depends tool.
Candidates for the additional dlls are:
icuin51.dll and icuuc51.dll
Found the Problem:
The enviromentvariable:
QT_QPA_PLATFORM_PLUGIN_PATH=C:\BuildPackages\QT\plugins\platforms
was set to the path. If removing this variable, everything works as it should!

Creating Setup of large data with NSIS Script

I am creating setup of large data approximetly 10 GB with NSIS Script and trying to create a single setup (exe). Its giving an Error -
Internal compiler error #12345: error mmapping file (xxxxxxxxxx, xxxxxxxx) is out of range.
Note: you may have one or two (large) stale temporary file(s) left in your temporary directory (Generally this only happens on Windows 9x).
Please tell me how to solve this issue ?
Is there any other way to create a setup for this kinda situation ?
NSIS installers are limited to 2Gb.
If you absolutely need it to be one file and you want to continue to use NSIS you have to append the data to the end of the generated setup. I'm not sure I would recommend that approach but it could work if the appended data is a zip file (or some other format with the header at the end) and you use one of the NSIS zip plugins to extract at run-time...
I have used https://sourceforge.net/projects/nsisbi/ instead of normal NSIS. It solved the problem.
I was using Silent Install Builder 5 and received this same error with a package installer that had LESS that 2 GB total. Once I determined that the NSIS compiler was to blame, I began experimenting with several possible solutions and here's what worked: I downloaded the newer NSISBI compiler from here https://sourceforge.net/projects/nsisbi/ and then did these 3 steps:
Go to C:\Program Files (x86)\Silent Install Builder 5 and renamed the default NSIS folder to a new name.
Copied the NSISBI folder into the C:\Program Files (x86)\Silent Install Builder 5 directory and renamed IT to NSIS.
Tries to compile some large packages above and just below 2GB and the first few tries I would get missing file errors in the Silent Install Builder 5 compiling box. No worries because the missing files are in the old NSIS folder, that's why y9u don't delete it.
Each time find the missing file error displays, find the missing files and copy them into the same folder location in the new NSIS folder. About 3 times you will do this until there are no more errors at all and you can then include the large files without generating the "internal compiler error #12345: error mmapping file xxxx is out of range." error message. NSISBI works!

Resources