我需要一个可以在后台静默运行的应用程序,但仍然可以与当前用户的桌面进行交互,而且不是服务。
我希望应用程序在不生成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;
这只是从控制台分离进程,它不会删除控制台。找到here
的详细信息所以我试着跟踪窗口的句柄,然后是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命令行选项无法创建控制台窗口或关闭控制台窗口的方法?
答案 0 :(得分:3)
控制台窗口实际上不是特定于GNAT的,而是Windows上的更多GCC。
您可以使用-Wl,-subsystem,windows
或-mwindows
使其不会弹出。