T.T.T.
T.T.T.

Reputation: 34603

diskpart does not process script correctly when executed from CreateProcess()

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

.
.

When running from the command prompt: diskpart /s myScript.txt it works as expected.

However, when run using win api's CreateProcess() both the convert commands do work but when it gets to
create volume, it displays:

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

. .

Now, to make things more interesting:
If the script is executed again from CreateProcess() a 2nd time (given the disks are now converted and it gives a correct error for the convert comamnds), when it gets to the create volume, it does work.

This makes me think it has something do with the disks and or executable?

Any point in the right direction is appreciated as this is very confusing. Thanks.

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 ) );

end original question________________________________________________________

EDIT:
Updates and more info:

Maybe should just run the whole thing twice (with errors on the second run) as that did work

EDIT2
The 2 scripts is now working, or worked when I tried it again. Not sure why it didn't work the first time.

Upvotes: 6

Views: 2285

Answers (3)

Serge Ballesta
Serge Ballesta

Reputation: 149145

As it could be a timing problem, you should ensure that you are correctly waiting the end of the diskpart command before proceeding further in parent program.

I always use WaitForSingleObject after CreateProcess when I want to simulate cmd.exe processing :

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

This sequence is closer the the good old system function ...

Upvotes: 2

janm
janm

Reputation: 18359

Because your script works the second time through it seems the most likely cause is timing related -- The volumes are not ready by the time the create volume command is executed.

Based on that assumption:

You can add a detail disk command before the create volume command to find out the state of the disk. That will tell you something about the current state of the disk. Select the first disk as well to show its details too if disk 2 doesn't show you anything interesting. The information you get from this is likely to be helpful.

As for actually resolving the problem, introducing a delay by taking the disks online and offline may help. For example:

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

Upvotes: 4

user3629249
user3629249

Reputation: 16540

Here is an excerpt of what http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx says about the first parameter:

The lpApplicationName parameter can be NULL. In that case, the module name must be the first white space–delimited token in the lpCommandLine string.

If the executable module is a 16-bit application, lpApplicationName should be NULL, and the string pointed to by lpCommandLine should specify the executable module as well as its arguments.

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 ) );

Upvotes: 2

Related Questions