Jacob 已经涵盖了讨论,但我最终在系统调用之上生成了一个快速绑定。我能够使用 GPS 在 Windows 10 中生成应用程序事件来编译和运行它:
Windows_Event_Log.ads
package Windows_Event_Log is
type Event_Type is
(Error,
Warning,
Information,
Success_Audit,
Failure_Audit);
type Event_Category is
(Application,
System);
-- Calls command
procedure Event_Create
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String);
-- For Debug
function Make_Event_String
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String)
return String;
end Windows_Event_Log;
Windows_Event_Log.adb
with Interfaces.C.Strings;
with Ada.Characters.Latin_1;
with Ada.Containers.Indefinite_Holders;
package body Windows_Event_Log is
package String_Holders is new Ada.Containers.Indefinite_Holders(String);
-- Conversion arrays
Type_String : constant array(Event_Type) of String_Holders.Holder :=
(Error => String_Holders.To_Holder("ERROR"),
Warning => String_Holders.To_Holder("WARNING"),
Information => String_Holders.To_Holder("INFORMATION"),
Success_Audit => String_Holders.To_Holder("SUCCESSAUDIT"),
Failure_Audit => String_Holders.To_Holder("FAILUREAUDIT"));
Category_String : constant array(Event_Category) of String_Holders.Holder :=
(Application => String_Holders.To_Holder("APPLICATION"),
System => String_Holders.To_Holder("SYSTEM"));
function Make_Event_String
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String)
return String
is begin
return
"EventCreate /t "
& Type_String(Type_Of_Event).Element
& " /id "
& Positive'Image(ID)
& " /l "
& Category_String(Category).Element
& " /so "
& Source
& " /d """
& Message
& """ >nul 2>&1"; -- Suppress output and error
end Make_Event_String;
-- Thin binding to the system call
function System(Str : Interfaces.C.Strings.chars_ptr) return Interfaces.C.int
with
Import,
Convention => C,
External_Name => "system";
procedure Event_Create
(Type_Of_Event : Event_Type;
ID : Positive;
Category : Event_Category;
Source : String;
Message : String)
is
Event_String : String := Make_Event_String
(Type_Of_Event => Type_Of_Event,
ID => ID,
Category => Category,
Source => Source,
Message => Message)
& Ada.Characters.Latin_1.NUL; -- needed for C strings
Event_Chars_Ptr : Interfaces.C.Strings.chars_ptr :=
Interfaces.C.Strings.New_String(Event_String); --allocates memory
-- This line actually makes the system call
Result : Interfaces.C.int := System(Event_Chars_Ptr);
begin
-- Free the allocated memory from New_String
Interfaces.C.Strings.Free(Event_Chars_Ptr);
end;
end Windows_Event_Log;
主文件
with Windows_Event_Log;
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
Event_Type : Windows_Event_Log.Event_Type := Windows_Event_Log.Warning;
ID : Positive := 458;
Category : Windows_Event_Log.Event_Category := Windows_Event_Log.Application;
Source : String := "SomeString";
Message : String := "This is another joke";
begin
-- Debug print
Put_Line
("Generated Command => "
& Windows_Event_Log.Make_Event_String
(Type_Of_Event => Event_Type,
ID => ID,
Category => Category,
Source => Source,
Message => Message));
-- Actual Command Sent
Windows_Event_Log.Event_Create
(Type_Of_Event => Event_Type,
ID => ID,
Category => Category,
Source => Source,
Message => Message);
end Main;
我只测试了几个输入用例,所以它还没有完全测试,但我想给你一个快速绑定的例子。它是使用 GNAT GPL 2017 for windows 编译和测试的
参考
用于 Windows 的 system() api
适用于 Windows 的 EventCreate api
C 中的 Rosetta 代码示例,了解如何执行此操作