在 python 的 pywin32、win32job、CreateJobObject 函数中,如何为名称参数传递 NULL?
In python with pywin32, win32job, the CreateJobObject function, how do I pass NULL for the name parameter?
我正在尝试使用 PyWin32 包中的 win32job API。我想这样做:
win32job.CreateJobObject(None, NULL)
我想将 NULL 作为第二个参数传递,如下所述:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682409(v=vs.85).aspx
If lpName is NULL, the job is created without a name.
如何传入NULL?
这是我希望有效但无效的方法:
win32job.CreateJobObject(None, None)
错误:
TypeError: None is not a valid string in this context
(附带问题...如果有人知道如何查看与 Windows 中的进程关联的 JobObjects,那将很有帮助。)
您可以使用 win32job.CreateJobObject(None, "")
。尽管未在 [MS.Docs]: CreateJobObjectA function 上指定,但空字符串的行为与 NULL.
相同
根据上面的link:
If the function succeeds, the return value is a handle to the job object. The handle has the JOB_OBJECT_ALL_ACCESS access right. If the object existed before the function call, the function returns a handle to the existing job object and GetLastError returns ERROR_ALREADY_EXISTS.
我写了一个小的 C 程序用于演示:
#include <Windows.h>
#include <stdio.h>
#define EMPTY_TEXT ""
#define DUMMY0_TEXT "dummy0"
#define DUMMY1_TEXT "dummy1"
#define DIM 12
int main() {
char* names[DIM] = { NULL, NULL, EMPTY_TEXT, EMPTY_TEXT, DUMMY0_TEXT,
DUMMY0_TEXT, EMPTY_TEXT, DUMMY0_TEXT, DUMMY1_TEXT,
NULL, DUMMY0_TEXT, DUMMY1_TEXT };
HANDLE jobs[DIM] = { NULL };
for (int i = 0; i < DIM; i++) {
jobs[i] = CreateJobObjectA(NULL, names[i]);
printf("%02d [%6s] CreateJobObject: %08X - GetLastError: %d\n", i, names[i], (long)jobs[i], GetLastError());
}
for (int i = 0; i < DIM; i++)
CloseHandle(jobs[i]);
return 0;
}
输出(使用VStudio 2015 Community Edition构建并运行):
00 [(null)] CreateJobObject: 000000D8 - GetLastError: 0
01 [(null)] CreateJobObject: 000000E0 - GetLastError: 0
02 [ ] CreateJobObject: 00000088 - GetLastError: 0
03 [ ] CreateJobObject: 000000F0 - GetLastError: 0
04 [dummy0] CreateJobObject: 000000F4 - GetLastError: 0
05 [dummy0] CreateJobObject: 000000F8 - GetLastError: 183
06 [ ] CreateJobObject: 000000E8 - GetLastError: 0
07 [dummy0] CreateJobObject: 000000FC - GetLastError: 183
08 [dummy1] CreateJobObject: 00000100 - GetLastError: 0
09 [(null)] CreateJobObject: 000000DC - GetLastError: 0
10 [dummy0] CreateJobObject: 000000E4 - GetLastError: 183
11 [dummy1] CreateJobObject: 00000104 - GetLastError: 183
你可以看到对于 "dummy0" 和 "dummy",每次(除了 1st) 创建新对象时,该函数会 return 一个新的 HANDLE,但失败 (GetLastError returns 183(即 ERROR_ALREADY_EXISTS)。 NULL and 空字符串名称不会发生这种情况(从这里我了解到每次调用都会创建一个新对象,而不是递增一个现有对象的引用)。
Python "translation" (code.py):
#!/usr/bin/env python3
import win32job
import win32api
DUMMY0 = "dummy00"
DUMMY1 = "dummy11"
JOB_NAMES = ["", "", DUMMY0, DUMMY0, "", DUMMY1, DUMMY0, "", DUMMY1]
if __name__ == "__main__":
handles = list()
for i, name in enumerate(JOB_NAMES):
h = win32job.CreateJobObject(None, name)
print("{} [{:10}] {} - GetLastError: {}".format(i, name, h, win32api.GetLastError()))
handles.append(h)
for h in handles:
win32api.CloseHandle(h)
输出(结果与C的情况相同——这是自然的,因为Python 函数只包装较低级别的 C 个):
(py35x64_test) e:\Work\Dev\Whosebug\q046800142>"c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
0 [ ] <PyHANDLE:300> - GetLastError: 0
1 [ ] <PyHANDLE:308> - GetLastError: 0
2 [dummy00 ] <PyHANDLE:580> - GetLastError: 0
3 [dummy00 ] <PyHANDLE:584> - GetLastError: 183
4 [ ] <PyHANDLE:588> - GetLastError: 0
5 [dummy11 ] <PyHANDLE:592> - GetLastError: 0
6 [dummy00 ] <PyHANDLE:596> - GetLastError: 183
7 [ ] <PyHANDLE:600> - GetLastError: 0
8 [dummy11 ] <PyHANDLE:604> - GetLastError: 183
关于 "side" 问题:很遗憾,我不熟悉该主题。
我正在尝试使用 PyWin32 包中的 win32job API。我想这样做:
win32job.CreateJobObject(None, NULL)
我想将 NULL 作为第二个参数传递,如下所述:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682409(v=vs.85).aspx
If lpName is NULL, the job is created without a name.
如何传入NULL?
这是我希望有效但无效的方法:
win32job.CreateJobObject(None, None)
错误:
TypeError: None is not a valid string in this context
(附带问题...如果有人知道如何查看与 Windows 中的进程关联的 JobObjects,那将很有帮助。)
您可以使用 win32job.CreateJobObject(None, "")
。尽管未在 [MS.Docs]: CreateJobObjectA function 上指定,但空字符串的行为与 NULL.
根据上面的link:
If the function succeeds, the return value is a handle to the job object. The handle has the JOB_OBJECT_ALL_ACCESS access right. If the object existed before the function call, the function returns a handle to the existing job object and GetLastError returns ERROR_ALREADY_EXISTS.
我写了一个小的 C 程序用于演示:
#include <Windows.h>
#include <stdio.h>
#define EMPTY_TEXT ""
#define DUMMY0_TEXT "dummy0"
#define DUMMY1_TEXT "dummy1"
#define DIM 12
int main() {
char* names[DIM] = { NULL, NULL, EMPTY_TEXT, EMPTY_TEXT, DUMMY0_TEXT,
DUMMY0_TEXT, EMPTY_TEXT, DUMMY0_TEXT, DUMMY1_TEXT,
NULL, DUMMY0_TEXT, DUMMY1_TEXT };
HANDLE jobs[DIM] = { NULL };
for (int i = 0; i < DIM; i++) {
jobs[i] = CreateJobObjectA(NULL, names[i]);
printf("%02d [%6s] CreateJobObject: %08X - GetLastError: %d\n", i, names[i], (long)jobs[i], GetLastError());
}
for (int i = 0; i < DIM; i++)
CloseHandle(jobs[i]);
return 0;
}
输出(使用VStudio 2015 Community Edition构建并运行):
00 [(null)] CreateJobObject: 000000D8 - GetLastError: 0 01 [(null)] CreateJobObject: 000000E0 - GetLastError: 0 02 [ ] CreateJobObject: 00000088 - GetLastError: 0 03 [ ] CreateJobObject: 000000F0 - GetLastError: 0 04 [dummy0] CreateJobObject: 000000F4 - GetLastError: 0 05 [dummy0] CreateJobObject: 000000F8 - GetLastError: 183 06 [ ] CreateJobObject: 000000E8 - GetLastError: 0 07 [dummy0] CreateJobObject: 000000FC - GetLastError: 183 08 [dummy1] CreateJobObject: 00000100 - GetLastError: 0 09 [(null)] CreateJobObject: 000000DC - GetLastError: 0 10 [dummy0] CreateJobObject: 000000E4 - GetLastError: 183 11 [dummy1] CreateJobObject: 00000104 - GetLastError: 183
你可以看到对于 "dummy0" 和 "dummy",每次(除了 1st) 创建新对象时,该函数会 return 一个新的 HANDLE,但失败 (GetLastError returns 183(即 ERROR_ALREADY_EXISTS)。 NULL and 空字符串名称不会发生这种情况(从这里我了解到每次调用都会创建一个新对象,而不是递增一个现有对象的引用)。
Python "translation" (code.py):
#!/usr/bin/env python3
import win32job
import win32api
DUMMY0 = "dummy00"
DUMMY1 = "dummy11"
JOB_NAMES = ["", "", DUMMY0, DUMMY0, "", DUMMY1, DUMMY0, "", DUMMY1]
if __name__ == "__main__":
handles = list()
for i, name in enumerate(JOB_NAMES):
h = win32job.CreateJobObject(None, name)
print("{} [{:10}] {} - GetLastError: {}".format(i, name, h, win32api.GetLastError()))
handles.append(h)
for h in handles:
win32api.CloseHandle(h)
输出(结果与C的情况相同——这是自然的,因为Python 函数只包装较低级别的 C 个):
(py35x64_test) e:\Work\Dev\Whosebug\q046800142>"c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py 0 [ ] <PyHANDLE:300> - GetLastError: 0 1 [ ] <PyHANDLE:308> - GetLastError: 0 2 [dummy00 ] <PyHANDLE:580> - GetLastError: 0 3 [dummy00 ] <PyHANDLE:584> - GetLastError: 183 4 [ ] <PyHANDLE:588> - GetLastError: 0 5 [dummy11 ] <PyHANDLE:592> - GetLastError: 0 6 [dummy00 ] <PyHANDLE:596> - GetLastError: 183 7 [ ] <PyHANDLE:600> - GetLastError: 0 8 [dummy11 ] <PyHANDLE:604> - GetLastError: 183
关于 "side" 问题:很遗憾,我不熟悉该主题。