mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Feb 2015
Posts: 138
kap Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Feb 2015
Posts: 138
The below code queries process information for mirc.exe via WMI, which in theory means you can get at it through mIRC COM...

Code
wmic process where name="mirc.exe" get /value


If you wanted to query the ram usuage of your current mirc instance, how would you do that? I mean, say you have more than one mirc.exe open, how can you look it up? Is there a PID identifier in mirc that can help?


GNU Terry Pratchett - Looking for a mIRC help channel -> Check #mircscripting @ irc.swiftirc.net
Joined: Dec 2015
Posts: 148
Vogon poet
Offline
Vogon poet
Joined: Dec 2015
Posts: 148
Code
alias mywmi {
  .comopen wmi.open WbemScripting.SWbemLocator
  .comclose wmi.open $com(wmi.open,ConnectServer,1,bstr,.,bstr,root\CIMV2,dispatch* wmi.locator)
  set -l %properties Caption CommandLine CreationClassName CreationDate CSCreationClassName CSName Description ExecutablePath ExecutionState Handle HandleCount InstallDate KernelModeTime MaximumWorkingSetSize MinimumWorkingSetSize Name OSCreationClassName OSName OtherOperationCount OtherTransferCount PageFaults PageFileUsage ParentProcessId PeakPageFileUsage PeakVirtualSize PeakWorkingSetSize Priority PrivatePageCount ProcessId QuotaNonPagedPoolUsage QuotaPagedPoolUsage QuotaPeakNonPagedPoolUsage QuotaPeakPagedPoolUsage ReadOperationCount ReadTransferCount SessionId Status TerminationDate ThreadCount UserModeTime VirtualSize WindowsVersion WorkingSetSize WriteOperationCount WriteTransferCount
  .comclose wmi.locator $com(wmi.locator,ExecQuery,1,bstr,SELECT * FROM Win32_Process WHERE ExecutablePath=" $+ $replacex($mircexe,\,\\) $+ ",dispatch* wmi.properties) $com(wmi.properties,Count,3)
  set -l %instances $com(wmi.properties).result
  echo -a Retrieving $numtok(%properties,32) properties(s) from %instances instances from Win32_Process class in root\CIMV2 namespace
  set -l %x 1
  while (%x <= %instances) {
    tokenize 32 %properties
    while ($1) {
      echo -a Instance $+($chr(35),%x,:) $1 = $comval(wmi.properties,%x,$1)
      tokenize 32 $2-
    }
    inc %x
  }
  .comclose wmi.properties
  :error
  if ($error) {
    if ($com(wmi.open)) .comclose wmi.open
    if ($com(wmi.locator)) .comclose wmi.locator
    if ($com(wmi.properties)) .comclose wmi.properties
  }
}
/MYWMI

It uses $mircexe and ExecutablePath to identify the right process. If more than one process has the same ExecutablePath, it'll list all of them.

You could potentially get the right PID with some tricks, but as far as I know there's no straight forward way to do it. Maybe by starting another program and checking for the parent ID or something, but I assume ExecutablePath is accurate enough in most cases.

Shameless plug: WMI Explorer for mIRC https://mircscripts.net/Ls5JN

Joined: Feb 2015
Posts: 138
kap Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Feb 2015
Posts: 138
I define multiple instances of mIRC, each with their own working directory by creating a shortcut to (the same) mirc.exe and specifying a command line switch, for example: -r"%appdata%\mIRC1"

I think I can search for the CommandLine property in WMI for the mirc.exe process by using $mircexe and $cmdline to get the WorkingSetSize, but yeah maybe a $pid would work wonders!

Thanks for the WMI example, much appreciated!


GNU Terry Pratchett - Looking for a mIRC help channel -> Check #mircscripting @ irc.swiftirc.net
Joined: Dec 2015
Posts: 148
Vogon poet
Offline
Vogon poet
Joined: Dec 2015
Posts: 148
Just because I got bored:
Code
alias mywmi {
  .comopen wmi.open WbemScripting.SWbemLocator
  .comclose wmi.open $com(wmi.open,ConnectServer,1,bstr,.,bstr,root\CIMV2,dispatch* wmi.locator)
  set -l %properties Caption CommandLine CreationClassName CreationDate CSCreationClassName CSName Description ExecutablePath ExecutionState Handle HandleCount InstallDate KernelModeTime MaximumWorkingSetSize MinimumWorkingSetSize Name OSCreationClassName OSName OtherOperationCount OtherTransferCount PageFaults PageFileUsage ParentProcessId PeakPageFileUsage PeakVirtualSize PeakWorkingSetSize Priority PrivatePageCount ProcessId QuotaNonPagedPoolUsage QuotaPagedPoolUsage QuotaPeakNonPagedPoolUsage QuotaPeakPagedPoolUsage ReadOperationCount ReadTransferCount SessionId Status TerminationDate ThreadCount UserModeTime VirtualSize WindowsVersion WorkingSetSize WriteOperationCount WriteTransferCount
  .comclose wmi.locator $com(wmi.locator,ExecQuery,1,bstr,SELECT * FROM Win32_Process WHERE ExecutablePath=" $+ $replacex($mircexe,\,\\) $+ " AND CommandLine='" $+ $replacex($mircexe,\,\\) $+ " $cmdline $+ ',dispatch* wmi.properties) $com(wmi.properties,Count,3)
  set -l %instances $com(wmi.properties).result
  echo -a Retrieving $numtok(%properties,32) properties(s) from %instances instances from Win32_Process class in root\CIMV2 namespace
  set -l %x 1
  while (%x <= %instances) {
    tokenize 32 %properties
    while ($1) {
      echo -a Instance $+($chr(35),%x,:) $1 = $comval(wmi.properties,%x,$1)
      tokenize 32 $2-
    }
    inc %x
  }
  .comclose wmi.properties
  :error
  if ($error) {
    if ($com(wmi.open)) .comclose wmi.open
    if ($com(wmi.locator)) .comclose wmi.locator
    if ($com(wmi.properties)) .comclose wmi.properties
  }
}

It uses both ExecutablePath and CommandLine to get the right instance. Assuming each $cmdline is different, this should give the right answer each time.


I was also testing PID, and this is the easiest straight forward way to get the right one I could come up with:
Code
alias pid {
  tokenize 1 $ctime
  while ($1 == $ctime) noop
  .comopen wmi.open WbemScripting.SWbemLocator
  .comclose wmi.open $com(wmi.open,ConnectServer,1,bstr,.,bstr,root\CIMV2,dispatch* wmi.locator)
  .comclose wmi.locator $com(wmi.locator,ExecQuery,1,bstr,SELECT * FROM Win32_Process WHERE ExecutablePath = " $+ $replacex($mircexe,\,\\) $+ ",dispatch* wmi.properties) $com(wmi.properties,Count,3)
  set -l %d $asctime($floor($calc($ctime -($uptime(mirc)/1000))),yyyymmddHHnnss)
  set -l %x 1
  set -l %pid
  while (%x <= $com(wmi.properties).result) {
    if (%d $+ .* iswm $comval(wmi.properties,%x,CreationDate)) %pid = $comval(wmi.properties,%x,ProcessId)
    inc %x
  }
  .comclose wmi.properties
  return %pid
  :error
  if ($com(wmi.open)) .comclose wmi.open
  if ($com(wmi.locator)) .comclose wmi.locator
  if ($com(wmi.properties)) .comclose wmi.properties
}

It uses CreationDate to figure out the right instance, but this will fail if the mIRC instances were started at the same exact time.

Joined: Feb 2015
Posts: 138
kap Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Feb 2015
Posts: 138
I have been looking at various straight forward ways to get at the pid, through COM, command line, powershell, vbscript etc, but no go.

There's an inbuild windows function called GetCurrentProcessId(), but I can't get to it through mIRC's `/dll` command...

Unless there's a $mircpid identifier, this will have to do...

Thanks again!


Last edited by kap; 13/12/20 11:25 AM.

GNU Terry Pratchett - Looking for a mIRC help channel -> Check #mircscripting @ irc.swiftirc.net

Link Copied to Clipboard