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", "_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 コマンド ライン オプション、またはコンソール ウィンドウを閉じる方法はありますか?

4

1 に答える 1

3

コンソール ウィンドウは、実際には GNAT 固有ではなく、Windows では GCC です。

を使用する-Wl,-subsystem,windows-mwindows、ポップアップしないようにすることができます。

于 2012-07-23T06:31:11.857 に答える