すべての印刷機能を実行する DLL を作成しました。印刷プレビュー、印刷、および PDF の生成を行うことができます。
現在、この DLL の特定の使用パターンがあり、その後 DLL は適切にアンロードできません。その結果、メイン プログラムを終了すると、メイン プログラムは消えますが終了せず、プロセスを手動で強制終了する必要があります。
原因は、一部の GDI リソースが適切に「閉じられていない」ことにあると思います (これを言うとき、GDI に関する無知の深さから言います)。GDI リソースを直接処理するのではなく、さまざまな Delphi コンポーネントを使用するときに GDI リソースが使用されます。
このような問題を見つけて修正する方法についてのヒントはありますか? GDIView を使用して、プログラムを終了しようとした後も GID リソースが残っていることを確認しましたが、これらの Windows/カーネル ハンドルを基礎となる Delphi コードに関連付ける方法がわかりません。プログラムの実行中にさまざまな時点で GIDView リストを提供できます。
ありがとう!
ジョン (デルファイ 2007)
私は提案された提案に返信しましたが、誰も私の回答に返信しませんでした。結局、私はあきらめました。問題を回避する方法として、自分のプロセスだけでなく、同じ名前の他のすべてのプロセスも強制終了する自殺ルーチンを作成することになりました。ばかばかしいやり過ぎですが、他に選択肢がないように思えました。どこかで見つけたフリーウェアの ProcessInfo 機能を使用しています。
procedure KillNamedProcesses(pName : String);
// used to clean up programs that hang as a result of DLLs not unloading
var
ProcessInfo : TProcessInfo;
ProcessName : String;
i : INTEGER;
currentPID : cardinal;
BEGIN
currentPID := GetCurrentProcessID;
pName := UpperCase(pName);
ProcessInfo := TProcessInfo.Create(nil);
// kill all old processes (not our process)
for i := 0 to ProcessInfo.RunningProcesses.Count - 1 do begin
ProcessName := ProcessInfo.RunningProcesses[i].ExeFile;
IF (UpperCase(ProcessName) <> pName) THEN CONTINUE;
IF (currentPID <> ProcessInfo.RunningProcesses[i].ProcessID) then
ProcessInfo.RunningProcesses[i].TerminateProcess;
END;
// kill the last one (ourselves)
for i := 0 to ProcessInfo.RunningProcesses.Count - 1 do begin
ProcessName := ProcessInfo.RunningProcesses[i].ExeFile;
IF (UpperCase(ProcessName) <> pName) THEN CONTINUE;
ProcessInfo.RunningProcesses[i].TerminateProcess;
END;
ProcessInfo.Free;
END; // KillNamedProcess