77 */
88
99using System ;
10+ using System . Collections . Generic ;
1011using System . Linq ;
1112using System . Net . NetworkInformation ;
1213using Weaver . Interfaces ;
1314using Weaver . Messages ;
15+ using Weaver . Registry ;
1416
1517namespace CoreBuilder . Extensions
1618{
@@ -31,60 +33,112 @@ public sealed class WhoAmIExtension : ICommandExtension
3133 public string Namespace => "System" ;
3234
3335 /// <inheritdoc />
34- public CommandResult Invoke ( ICommand command , string [ ] extensionArgs , Func < string [ ] , CommandResult > executor ,
35- string [ ] commandArgs )
36+ public CommandResult Invoke ( ICommand command , string [ ] extensionArgs , Func < string [ ] , CommandResult > executor , string [ ] commandArgs )
3637 {
3738 if ( extensionArgs . Length == 0 )
3839 {
3940 return CommandResult . Fail (
4041 "No parameter specified. Example: whoami().who(ip,hostname) or whoami().who(ip)" ) ;
4142 }
4243
44+ // 1. Cast to the concrete parent command to access its public/internal fields
45+ if ( command is not WhoAmI parent )
46+ {
47+ return CommandResult . Fail ( "Extension 'who' is only compatible with the WhoAmI command." ) ;
48+ }
49+
50+ // Use the registry and the key defined by the parent command
51+ var registry = parent . Variables ;
52+ string storeKey = parent . LastStoreKey ;
53+
4354 try
4455 {
56+ // 2. Fetch existing object from the registry to allow incremental updates
57+ // This ensures that whoami(x).who(ip).who(os) preserves the IP.
58+ var whoamiData = new Dictionary < string , VmValue > ( ) ;
59+ if ( registry . TryGetObject ( storeKey , out var existingObj ) && existingObj != null )
60+ {
61+ foreach ( var kvp in existingObj )
62+ {
63+ whoamiData [ kvp . Key ] = kvp . Value ;
64+ }
65+ }
66+
67+ // 3. Gather System Data
4568 var hostname = Environment . MachineName ;
4669 var username = Environment . UserName ;
4770 var domain = Environment . UserDomainName ;
4871
49- var ips = NetworkInterface
50- . GetAllNetworkInterfaces ( )
72+ var ips = NetworkInterface . GetAllNetworkInterfaces ( )
5173 . Where ( n => n . OperationalStatus == OperationalStatus . Up )
5274 . SelectMany ( n => n . GetIPProperties ( ) . UnicastAddresses )
5375 . Where ( a => a . Address . AddressFamily == System . Net . Sockets . AddressFamily . InterNetwork )
5476 . Select ( a => a . Address . ToString ( ) )
5577 . Distinct ( )
5678 . ToList ( ) ;
5779
58- var ipsJoined = ips . Any ( ) ? string . Join ( ", " , ips ) : "None" ;
80+ string ipsJoined = ips . Any ( ) ? string . Join ( ", " , ips ) : "None" ;
5981
60- // Build a list of lines for requested fields
61- var lines = extensionArgs . Select ( arg => arg . ToLowerInvariant ( ) )
62- . Select ( field =>
82+ // 4. Parse requested fields and update the dictionary
83+ var lines = new List < string > ( ) ;
84+ foreach ( var field in extensionArgs . Select ( arg => arg . ToLowerInvariant ( ) ) )
85+ {
86+ switch ( field )
6387 {
64- return field switch
65- {
66- "hostname" => $ "Hostname: { hostname } ",
67- "username" => $ "Username: { username } ",
68- "domain" => $ "Domain: { domain } ",
69- "ip" => $ "IP: { ipsJoined } ",
70- "os" => $ "OS: { Environment . OSVersion } ",
71- "64bitos" => $ "64-bit OS: { Environment . Is64BitOperatingSystem } ",
72- "64bitprocess" => $ "64-bit Process: { Environment . Is64BitProcess } ",
73- "processorcount" => $ "Processor Count: { Environment . ProcessorCount } ",
74- "clrversion" => $ "CLR Version: { Environment . Version } ",
75- _ => $ "Unknown parameter: { field } "
76- } ;
77- } ) . ToArray ( ) ;
88+ case "hostname" :
89+ whoamiData [ "hostname" ] = VmValue . FromString ( hostname ) ;
90+ lines . Add ( $ "Hostname: { hostname } ") ;
91+ break ;
92+ case "username" :
93+ whoamiData [ "username" ] = VmValue . FromString ( username ) ;
94+ lines . Add ( $ "Username: { username } ") ;
95+ break ;
96+ case "domain" :
97+ whoamiData [ "domain" ] = VmValue . FromString ( domain ) ;
98+ lines . Add ( $ "Domain: { domain } ") ;
99+ break ;
100+ case "ip" :
101+ whoamiData [ "ip" ] = VmValue . FromString ( ipsJoined ) ;
102+ lines . Add ( $ "IP: { ipsJoined } ") ;
103+ break ;
104+ case "os" :
105+ whoamiData [ "os" ] = VmValue . FromString ( Environment . OSVersion . ToString ( ) ) ;
106+ lines . Add ( $ "OS: { Environment . OSVersion } ") ;
107+ break ;
108+ case "64bitos" :
109+ whoamiData [ "64bitos" ] = VmValue . FromBool ( Environment . Is64BitOperatingSystem ) ;
110+ lines . Add ( $ "64-bit OS: { Environment . Is64BitOperatingSystem } ") ;
111+ break ;
112+ case "64bitprocess" :
113+ whoamiData [ "64bitprocess" ] = VmValue . FromBool ( Environment . Is64BitProcess ) ;
114+ lines . Add ( $ "64-bit Process: { Environment . Is64BitProcess } ") ;
115+ break ;
116+ case "processorcount" :
117+ whoamiData [ "processorcount" ] = VmValue . FromInt ( Environment . ProcessorCount ) ;
118+ lines . Add ( $ "Processor Count: { Environment . ProcessorCount } ") ;
119+ break ;
120+ case "clrversion" :
121+ whoamiData [ "clrversion" ] = VmValue . FromString ( Environment . Version . ToString ( ) ) ;
122+ lines . Add ( $ "CLR Version: { Environment . Version } ") ;
123+ break ;
124+ default :
125+ lines . Add ( $ "Unknown parameter: { field } ") ;
126+ break ;
127+ }
128+ }
78129
79- // Join lines into a single message
80- var message = string . Join ( Environment . NewLine , lines ) ;
130+ // 5. Store the updated dictionary back into the registry
131+ // Your VariableRegistry.SetObject handles the memory overwrite/reuse logic.
132+ registry . SetObject ( storeKey , whoamiData ) ;
81133
82- return CommandResult . Ok ( message : message ) ;
134+ // 6. Return the status message
135+ string message = string . Join ( Environment . NewLine , lines ) ;
136+ return CommandResult . Ok ( message , storeKey , EnumTypes . Wobject ) ;
83137 }
84138 catch ( Exception ex )
85139 {
86140 return CommandResult . Fail ( $ "WhoExtension failed: { ex . Message } ") ;
87141 }
88142 }
89143 }
90- }
144+ }
0 commit comments