Link to home
Start Free TrialLog in
Avatar of Scamquist
ScamquistFlag for United States of America

asked on

Warning: exec(): Unable to fork...when calling batch file from PHP

I am trying to call a batch file from PHP.  

The batch file is just a confirmation message.  The batch file does run from from a command line.

I keep getting the error: Warning: exec(): Unable to fork
I posted this question before and got it to work.  I needed to restore the server to a previous state.  Now, I cannot get exec statements to work again.  

I gave Read and Read & Write permissons to user IUSR_COMPUTERNAME on CMD.EXE. Giving full permission did not help.  I even gave all domain users full permission to see if that would help.  It didn't



>echo %COMSPEC%
C:\WINDOWS\system32\cmd.exe

>cacls %COMSPEC%
C:\WINDOWS\system32\cmd.exe BUILTIN\Administrators:F
                            NT AUTHORITY\BATCH:R
                            NT AUTHORITY\INTERACTIVE:R
                            GAMAY\IUSR_GAMAY-SRV1:R
                            NT AUTHORITY\SERVICE:R
                            NT AUTHORITY\SYSTEM:F
                            GAMAY\TelnetClients:R


I tried to copy the CMD.EXE to my C:\PHP folder.


I tried the follwing commands

exec('ConfirmRecipe.bat');
Error:
Warning: exec(): Unable to fork [ConfirmRecipe.bat] in C:\Inetpub\wwwroot\CallFile6.php on line 2

shell_exec('ConfirmRecipe.bat');
Error:
Warning: shell_exec(): Unable to execute 'ConfirmRecipe.bat' in C:\Inetpub\wwwroot\CallFile6.php on line 2

shell_exec("C:\Inetpub\wwwroot\RecipeConfirm.bat");
Error:
Warning: shell_exec(): Unable to execute 'C:\Inetpub\wwwroot\RecipeConfirm.bat' in C:\Inetpub\wwwroot\CallFile6.php on line 2

Is there anything in the php.ini that could be causing this?  
Avatar of Rob
Rob
Flag of Australia image

what about using the COM


$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("ConfirmRecipe.bat", 7, false);

Open in new window

Avatar of Scamquist

ASKER

I entered:
<?php
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("ConfirmRecipe.bat", 7, false);
?>

threw the error:

Fatal error: Uncaught exception 'com_exception' with message 'Source: Unknown Description: Unknown' in C:\Inetpub\wwwroot\CallFile.php:3 Stack trace: #0 C:\Inetpub\wwwroot\CallFile.php(3): com->Run('ConfirmRecipe.b...', 7, false) #1 {main} thrown in C:\Inetpub\wwwroot\CallFile.php on line 3
ASKER CERTIFIED SOLUTION
Avatar of Rob
Rob
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I replaced cmd /c dir with the full path to the batch file.  

When I opened the page, the batch file did not run, but the page retruned -1


fyi, the contents of the batch file are:
Msg * "Recipe has been copied to MAS"
<?php
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Exec("cmd /c C:\Inetpub\wwwroot\RecipeConfirm.bat");

echo ReadAllFromAny($oExec);


Function ReadAllFromAny($oExec) {

     If (!$oExec->StdOut->AtEndOfStream) {
          return $oExec->StdOut->ReadAll;
 	}

     If (!$oExec->StdErr->AtEndOfStream) {
          return "STDERR: " . $oExec->StdErr->ReadAll;
 	}

     return -1;
}

?>

Open in new window

What does the batch file do?  There may be another way of achieving it...
the RecipeConfirm.bat was a test.  I thought if this batch file would work, all would work.

Ultimately, I need to
stop sql server 2005
start sql server 2005
run a stored procedure
dhange drive and invoke a program
run a stored procedure

Below is a sample of the full code I need to run

net stop "MSSQLSERVER"
net start "MSSQLSERVER"

osql -E -d Iris -S Gamay-srv1 -Q "Exec spRecipeUpload"
cd\
d:
cd\Iris\htdocs
start GAMimportrecipelnk
osql -E -d Iris -S Gamay-srv1 -Q "Exec RunRefresh"



to run the stored procedure, I tried

system('osql -E -d Iris -S Gamay-srv1 -Q "Exec RunRefresh"');

this produced the error:
Warning: system(): Unable to fork [osql -E -d Iris -S Gamay-srv1 -Q "Exec RunRefresh"] in C:\Inetpub\wwwroot\MyTest.php on line 2
PHP has built in support for SQL Server
http://au.php.net/manual/en/function.mssql-execute.php

I haven't tested this but it's worth a shot seeing as it's not that much code.  You could wrap it in a function for simplicity
<?php
$server = 'Gamay-srv1\Iris';

// Connect to MSSQL
$link = mssql_connect($server);

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Exec('cmd /c net stop "MSSQLSERVER"');
$oExec = $WshShell->Exec('cmd /c net start "MSSQLSERVER"');

$stmt = mssql_init('spRecipeUpload');
mssql_execute($stmt);
mssql_free_statement($stmt);

$oExec = $WshShell->Exec('cmd /c d:\Iris\htdocs\GAMimportrecipelnk');

$stmt = mssql_init('RunRefresh');
mssql_execute($stmt);
mssql_free_statement($stmt);

?>

Open in new window

My server crashed tonight, so I cannot test it right now.  

Should I be able to swap mssql with sqlsrv in the statements?

I will let you know how it works as soon as I get my server back up.

Thank you for you help.
That's no good about the server... good luck :)

Not sure what you mean by swapping mssql with sqlsrv?

I am using PHP 5.3.6.  To connect to SQL, I use sql_connect(.....

___________________________________________________________________________

from
http://social.msdn.microsoft.com/Forums/en-US/sqldriverforphp/thread/b64321c9-658e-49f2-9fdd-168ff5031863/
___________________________________________________________________________

The SQL Server driver for PHP developed and supported by Microsoft is “sqlsrv” and not “mssql”. The two drivers are similar, but not compatible. IA quick glance through the APIs list should reveal the differences. For instance, mssql has a “bind” function, while “sqlsrv” has not (as it implements implicit binding with prepared statements). In summary, there is no (backward) compatibility between the two drivers.

Additionally, “mssql” was dropped from PHP 5.3 distribution. Since the “php_mssql.dll” is no longer deployed with PHP 5.3, all calls to “mssql_” API are expected to fail.
ok sure :)  i don't use sql server so pardon the ignorance.

is your server back up?
Not yet.  I think I need a bigger hammer.  :)

I need to take it to another level and have some esle look at it.  Hope to have it back up today...unless the drive controller is bad.

Once I am back up, I will try your suggestion and hope for success.

Thank you for you patience.

Steve
I expect to have a replacement server by the end of the week.  I hope we can solve this issue at that time.  

Thank you.
I'll wait to hear from you :)
Still here.  Need to change the syntax for sqlsrv_connnect.   Lemme fix and see if it works.
I made the following changes.  php.5.3.8 uses sqlsrv instead of mssql

the mssql_init appears to have been replaced with

$stmt =  "{call StoredProcedureName(RunRefresh)}";
   
(for a list of sqlsrv commands, see
http://blogs.msdn.com/b/brian_swan/archive/2010/03/10/mssql-vs-sqlsrv-what-s-the-difference-part-2.aspx  )

I connect to the database, but now I get the following errors:

Connection established.
Warning: sqlsrv_execute() expects parameter 1 to be resource, string given in C:\Inetpub\wwwroot\MyTest.php on line 21
Warning: sqlsrv_free_stmt() expects parameter 1 to be resource, string given in C:\Inetpub\wwwroot\MyTest.php on line 22
Warning: sqlsrv_execute() expects parameter 1 to be resource, string given in C:\Inetpub\wwwroot\MyTest.php on line 27
Warning: sqlsrv_free_stmt() expects parameter 1 to be resource, string given in C:\Inetpub\wwwroot\MyTest.php on line 28


<?php
$serverName = "(local)";
$connectionInfo = array("UID" => "UserName", "PWD" => "Password", "Database"=>"DatabaseName");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn )
{
     echo "Connection established.<br>";
}
else
{
     echo "Connection could not be established.<br>";
     die( print_r( sqlsrv_errors(), true));
}

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Exec('cmd /c net stop "MSSQLSERVER"');
$oExec = $WshShell->Exec('cmd /c net start "MSSQLSERVER"');

$stmt =  "{call StoredProcedureName(spRecipeUpload)}";

sqlsrv_execute($stmt);
sqlsrv_free_stmt($stmt);

$oExec = $WshShell->Exec('cmd /c d:\Iris\htdocs\GAMimportrecipelnk');

$stmt =  "{call StoredProcedureName(RunRefresh)}";
sqlsrv_execute($stmt);
sqlsrv_free_stmt($stmt);

?>

Open in new window

You need to "prepare" the statement, that's all your missing

add this at line 20:

$prep_stmt = sqlsrv_prepare($conn, $stmt);

Open in new window

change line 21:
sqlsrv_execute($prep_stmt);

Open in new window

Do I need to change the other lines with $stmt to $prep_stmt  ?

Do I need to add

$prep_stmt = sqlsrv_prepare($conn, $stmt);

after line 26?
tagit - you are the BEST.  I spent too may days searching for a solution.  

The code below works.

Thank you so much
<?php
$serverName = "(local)";
$connectionInfo = array("UID" => "UserName", "PWD" => "Password", "Database"=>"Database");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn )
{
     echo "Connection established.<br>";
}
else
{
     echo "Connection could not be established.<br>";
     die( print_r( sqlsrv_errors(), true));
}

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Exec('cmd /c net stop "MSSQLSERVER"');
$oExec = $WshShell->Exec('cmd /c net start "MSSQLSERVER"');

$stmt =  "{call StoredProcedureName(spRecipeUpload)}";
$prep_stmt = sqlsrv_prepare($conn, $stmt); 
sqlsrv_execute($prep_stmt); 
sqlsrv_free_stmt($prep_stmt);

$oExec = $WshShell->Exec('cmd /c d:\Iris\htdocs\GAMimportrecipelnk');

$stmt =  "{call StoredProcedureName(RunRefresh)}";
$prep_stmt = sqlsrv_prepare($conn, $stmt); 
sqlsrv_execute($prep_stmt);
sqlsrv_free_stmt($prep_stmt);
?>

Open in new window

Too quick.    I thought it ran the stored procedures, but they did not run.  

The only difference is the code did not produce an error.
I suggest looking at the example on this site: http://php.net/manual/en/function.sqlsrv-prepare.php

Do you need the curly brackets? {}  try removing them

$stmt =  "call StoredProcedureName(spRecipeUpload)";
$prep_stmt = sqlsrv_prepare($conn, $stmt); 
sqlsrv_execute($prep_stmt); 
sqlsrv_free_stmt($prep_stmt);

Open in new window

also where does spRecipeUpload come from?
spRecipeUpload is a stored procedure in SQL 2005
Removing the curly brackets { } had no effect
ok not too sure of your setup but can't you call the stored procedure directly like this?

$stmt =  "exec spRecipeUpload";
$prep_stmt = sqlsrv_prepare($conn, $stmt); 
sqlsrv_execute($prep_stmt); 
sqlsrv_free_stmt($prep_stmt);

Open in new window

This change did not run the stored procedure.

It is strange.  The first 13 lines of my codes establish and confirms the connection to the SQL server.

However, nothing happens after that.  None of the stored procedures run, nor does the GAMimportrecipelnk command.

are you able to run the stored procedure (and confirm it ran) from the command line?

osql -E -d Iris -S Gamay-srv1 -Q "Exec spRecipeUpload"

Open in new window

Yes, when run from a command line, the stored procedure runs properly.
ok then I would try the query version of sqlsrv rather than the execute (as it is just the one query)

eg.

$sql = "Exec spRecipeUpload";
$stmt = sqlsrv_query( $conn, $sql);
if( $stmt === false ) {
     die( print_r( sqlsrv_errors(), true));
}

Open in new window

new error message.  Have not seen this before.

 
Connection established.
Array ( [0] => Array ( [0] => 42000 [SQLSTATE] => 42000 [1] => 229
 [code] => 229 [2] => [Microsoft][SQL Server Native Client 10.0]
[SQL Server]EXECUTE permission denied on object 'spRecipeUpload',
 database 'Iris', schema 'dbo'. [message] => [Microsoft][SQL Server
 Native Client 10.0][SQL Server]EXECUTE permission denied on 
object 'spRecipeUpload', database 'Iris', schema 'dbo'. ) )

Open in new window

Thanks for the link.  I ran the

GRANT EXECUTE ON [storedProcName] TO [userName]

and threw another error.  

I will search this new error and post back.


For others that may view this thread in the future, here is the latest error.


I will post back if I find a solution


Array ( [0] => Array ( [0] => 42000 [SQLSTATE] => 42000 [1] => 4629 [code] => 4629 [2] => [Microsoft][SQL Server Native Client 10.0][SQL Server]Permissions on server scoped catalog views or
 system stored procedures or extended stored procedures can be
 granted only when the current database is master. [message] =>
 [Microsoft][SQL Server Native Client 10.0][SQL Server]Permissions
 on server scoped catalog views or system stored procedures or
 extended stored procedures can be granted only when the current
 database is master. ) )

Open in new window

I've requested this to be looked at by other experts in MSSQL so hopefully you'll get someone that knows about that error
I appreciate the amount it time you put into this.  It feels like we are getting close.  I guess if this was easy, they wouldn't call it work.

Thanks for the notice to the other experts.
I've requested that this question be closed as follows:

Accepted answer: 0 points for Scamquist's comment http:/Q_27327634.html#36709127

for the following reason:

Your use of function got me in the right direction. &nbsp;I posted what finally worked at the bottom of this thread. &nbsp;While it wasn't all the way, it got me there. &nbsp;I really appreciate your help. &nbsp;Above and beyond what I would expect.
I need to cancel this.  I did not mean to accept my solution.  Can you help.

I meant to select tagit's answer 09/27/11 02:37 AM, ID: 36707924

Steve lIndquist
Your use of function got me in the right direction.  I posted what finally worked at the bottom of this thread.  While it wasn't all the way, it got me there.  I really appreciate your help.  Above and beyond what I would expect.
Thanks and glad you got there in the end. I can't see where you've posted the solution though...