2012-07-05 2 views
3

백그라운드에서 자동으로 실행되지만 현재 사용자의 데스크탑과 상호 작용하는 서비스가 아닌 애플리케이션이 필요합니다.콘솔없이 프로세스 생성하기

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", "[email protected]"); 

    function Get_Function_Address(
    Module  : in System.Address; 
    Function_Name : in Char_Array) 
    return System.Address; 
    pragma Import(stdcall, Get_Function_Address, "GetProcAddress", "[email protected]"); 

    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", "[email protected]"); 

    function Get_Function_Address(
    Module  : in System.Address; 
    Function_Name : in Char_Array) 
    return System.Address; 
    pragma Import(stdcall, Get_Function_Address, "GetProcAddress", "[email protected]"); 

    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 명령 줄 옵션이나 콘솔 창을 닫는 방법이 있습니까?

+1

-mwindows는 Windows에서 GNAT와 작동합니까? * nix 당신은 아무것도 필요 없어, 콘솔 윈도우가 생성되어서는 안됩니다. – oenone

+0

@ ensone 맨 페이지에서 mwindows를 보지 못했지만 시도해 보겠습니다. 윈도우즈에서는 GNAT가 자동으로 콘솔을 응용 프로그램에 연결합니다. – Ignoreme

+0

@ enone 그게 효과가 있다면, 당신이 대답하게 만들면, 나는 투표하고 그것을 받아 들일 것입니다. – Ignoreme

답변

3

콘솔 창은 실제로 GNAT 전용이 아니며 Windows의 GCC가 많습니다.

-Wl,-subsystem,windows 또는 -mwindows을 사용하여 팝업되지 않도록 할 수 있습니다.

관련 문제