从CreateProcess()执行时,diskpart不能正确处理脚本

时间:2015-01-09 17:27:32

标签: c++ windows winapi

diskpart" myScript.txt":

select disk 1
convert dynamic noerr
select disk 2
convert dynamic noerr
create volume stripe disk=1,2 noerr
assign letter=X noerr


从命令提示符运行时:diskpart /s myScript.txt 按预期工作

然而,使用win api' CreateProcess()运行时,转换命令执行工作但是当它到达时  create volume,显示:

"The arguments you specified for this command are not valid"

。 。

现在,让事情变得更有趣:
如果第二次从CreateProcess()再次执行脚本(给定磁盘现在已转换,并为转换comamnds提供正确错误), 当它到达create volume时,确实有效。

这让我觉得它与磁盘和/或可执行文件有关吗?

正确的方向上的任何一点都值得赞赏,因为这非常令人困惑。谢谢。

STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(si);
strncpy( command, "diskpart.exe /s myScript.txt", (sizeof(command) - 1) );  

             CreateProcess( "c:\\WINDOWS\\system32\\diskpart.exe",
                             command,
                             NULL,
                             NULL,
                             TRUE,
                             0,
                             NULL,
                             NULL,
                             &si,
                             &pi ) );

结束原始问题________________________________________________________

修改:
更新和更多信息:

  • 在创建卷命令之前添加了大约15 - 20秒的延迟,仍然收到相同的错误消息。

  • 此外,将工作分成两个脚本,两次调用 的CreateProcess()。在第二个脚本上,只需调用"创建卷" 并分配,它挂了一段时间,然后回来了"这 命令无法在此时完成" ..或某事 效果。

  • 需要注意的另一件事是:在第一个脚本上,将它们放入 与运行相比,它的运行速度慢了两倍 命令提示符。

也许应该只运行整个事情两次(第二次运行时出错),因为它确实有效

EDIT2
这两个脚本现在正在工作,或者在我再次尝试时工作。不知道为什么它第一次没有工作。

3 个答案:

答案 0 :(得分:4)

因为你的脚本第二次工作,所以最可能的原因似乎与时序有关 - 在create volume命令执行时,卷还没有准备好。

基于这个假设:

您可以在detail disk命令之前添加create volume命令以查找磁盘的状态。这将告诉你一些关于磁盘当前状态的信息。如果磁盘2没有显示任何有趣的内容,也请选择第一个磁盘以显示其详细信息。您从中获得的信息可能会有所帮助。

至于实际解决问题,通过使磁盘联机和脱机引入延迟可能会有所帮助。例如:

select disk 1
convert dynamic
select disk 2
convert dynamic
select disk 1
offline disk
select disk 2
offline disk
select disk 1
online disk
select disk 2
online disk
create volume stripe disk=1,2
assign letter=X

答案 1 :(得分:2)

以下是关于第一个参数的http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx说明的摘录:

  

lpApplicationName参数可以为NULL。在这种情况下,模块名称必须是lpCommandLine字符串中第一个以空格分隔的标记。

     

如果可执行模块是16位应用程序,则lpApplicationName应为NULL,lpCommandLine指向的字符串应指定可执行模块及其参数。

given the above, Suggest:
(first, assure command[] buffer is plenty large enough for the following)
(may have to add the path for the 'myStript.txt)
(may be necessary to add some wait time before calling CreateProcess() 
 to assure the prior commands have completed.

strncpy( command, "c:\\Windows\\System32\\diskpart.exe /s myScript.txt", (sizeof(command) - 1) );  

CreateProcess(  NULL,
                command,
                NULL,
                NULL,
                TRUE,
                0,
                NULL,
                NULL,
                &si,
                &pi ) );

答案 2 :(得分:2)

因为它可能是一个计时问题,所以你应该确保正确地等待diskpart命令的结束,然后继续进行父程序。

当我想模拟cmd.exe处理时,我总是在WaitForSingleObject之后使用CreateProcess

CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);

此序列更接近旧的system函数...