Discussion:
How do I call a Windows API function?
(too old to reply)
Helge Kruse
2010-08-17 14:45:40 UTC
Permalink
Hello,

I need to get the proceess identifier of the process that executes my
JScript.

This information is provided by the Win32 API function GetCurrentProcessId.
But how can I call this function from my .js program? I know, that I could
write a in-process COM server that performs the actual call, but this looks
like overkill for calling one function.

Helge
--
Time is an ocean but it ends at the shore.
-TNO-
2010-08-17 17:51:28 UTC
Permalink
Post by Helge Kruse
Hello,
I need to get the proceess identifier of the process that executes my
JScript.
This information is provided by the Win32 API function GetCurrentProcessId.
But how can I call this function from my .js program? I know, that I could
write a in-process COM server that performs the actual call, but this looks
like overkill for calling one function.
function getPID(){
var objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2"),
sql = "SELECT * FROM Win32_Process " +
"WHERE (Name='cscript.exe' OR Name='wscript.exe') " +
" AND CommandLine LIKE '%" + WScript.ScriptName +
"%'",
e = new Enumerator(objWMIService.ExecQuery(sql,"WQL",48)
), pid;

for (;!e.atEnd();e.moveNext()){
var objItem = e.item();
return objItem.ProcessId
}

return void 0;
}


Note that this works only in JScript executed by the WSH. Other
environments require a different approach.
Helge Kruse
2010-08-18 06:22:14 UTC
Permalink
Post by Helge Kruse
Hello,
Post by Helge Kruse
I need to get the proceess identifier of the process that executes my
JScript.
This information is provided by the Win32 API function
GetCurrentProcessId.
But how can I call this function from my .js program? I know, that I could
write a in-process COM server that performs the actual call, but this looks
like overkill for calling one function.
function getPID(){
var objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2"),
sql = "SELECT * FROM Win32_Process " +
"WHERE (Name='cscript.exe' OR Name='wscript.exe') " +
" AND CommandLine LIKE '%" + WScript.ScriptName +
"%'",
e = new Enumerator(objWMIService.ExecQuery(sql,"WQL",48)
), pid;
for (;!e.atEnd();e.moveNext()){
var objItem = e.item();
return objItem.ProcessId
}
return void 0;
}
You near to it. The goal is to identify, if the script is hosted by wscript
or cscript. Unfortunately this doesn't work, since the query does not
distinguish between two instances of the same script.

Further I need to execute this in a WSC component implemented with JScript.
There is no WScript available in this context.
-TNO-
2010-08-19 04:02:42 UTC
Permalink
Post by Helge Kruse
Post by Helge Kruse
Hello,
Post by Helge Kruse
I need to get the proceess identifier of the process that executes my
JScript.
This information is provided by the Win32 API function
GetCurrentProcessId.
But how can I call this function from my .js program? I know, that I could
write a in-process COM server that performs the actual call, but this looks
like overkill for calling one function.
function getPID(){
   var objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2"),
       sql = "SELECT * FROM Win32_Process " +
             "WHERE (Name='cscript.exe' OR Name='wscript.exe') " +
             "      AND CommandLine LIKE '%" + WScript.ScriptName +
"%'",
       e = new Enumerator(objWMIService.ExecQuery(sql,"WQL",48)
       ), pid;
   for (;!e.atEnd();e.moveNext()){
   var objItem = e.item();
       return objItem.ProcessId
   }
   return void 0;
}
You near to it. The goal is to identify, if the script is hosted by wscript
or cscript. Unfortunately this doesn't work, since the query does not
distinguish between two instances of the same script.
Further I need to execute this in a WSC component implemented with JScript.
There is no WScript available in this context.
I noticed your post here and it was a bit more enlightening:
https://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.scripting.vbscript&tid=60fa2d0d-20fb-4cfd-8464-de80dc63b615&cat=&lang=&cr=&sloc=&p=1

The problem is that there is no way to directly discover the caller of
a component if a reference is not passed, so anything that could be
come up with will probably be little more than a hack I think.

Here is an alternative hack I've came up with:

http://pastebin.com/k8Vy1GdH

The general idea I used is to query all the possibly relevant
processes at the time of component creation and then to filter out all
but the latest one.

The sorting is probably bugged since I was lazy and wanted to convey
the general idea. The non-lazy idea would be to use a regular
expression on the CreationDates then feed those into 2 date objects
for comparison.

Hopefully this can get you on the right path.
Helge Kruse
2010-08-19 12:40:32 UTC
Permalink
Post by -TNO-
The problem is that there is no way to directly discover the caller of
a component if a reference is not passed, so anything that could be
come up with will probably be little more than a hack I think.
http://pastebin.com/k8Vy1GdH
The general idea I used is to query all the possibly relevant
processes at the time of component creation and then to filter out all
but the latest one.
The sorting is probably bugged since I was lazy and wanted to convey
the general idea. The non-lazy idea would be to use a regular
expression on the CreationDates then feed those into 2 date objects
for comparison.
Thanks for proposing this approach. Using the last started cscript/wscript
process as the own process looks like a solution. But since some of my
scripts does not instantiate the WSC immediately the detection is not safe.
I don't expect that someone changes the default scripting host at the
command line. But you get a race condition though when starting wscript by
doubleclick in explorer and cscript from the command line.

Helge
-TNO-
2010-08-19 17:56:57 UTC
Permalink
Post by -TNO-
The problem is that there is no way to directly discover the caller of
a component if a reference is not passed, so anything that could be
come up with will probably be little more than a hack I think.
http://pastebin.com/k8Vy1GdH
The general idea I used is to query all the possibly relevant
processes at the time of component creation and then to filter out all
but the latest one.
The sorting is probably bugged since I was lazy and wanted to convey
the general idea. The non-lazy idea would be to use a regular
expression on the CreationDates then feed those into 2 date objects
for comparison.
Thanks for proposing this approach. Using the last started cscript/wscript.
process as the own process looks like a solution. But since some of my
scripts does not instantiate the WSC immediately the detection is not safe.
I don't expect that someone changes the default scripting host at the
command line. But you get a race condition though when starting wscript by
doubleclick in explorer and cscript from the command line.
Helge
Indeed, at this point the solution comes down to trickery and
inference me thinks. There is no way you can alter the source files?

hmm. Another possible approach: have the WSC component run a program
in hidden mode, then use WMI to query the owning process of that
program.
Helge Kruse
2010-08-20 05:50:00 UTC
Permalink
Post by -TNO-
hmm. Another possible approach: have the WSC component run a program
in hidden mode, then use WMI to query the owning process of that
program.
I it's not clear to me, how an additional process (program) would help here.
But I could also write a COM-DLL that can be instantiated by the WSC. Then I
have the Win32 API avaiable. One problem might be the registration of that
DLL.

Finally I think, I have to think about another approach for the overall
problem.
-TNO-
2010-08-20 18:50:28 UTC
Permalink
Post by Helge Kruse
I it's not clear to me, how an additional process (program) would help here.
But I could also write a COM-DLL that can be instantiated by the WSC. Then I
have the Win32 API avaiable. One problem might be the registration of that
DLL.
Finally I think, I have to think about another approach for the overall
problem.
This is what I meant:

http://pastebin.com/ZpyPD1dU

I think this works for obtaining the appropriate pid. A second query
would have to be done though using the resulting pid to obtain the
related host, but that is trivial enough with the proper pid in hand.
For cleanup purposes, its probably better to run a query-able process
that probably won't be in use (calc.exe perhaps)
Helge Kruse
2010-08-23 07:19:22 UTC
Permalink
Post by -TNO-
http://pastebin.com/ZpyPD1dU
I think this works for obtaining the appropriate pid.
I don't think so. It kills all calc processes and opens a new cmd window.
The pid is indefined if no calc process was running before.

Helge
-TNO-
2010-08-23 19:15:47 UTC
Permalink
Post by Helge Kruse
Post by -TNO-
http://pastebin.com/ZpyPD1dU
I think this works for obtaining the appropriate pid.
I don't think so. It kills all calc processes and opens a new cmd window.
The pid is indefined if no calc process was running before.
Updated:

http://pastebin.com/MzwX3VMv
-TNO-
2010-08-23 19:21:00 UTC
Permalink
Post by -TNO-
http://pastebin.com/MzwX3VMv
I missed a semicolon:

http://pastebin.com/CssWev93

Kenneth A. Larsen
2010-08-20 21:57:52 UTC
Permalink
Post by Helge Kruse
Post by -TNO-
hmm. Another possible approach: have the WSC component run a program
in hidden mode, then use WMI to query the owning process of that
program.
I it's not clear to me, how an additional process (program) would help
here. But I could also write a COM-DLL that can be instantiated by the
WSC. Then I have the Win32 API avaiable. One problem might be the
registration of that DLL.
Finally I think, I have to think about another approach for the overall
problem.
Good!
-TNO-
2010-08-17 17:53:24 UTC
Permalink
Post by Helge Kruse
Hello,
I need to get the proceess identifier of the process that executes my
JScript.
This information is provided by the Win32 API function GetCurrentProcessId.
But how can I call this function from my .js program? I know, that I could
write a in-process COM server that performs the actual call, but this looks
like overkill for calling one function.
function getPID(){
var objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2"),
sql = "SELECT * FROM Win32_Process " +
"WHERE (Name='cscript.exe' OR Name='wscript.exe') " +
" AND CommandLine LIKE '%" + WScript.ScriptName +
"%'",
e = new Enumerator(objWMIService.ExecQuery(sql,"WQL",48)
), pid;

for (;!e.atEnd();e.moveNext()){
var objItem = e.item();
return objItem.ProcessId
}

return void 0;
}
Loading...