Наш InnoSetup использует внешнюю библиотеку DLL для захвата и проверки файла xml для путей к файлам данных. Это работает нормально в большинстве случаев, Windows XP, 7, 10 (32 / 64bit). Но для некоторых пользователей это не получается, а для меня это не так в Crossover 19 для macOS 10.15. Поэтому сначала я добавил задержку загрузки в сценарий inno, чтобы обойти ошибку времени выполнения «not import dll».
Но потом я получаю сообщение «не могу вызвать pro c» во время выполнения. Отладчик InnoSetup указал мне на procedure GetExultGamePaths
нашего скрипта.
Код в нашей dll:
extern "C" {
__declspec(dllexport) void __stdcall GetExultGamePaths(char *ExultDir, char *BGPath, char *SIPath, int MaxPath) {
MessageBoxDebug(nullptr, ExultDir, "ExultDir", MB_OK);
MessageBoxDebug(nullptr, BGPath, "BGPath", MB_OK);
MessageBoxDebug(nullptr, SIPath, "SIPath", MB_OK);
int p_size = strlen(ExultDir) + strlen("/exult.cfg") + MAX_STRLEN;
char *p = new char[p_size];
// Get the complete path for the config file
Path config_path(ExultDir);
config_path.AddString("exult.cfg");
config_path.GetString(p, p_size);
setup_program_paths();
const static char *si_pathdef = CFG_SI_NAME;
const static char *bg_pathdef = CFG_BG_NAME;
MessageBoxDebug(nullptr, ExultDir, p, MB_OK);
try {
// Open config file
Configuration config;
if (get_system_path("<CONFIG>") == ".")
config.read_config_file(p);
else
config.read_config_file("exult.cfg");
std::string dir;
// SI Path
config.value("config/disk/game/serpentisle/path", dir, si_pathdef);
if (dir != si_pathdef) {
Path si(ExultDir);
si.AddString(dir.c_str());
si.GetString(SIPath, MaxPath);
} else {
std::strncpy(SIPath, si_pathdef, MaxPath);
}
// BG Path
config.value("config/disk/game/blackgate/path", dir, bg_pathdef);
if (dir != bg_pathdef) {
Path bg(ExultDir);
bg.AddString(dir.c_str());
bg.GetString(BGPath, MaxPath);
} else {
std::strncpy(BGPath, bg_pathdef, MaxPath);
}
} catch (...) {
std::strncpy(BGPath, bg_pathdef, MaxPath);
std::strncpy(SIPath, si_pathdef, MaxPath);
}
delete [] p;
}
Часть скрипта InnoSetup
procedure GetExultGamePaths(sExultDir, sBGPath, sSIPath: String; iMaxPath: Integer);
external 'GetExultGamePaths@files:exconfig.dll stdcall delayload';
procedure CurPageChanged(CurPageID: Integer);
var
sBGPath: String;
sSIPath: String;
begin
if CurPageID = DataDirPage.ID then begin
if bSetPaths = False then begin
setlength(sBGPath, 1024);
setlength(sSIPath, 1024);
GetExultGamePaths(ExpandConstant('{app}'), sBGPath, sSIPath, 1023 );
BGEdit.Text := sBGPath;
SIEdit.Text := sSIPath;
end;
end;
end;
The GetExultGamePaths(ExpandConstant('{app}'), sBGPath, sSIPath, 1023 );
- это то, что выдает ошибку «не удалось вызвать про c» во время выполнения.
Я понятия не имею, почему это происходит только в нескольких системах. Полный код для нашей dll и скрипта находится по адресу https://github.com/exult/exult/blob/master/win32/ Код dll находится в exconfig. *, А скрипт InnoSetup находится в exult_installer.iss