私のプログラムはいくつかのdllをロードし、それらの関数を呼び出します。dllは、さまざまなバージョンのCRTを使用できます。
Cランタイムは、引数の有効性をチェックして問題を見つけると、無効なパラメーターハンドルを呼び出します。これにより、[送信-送信しない]ダイアログの有無にかかわらず、アプリケーションが閉じられます。
* _set_invalid_parameter_handler *を呼び出してみましたが、不正なdll内から呼び出された場合にのみ機能します。SetErrorModeを試しましたが、ダイアログなしでプロセスを強制終了することができました。
それらの例外を処理する方法はありますか?一部のリソースが危険にさらされてもかまいません。私が欲しいのは、ユーザーが構成を保存できるようにすることだけです。ダイアログが表示されたら、それをクリックしてプロセスを強制終了します。
編集 すべてのバージョンのCRTをロードするか、すべてのDLLを列挙するソリューションは失敗します。すべてを明確にするために、これは遊ぶための小さな例です:
これが私のメインアプリケーションになります(ファイルapplication.cと呼びましょう):
#include <windows.h>
void myInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) {
wprintf(L"Invalid parameter detected in function %s. File: %s Line: %d\n", function, file, line);
wprintf(L"Expression: %s\n", expression);
}
void fixMyProblem() {
}
int main(int argc, char **argv) {
HMODULE hModule = LoadLibrary("extension.dll");
void (WINAPI *function)() = GetProcAddress(hModule, "function");
fixMyProblem();
function();
}
このアプリケーションは、悪いことをするdllをロードします(それは私によって開発されていないので、そこでバグを修正するように指示する解決策を受け入れません)。そのファイル拡張子を呼び出しましょう。c 。
#include <stdio.h>
__declspec(dllexport) void function() {
printf("do bad stuff");
fopen(NULL, "r");
}
コンパイルするには、次のようにします。
cl extension.c /link /OUT:extension.dll /DLL
cl application.c
問題は、関数fixMyProblem()で何をするかです。これにより、XPで送信/送信しないダイアログが表示されないか、アプリケーションが7でダイアログの動作を停止します。
David Gladfelterによると、私はやるべきです
void fixMyProblem() {
_set_invalid_parameter_handler(myInvalidParameterHandler);
}
また、利用可能なバージョンCRTごとにこれを実行します。1つのバージョンのCRT(exeとdllの両方に同じものを使用しています)を使用しても、機能しないことがわかりました。どちらも同じバージョンのCRTを使用していますが、同じCRTを使用していないようです。
この場合、変更する必要があるものはDLL内にあると思います。もちろん、* _set_invalid_parameter_handler*はエクスポートされません。
しかし、David Heffernanに公平を期すために、彼のソリューションの実装は次のとおりです。
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
void fixMyProblem() {
HANDLE hProcess = GetCurrentProcess();
HMODULE *hModules;
DWORD requiredSize = 0;
DWORD secondRequiredSize = 0;
if (!EnumProcessModules(hProcess, NULL, 0, &requiredSize)) {
printf("oops\n");
return;
}
hModules = malloc(requiredSize);
if (EnumProcessModules(hProcess, hModules, requiredSize, &secondRequiredSize)) {
int i;
int loadedModules = min(requiredSize, secondRequiredSize) / sizeof(HMODULE);
for (i = 0; i < loadedModules; i++) {
void *(WINAPI *_set_invalid_parameter_handler_function)(void *) = (void *(WINAPI *)(void *)) GetProcAddress(hModules[i], "_set_invalid_parameter_handler");
if (_set_invalid_parameter_handler_function != NULL) {
_set_invalid_parameter_handler_function(myInvalidParameterHandler);
printf("fixed dll %d\n", i);
}
}
} else {
printf("oops\n");
}
free(hModules);
}
このテストではなく、実際のアプリケーションでは、1つのdllが修正されました(msvcp90.dll)。それでも私の問題は解決しません。
これを解決するために助けていただければ幸いです。