バックグラウンドで静かに実行され、現在のユーザーのデスクトップと対話し、サービスではないアプリケーションが必要です。
stdout コンソールを生成せずにアプリケーションを起動したい。
C では Kernel32.dll の FreeConsole を使用して行われているようです。そのため、関数をインポートしました。
procedure Free_Console
is
use System;
type Shared_Library_Function
is access function
return Interfaces.C.Int;
pragma Convention(Stdcall, Shared_Library_Function);
function To_Shared_Library_Function
is new Ada.Unchecked_Conversion(System.Address, Shared_Library_Function);
function Load_Library(
File_Name : in Interfaces.C.Char_Array)
return System.Address;
pragma Import(Stdcall, Load_Library, "LoadLibrary", "_LoadLibraryA@4");
function Get_Function_Address(
Module : in System.Address;
Function_Name : in Char_Array)
return System.Address;
pragma Import(stdcall, Get_Function_Address, "GetProcAddress", "_GetProcAddress@8");
Library : System.Address := Load_Library(To_C("kernel32.dll"));
Pointer : System.Address := Get_Function_Address(Library, To_C("FreeConsole"));
begin
if Pointer /= System.Null_Address then
declare
Result : Interfaces.C.Int := 1;
begin
Result := To_Shared_Library_Function(Pointer).all;
end;
else
-- TODO Handle Error
null;
end if;
end Free_Console;
これはコンソールからプロセスを切り離すだけで、コンソールは削除しません。この動作の詳細はこちら
そこで、ウィンドウへのハンドルを追跡してから、それを CloseHandle() しようとしました。
function Get_Console_Handle
return System.Address
is
use System;
STD_INPUT_HANDLE : constant Interfaces.C.Unsigned_Long := -10;
STD_OUTPUT_HANDLE : constant Interfaces.C.Unsigned_Long := -11;
STD_ERROR_HANDLE : constant Interfaces.C.Unsigned_Long := -12;
type Shared_Library_Function
is access function(
Standard_Handle : Interfaces.C.Unsigned_Long)
return System.Address;
pragma Convention(Stdcall, Shared_Library_Function);
function To_Shared_Library_Function
is new Ada.Unchecked_Conversion(System.Address, Shared_Library_Function);
function Load_Library(
File_Name : in Interfaces.C.Char_Array)
return System.Address;
pragma Import(Stdcall, Load_Library, "LoadLibrary", "_LoadLibraryA@4");
function Get_Function_Address(
Module : in System.Address;
Function_Name : in Char_Array)
return System.Address;
pragma Import(stdcall, Get_Function_Address, "GetProcAddress", "_GetProcAddress@8");
Library : System.Address := Load_Library(To_C("kernel32.dll"));
Pointer : System.Address := Get_Function_Address(Library, To_C("GetStdHandle"));
begin
if Pointer /= System.Null_Address then
return To_Shared_Library_Function(Pointer).all(STD_OUTPUT_HANDLE);
else
return System.Null_Address;
end if;
end Get_Console_Handle;
--winbase.CloseHandle
function Close_Handle(
Object_Handle : in System.Address)
return Interfaces.C.Int;
pragma Import(Stdcall, "CloseHandle");
これもどうにもなりません。Get_Console_Handle が間違ったハンドルを返すに違いありません。
私の質問は、コンソール ウィンドウを作成しない Gnat コマンド ライン オプション、またはコンソール ウィンドウを閉じる方法はありますか?