1 (изменено: chippp, 2015-05-20 12:22:51)

Тема: AHK: WIN32_Process Create не возвращает PID

Добрый день.


strComputer:="127.0.0.1"
ComObjError(1)
WbemLocator:=ComObjCreate("WbemScripting.SWbemLocator")
oCon:=WbemLocator.ConnectServer(strComputer, "root\cimv2")
oProc:=oCon.Get("Win32_Process")
oProc.Create("notepad.exe", ComObjMissing(), ComObjMissing(), processid)

MsgBox % processid
ExitApp

Проблема:
В переменную processid не возвращается pid запущенного процесса.

Описание метода Create класса Win32_Process https://msdn.microsoft.com/en-us/librar … s.85).aspx

Заранее спасибо за помощь.

2

Re: AHK: WIN32_Process Create не возвращает PID

Run, notepad.exe,,, PID
MsgBox, % PID
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: WIN32_Process Create не возвращает PID

Не подходит, процесс по факту запускаться будет на удаленной машине. localhost используется для теста.

4

Re: AHK: WIN32_Process Create не возвращает PID

А, ясно, попозже тогда напишу, если никто не опередит.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: WIN32_Process Create не возвращает PID

strComputer:="127.0.0.1"
ComObjError(1)
WbemLocator:=ComObjCreate("WbemScripting.SWbemLocator")
oCon:=WbemLocator.ConnectServer(strComputer, "root\cimv2")
oProc:=oCon.Get("Win32_Process")

processid := ComVar()
oProc.Create("notepad.exe", ComObjMissing(), ComObjMissing(), processid.ref)

MsgBox % processid[]
ExitApp

ComVar(Type=0xC)   ; http://ahkscript.org/docs/commands/ComObjActive.htm#ByRef
{
    static base := { __Get: "ComVarGet", __Set: "ComVarSet", __Delete: "ComVarDel" }
    ; Create an array of 1 VARIANT.  This method allows built-in code to take
    ; care of all conversions between VARIANT and AutoHotkey internal types.
    arr := ComObjArray(Type, 1)
    ; Lock the array and retrieve a pointer to the VARIANT.
    DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(arr), "ptr*", arr_data)
    ; Store the array and an object which can be used to pass the VARIANT ByRef.
    return { ref: ComObject(0x4000|Type, arr_data), _: arr, base: base }
}

ComVarGet(cv, p*) { ; Called when script accesses an unknown field.
    if p.MaxIndex() = "" ; No name/parameters, i.e. cv[]
        return cv._[0]
}

ComVarSet(cv, v, p*) { ; Called when script sets an unknown field.
    if p.MaxIndex() = "" ; No name/parameters, i.e. cv[]:=v
        return cv._[0] := v
}

ComVarDel(cv) { ; Called when the object is being freed.
    ; This must be done to allow the internal array to be freed.
    DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(cv._))
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: WIN32_Process Create не возвращает PID

Ну, или так, вроде попроще для понимания:

strComputer:="127.0.0.1"
ComObjError(1)
WbemLocator:=ComObjCreate("WbemScripting.SWbemLocator")
oCon:=WbemLocator.ConnectServer(strComputer, "root\cimv2")
oProc:=oCon.Get("Win32_Process")

processid := new ComVar
oProc.Create("notepad.exe", ComObjMissing(), ComObjMissing(), processid.ref)

MsgBox % processid[]
ExitApp

class ComVar
{   
   __New(Type = 0xC)  {  ; VT_VARIANT := 0xC
      this.arr := ComObjArray(Type, 1)
      DllCall("oleaut32\SafeArrayAccessData", Ptr, ComObjValue(this.arr), PtrP, arr_data)
      this.ref := ComObject(0x4000|Type, arr_data)  ; VT_BYREF := 0x4000
   }
   
   __Get(p*)  {
      if p.MaxIndex() = ""
         Return this.arr[0]
   }
   
   __Delete()  {
      DllCall("oleaut32\SafeArrayUnaccessData", Ptr, ComObjValue(this.arr))
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

7

Re: AHK: WIN32_Process Create не возвращает PID

Проверил. Работает. Спасибо огромное.

8 (изменено: wisgest, 2015-05-26 03:58:40)

Re: AHK: WIN32_Process Create не возвращает PID

У меня вот так работает:

strComputer:="127.0.0.1"
ComObjError(1)
WbemLocator:=ComObjCreate("WbemScripting.SWbemLocator")
oCon:=WbemLocator.ConnectServer(strComputer, "root\cimv2")
oProc:=oCon.Get("Win32_Process")

objInParams := oProc.Methods_("Create").InParameters.SpawnInstance_()
objInParams.CommandLine := "notepad.exe"
objOutParams := oProc.ExecMethod_("Create", objInParams)
MsgBox % objOutParams.ProcessId
ExitApp

Решение взято из незаслуженно удалённой темы «JScript: Работа с WMI»:

+ открыть спойлер

2007-08-24 23:23:41

mozers пишет:

Имеем вполне рабочий VBS код, для запуска процесса и показа присвоенного ему индификатора:

Set objProcess = GetObject("winmgmts:\\.\root\cimv2:Win32_Process")
pID=0
errReturn = objProcess.Create("cmd", null, null, pID)
WScript.Echo "Create ProcessID = " & pID

Тот же самый код, но выполненный на JS, лишь запускает процесс, но почему то никак не хочет присваивать значение индефикатору процесса:

var objProcess = GetObject("winmgmts:\\\\.\\root\\cimv2:Win32_Process");
var pID=0;
var errReturn = objProcess.Create("cmd", null, null, pID);
WScript.Echo ("Create ProcessID = " + pID);

Как заставить последний скрипт присваивать значение pID ?

2007-08-25 08:15:53

YMP пишет:

Возможно ссылка, которую приводил alexii, объясняет этот казус: Скрипты и [out] параметры COM-методов
Если я правильно уловил суть, VBS в таких случаях передаёт переменные методу по ссылке, а JScript - по значению. Т.е. создаётся временная переменная, туда копируется значение из pID и передаётся методу. Поэтому все изменения происходят во временной переменной, а pID остаётся как был.

2007-08-25 10:22:06

mozers пишет:

2YMP
Похоже что Вы совершенно правы и причина именно в этом. (Я тоже нашел анонс статьи из журнала Scripting Pro VIP, где рассматривется эта проблема и вроде как даже дается решение).
Но и про приведенной Вами ссылке и в найденном мной анонсе описана _причина_, но, увы, нет _решения_
Так все таки КАК ПОБЕДИТЬ ??? (меня интересует только изложенный выше конкретный пример).

2007-08-25 11:18:00

YMP пишет:

Статья в MSDN, возможно, даёт намёк на решение: Writing WMI Scripts in JScript

Methods in VBScript can be called directly, while JScript methods are called with the SWbemMethod, InParam, and OutParam objects.

К сожалению, в дальнейшем я ничего не понял, т.е. мои знания в WMI близки к нулю.

2007-08-25 12:31:20

The gray Cardinal пишет:

Для тех, кто не ищет лёгких путей :

objProcess = GetObject("winmgmts:\\\\.\\root\\cimv2:Win32_Process");
objInParams = objProcess.Methods_("Create").InParameters.SpawnInstance_();
objInParams.CommandLine = "cmd";
objOutParams = objProcess.ExecMethod_("Create", objInParams);
WScript.Echo(objOutParams.ProcessId);

2007-08-25 12:55:41

alexii пишет:

2mozers
Не забывайте про WMI Code Creator, с его помощью можно получить практически готовый шаблон кода (в том числе и этот; останется перевести его на jscript  )

2007-08-25 13:33:33

The gray Cardinal пишет:

OFF. На правах рекламы (Python)

import wmi
c = wmi.WMI()
pID, result = c.Win32_Process.Create("cmd")
print pID

2007-08-26 00:26:39

mozers пишет:

Спасибо ВСЕМ за отзывчивость, толковые советы и реальную помощь!
Все работатет
Мой скрипт запускает разные программки на другой машине, а если я где то ошибся и программка зависла (слишком уж долго выполняется), то скрипт ее принудительно завершает.
Все было написано на VBS, ща переписал на JS (он мне больше нравится), но вот на этом пунктике затормозил...
СПАСИБО, помогли!
WMI Code Creator - тоже штука неплохая, получше Scriptomatic2 будет, хотя у последнего больше форматов на выходе (в т.ч. и JS). Вот только с помощью оных приблуд код, что The gray Cardinal написал, не создашь

Мне почему-то казалось, что эта тема нашла отражение в Коллекции — выходит, ошибался…


Хотя, решение, которое привёл teadrinker — позволяющее работать с аргументами функций, передаваемыми по ссылке, — является более общим, по крайней мере для AutoHotkey.