CreateProcess 执行批处理文件

Posted

技术标签:

【中文标题】CreateProcess 执行批处理文件【英文标题】:CreateProcess to execute batch file 【发布时间】:2014-10-29 15:05:33 【问题描述】:

在我创建的 Windows 应用程序中,我试图运行一个指向 .vbs 的批处理文件。它运行 vbs 脚本,但不会根据需要修改注册表。但是,如果我手动运行批处理文件,它会正常运行。有没有人知道可能是什么问题?我认为这是权限,但是如果我手动单击批处理文件或我的程序打开它,为什么会很重要?无论如何,我已经修改了批处理文件以尝试以管理员身份运行,但在线似乎没有任何效果。

【问题讨论】:

问题和标题是如何关联的? 我在程序中通过 CreateProcess 运行那个批处理文件 CreateProcess 将暗示所创建进程的一些上下文:环境块、工作目录等。它可能是导致您的问题的那些因素之一。您可能需要对您的 vbs 脚本进行实际故障排除并确定它为什么不起作用,这将帮助您找出在 CreateProcess 调用中要更改的内容。 好吧,在 createprocess 命令中,我只是调用批处理文件,然后调用 VBS。运行程序,它会要求我输入用户名、密码和域,以便在重新启动时执行自动登录功能。但是查看注册表并没有添加任何内容。但是,如果我手动运行批处理文件,它会添加到注册表并正常运行。所以我认为不是 VBS,也许是创建过程? 【参考方案1】:

它没有说 CreateProcess 可以运行批处理文件。由于批处理文件不是程序 CreateProcess 不能用它做任何事情。 CMD.exe 执行批处理文件。

您会通过测试返回值和阅读文档知道这一点

来自帮助

返回值

如果函数成功,则返回值非零。

如果函数失败,返回值为零。要获取扩展的错误信息,请调用 GetLastError。

也来自帮助

要运行批处理文件,您必须启动命令解释器;将 lpApplicationName 设置为 cmd.exe 并将 lpCommandLine 设置为批处理文件的名称。


这是你做错了

1.你有一个奇怪的程序设计。

任何程序都可以提示用户输入并写入注册表。您正在编写一个程序,该程序至少有四种不同的注册表编写方式(.NET、WSH、WMI、API)。然后您运行一个批处理,该批处理具有两种写入注册表的方式(WMI 和 reg.exe)。然后是一个有两种方式(WMI、WSH)的vbs文件。

2。您不测试错误。

您必须测试错误。只有才能访问该错误。错误说明发生了什么。您必须修复错误或崩溃。如果没有错误编号、错误来源、它试图做什么以及参数,就没有意义。

会出现错误。例如,用户确实会删除或移动文件。

3.您必须阅读文档

它必须在您编程时打开。它解释了你需要告诉它什么,它才能以某些方式运行。只需输入随机命令(就像这里的许多命令一样 - 它们当然是无效的)输入随机参数(就像你一样)不起作用。如果您不阅读它们,您将不知道它们的含义。

4.玩无奈

当你得到答案后,你去查看文档中的所有内容,然后用谷歌搜索。

你不会用可悲的“它没用”来回答。您发布错误号、错误源、尝试执行的操作以及参数。


这是解码错误的方法

解码错误

-2147220978 样式数字是32位有符号整数,用计算器转换成十六进制。

Windows 错误(小数字)和 COM HResults(通常,但也有例外,以 8 开头,如 0x80040154)在 WinError.h 中定义,除了 8007nnnn,您可以在其中查找它包含的 Window 错误号。

作为一般规则,Windows 错误少于 65,535 (0xFFFF)。从 0x80000001 开始的错误是组件对象模型 (COM) HResults。从 0xC0000001 开始的错误是 NTStatus 结果。从 0xD0000001 开始的错误也是 HResult 中返回的 NTStatus 值。

NTStatus 错误(通常但不总是以 C 开头,如 0xC0000022)在 NTStatus.h 中定义。

.h 文件是最好的来源,因为它包含错误的符号名称,可以提供诸如错误来源之类的线索。 FormatMessage 不给出符号名称,只给出描述。

您可以通过下载 Platform SDK 获得这些文件(以千兆字节为单位) http://www.microsoft.com/en-us/download/details.aspx%3Fid%3D8279&sa=U&ei=w2IrULDDLsHFmAWbmIHoBg&ved=0CBwQFjAA&usg=AFQjCNHZn9-4f2NnuN9o3UWUsOF3wL7HBQ

如果您只想要这两个文件,我将它们放在我的 skydrive 上,这样我可以随时随地参考它们。 https://skydrive.live.com/redir?resid=E2F0CE17A268A4FA!121

注意 Internet 错误 (12,000 - 12,999) 是 Windows 错误,但在 wininet.h 中指定,也可在上面找到。

在其他 .h 文件中定义了错误。但 99% 都在以上三者中。

HResults 和 NTStatus 代码的结构

HResults 中的最高有效位和 NTStatus 中的两个最高有效位设置为错误。因此 Hresults 在错误时开始 8 并且 NTStatus 在错误时开始 C。接下来的 14 位或 15 位是保留的,一些指定设施 - 错误所在的区域。这是读取十六进制时的第三个和第四个数字。 EG 0xnn07nnnn - HResult 设施代码 7 是一个正常的 Windows 错误(从 COM 程序返回 - 因此它作为 HResult 返回)。设备代码在 Winerror.h 中为 HResults 定义,在 NTStatus.h 中为 NTStatus 代码定义。它们是不同的。

解码 0x8003nnnn 错误

具有设施代码 3 的 HResults 表示 HResult 包含 OLE 结构化存储错误(0x0 到 0xff)。这些与 Dos 错误代码相同。这些似乎不在 Windows 的头文件中,代码列表在本文末尾。

解码 0x8004nnnn 错误

具有设施代码 4 的 HResults 表示 HResult 包含 OLE 错误(0x0 到 0x1ff),而范围的其余部分(0x200 以后)是组件特定的错误,因此来自一个组件的 20e 与来自另一个组件的 20e 具有不同的含义。

这就是为什么错误的来源对于 0x80040200 以上的错误尤为重要。

解码 0x8007nnnn 错误

带有设施代码 7 的 HResults 表示 HResult 包含 Windows 的错误代码。您必须查找 Windows 的错误代码而不是 HResult。

解码 0x80070002。 0x 表示它是一个十六进制数,8 表示错误,前 7 表示它是 windows 错误,其余的数字 2 是实际的 windows 错误。

要查找错误,我们需要十进制格式。启动计算器(开始 - 所有程序 - 附件 - 计算器)并选择查看菜单 - 科学,然后选择查看菜单 - 十六进制。输入 2。然后查看菜单 - 十进制。它会说 2。

启动命令提示符(开始 - 所有程序 - 附件 - 命令提示符)并键入

net helpmsg 2

它会说

The system cannot find the file specified.

或在 winerror.h 中查找

//
// MessageId: ERROR_FILE_NOT_FOUND
//
// MessageText:
//
// The system cannot find the file specified.
//
#define ERROR_FILE_NOT_FOUND             2L

解码 0x8019nnnn 错误

设施 0x19 的 HResults 是 HTTP 错误。 16384(0x4000)下的代码与HTTP错误相同,例如HTTP状态404:服务器上不存在请求的URL是0x80190194(0x194 = 404)。代码 16,384 及更高版本是 BITS 特定的。

解码 0xDnnnnnnn 错误

从 0xD 开始的 HResult 是一个带有 NTStatus 值的 HResult。只需将前导 D 更改为 C 并视为 NTStatus (Hresult = NTStatus OR 0x10000000)。

Dos 错误代码(针对 0x8003nnnn 错误)

Code Message 
01 Invalid function number 
02 File not found 
03 Path not found 
04 Too many open files (no handles left) 
05 Access denied 
06 Invalid handle 
07 Memory control blocks destroyed 
08 Insufficient memory 
09 Invalid memory block address 
0A Invalid environment 
0B Invalid format 
0C Invalid access mode (open mode is invalid) 
0D Invalid data 
0E Reserved 
0F Invalid drive specified 
10 Attempt to remove current directory 
11 Not same device 
12 No more files 
13 Attempt to write on a write-protected diskette 
14 Unknown unit 
15 Drive not ready 
16 Unknown command 
17 CRC error 
18 Bad request structure length 
19 Seek error 
1A Unknown media type 
1B Sector not found 
1C Printer out of paper 
1D Write fault 
1E Read fault 
1F General failure 
20 Sharing violation 
21 Lock violation 
22 Invalid disk change 
23 FCB unavailable 
24 Sharing buffer overflow 
25 Reserved 
26 Unable to complete file operation (DOS 4.x) 
27-31 Reserved 
32 Network request not supported 
33 Remote computer not listening 
34 Duplicate name on network 
35 Network name not found 
36 Network busy 
37 Network device no longer exists 
38 NetBios command limit exceeded 
39 Network adapter error 
3A Incorrect network response 
3B Unexpected network error 
3C Incompatible remote adapter 
3D Print queue full 
3E No space for print file 
3F Print file deleted 
40 Network name deleted 
41 Access denied 
42 Network device type incorrect 
43 Network name not found 
44 Network name limit exceeded 
45 NetBIOS session limit exceeded 
46 Temporarily paused 
47 Network request not accepted 
48 Print or disk redirection is paused 
49-4F Reserved 
50 File already exists 
51 Reserved 
52 Cannot make directory entry 
53 Fail on INT 24 
54 Too many redirections 
55 Duplicate redirection 
56 Invalid password 
57 Invalid parameter 
58 Network device fault 
59 Function not supported by network (DOS 4.x) 
5A Required system component not installed (DOS 4.x) 


Facility Codes

NTStatus Facilities  HResults Facilities  
Common status values 0x0 Null 0x0 
Debugger 0x1 Rpc 0x1 
Rpc_runtime 0x2 Dispatch 0x2 
Rpc_stubs 0x3 Storage 0x3 
Io_error_code 0x4 Itf 0x4 
Various drivers 0x5-0xf Win32 0x7 
Ntwin32 0x7 Windows 0x8 
Ntsspi 0x9 Sspi 0x9 
Terminal_server 0xa Security 0x9 
Faciltiy_mui_error_code 0xb Control 0xa 
Usb_error_code 0x10 Cert 0xb 
Hid_error_code 0x11 Internet 0xc 
Firewire_error_code 0x12 Mediaserver 0xd 
Cluster_error_code 0x13 Msmq 0xe 
Acpi_error_code 0x14 Setupapi 0xf 
Sxs_error_code 0x15 Scard 0x10 
Transaction 0x19 Complus 0x11 
Commonlog 0x1a Aaf 0x12 
Video 0x1b Urt 0x13 
Filter_manager 0x1c Acs 0x14 
Monitor 0x1d Dplay 0x15 
Graphics_kernel 0x1e Umi 0x16 
Driver_framework 0x20 Sxs 0x17 
Fve_error_code 0x21 Windows_ce 0x18 
Fwp_error_code 0x22 Http 0x19 
Ndis_error_code 0x23 Usermode_commonlog 0x1a 
Hypervisor 0x35 Usermode_filter_manager 0x1f 
Ipsec 0x36 Backgroundcopy 0x20 
Maximum_value 0x37 Configuration 0x21 
  State_management 0x22 
  Metadirectory 0x23 
  Windowsupdate 0x24 
  Directoryservice 0x25 
  Graphics 0x26 
  Shell 0x27 
  Tpm_services 0x28 
  Tpm_software 0x29 
  Pla 0x30 
  Fve 0x31 
  Fwp 0x32 
  Winrm 0x33 
  Ndis 0x34 
  Usermode_hypervisor 0x35 
  Cmi 0x36 
  Windows_defender 0x50 

【讨论】:

我试过了,但它根本不起作用。它会询问用户名、密码和域,但不会将这些值写入注册表。如果我手动单击批处理文件,尽管它会要求输入用户名、密码和域,并且它确实会写入注册表。我一直在竭尽全力,但没有任何效果,它似乎正在做某事,但在运行我的程序时并没有完成最后一步。 我确实有错误检查,它没有给出错误。我已将其更改为严格运行 Vbs 而不是使用 bat 文件,现在它只给了我一个带有 E: 的命令窗口并且不执行 VBS。由于消息中的字符限制,我必须将代码附加到第二条消息中。 codeBOOL 结果 LPTSTR cmdname = "C:\\Windows\\System32\\cmd.exe"; LPTSTR cmdargs = "E:\\Programs\\LogonScript\\AutoLogonEnable.vbs"; if(LOGINFlag.State == Unchecked) result = CreateProcess(cmdname,cmdargs,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi); WaitForSingleObject(pi.hProcess, INFINITE); LOGINFlag.State = Checked;code如果你想让我给出错误检查代码,请告诉我 对不起,代码被宰了,我需要弄清楚如何在不按回车键并提交消息的情况下按您想要的方式格式化它

以上是关于CreateProcess 执行批处理文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 CreateProcess 运行批处理文件

使用 createProcess() 运行批处理文件

如何将带有空格的路径作为参数添加到 CreateProcess 批处理文件?

用于批处理脚本的 Visual Studio 2010 CreateProcess()

使用 CreateProcess 运行带空格的 bat

使用 createprocess() 调用时,Windows 的 wget 会忽略选项