I am trying to execute a script file (Batch or Python) in PHP (local WAMP server) that will open a program on my computer and send a keyboard shortcut to put the the program in fullscreen mode. I have this script already made using AutoHotKey (.ahk scripts).
I tried using these PHP commands to open a Batch file that runs the .ahk script:
system("cmd /c C:\wamp64\www\test.bat");
exec("test.bat");
exec("cmd.exe /c test.bat");
But all of these seem to just run the script on the webserver and not on my Windows computer so the .ahk file is never executed. I also tried directly executing .ahk file but I couldn't get that working either.
Does anyone know of a way I can use PHP(or another web language) to execute this script on my computer?
You have to specify absolute path for the batch file, as the CLI SAPI has nothing to do with WAMP's document root.
You have tried to pass full path in the first command. But the sequence \t within double quotes is parsed as a tabulation character. Change double quotes to single quotes:
system('cmd /c C:\wamp64\www\test.bat');
Also, I don't think you need to run cmd explicitly, since batch files are executable on Windows.
Related
I am currently facing the issue that I want to implement a PHP script that starts a batch file on a remote server.
After hours of ideas the nearest I came to the solution was a batch file on a local server which could be started by the PHP script. However, the batch file somehow does not start the remote batch file when started via PHP script.
If the batch file c:\directoryapps\sub\classes\actions\test.bat is started locally with a double click, the remote batch file c:\directory\sub\test.bat is executed without a problem by PsExec.
The permissions are granted as needed.
I am using the following code in PHP to start the first batch file:
$cmd = '"c:\\directoryapps\\sub\\classes\\actions\\test.bat"';
exec('cmd /c '.$cmd.' &');
The code of that batch file is as followed:
"C:/Windows/System32/SysinternalsSuite/PsExec.exe" \\server -i -u **** -p **** c:\\directory\\sub\\test.bat
How do I implement a working version of this?
I have also tried to run the first batch file code from within PHP script with even less success.
The main problem is the decision to install the Sysinternals Suite into a subdirectory of %SystemRoot%\System32. That was no good decision and cause the issue here.
The directory %SystemRoot%\System32 is for 64-bit applications executed in 64-bit environment on 64-bit Windows.
The usage of %SystemRoot%\System32, which is usually expanded to C:\Windows\System32, in 32-bit environment results in a redirection by Windows File System Redirector to %SystemRoot%\SysWOW64 respectively expanded C:\Windows\SysWOW64.
%SystemRoot%\SysWOW64 contains the 32-bit system executables, but not the directory SysinternalsSuite with file PsExec.exe.
python.exe is a 32-bit executable. For that reason is started with just cmd in the Python script %SystemRoot%\SysWOW64\cmd.exe which is the 32-bit version of Windows command processor. 32-bit cmd fails to find C:\Windows\SysWOW64\SysinternalsSuite\PsExec.exe and so psexec.exe is not executed at all.
Well, starting cmd.exe to run a batch file which contains only one command line to run psexec.exe with wrong path for 32-bit environment is not needed at all.
It would be enough to use in Python script:
$args = '\\\\server -i -u "****" -p "****" "C:\\directory\\sub\\test.bat"';
exec('C:\\Windows\\Sysnative\\SysinternalsSuite\\PsExec.exe '.$args.);
32-bit python.exe runs with this code the 32-bit executable PsExec.exe in subdirectory SysinternalsSuite of 64-bit Windows system directory with the appropriate arguments.
The special redirecting Sysnative exists only for 32-bit applications executed in 32-bit environment. Please note that Sysnative is neither a directory nor a symbolic link or hard link. The file system does not contain an entry Sysnative in directory C:\Windows. For that reason it is not possible to use in a batch file if exist %SystemRoot%\Sysnative or if exist %SystemRoot%\Sysnative\ as both conditions evaluate always to false. But if exist %SystemRoot%\Sysnative\cmd.exe can be used in a batch file to find out if the batch file is processed by 32-bit Windows command processor on a 64-bit Windows because of the condition evaluates to true in this use case.
I recommend reading also the Microsoft documentation pages WOW64 Implementation Details and Registry Keys Affected by WOW64 to get knowledge on how 32-bit Windows emulation works on 64-bit Windows.
A minor issue is appending & at end of the Windows command line. An ampersand at end of a shell script line is interpreted only by Unix/Linux/Mac shell script interpreters as instruction to run the executable detached in background. So the shell script interpreter does not wait for termination of the started executable before continuation of the script or before the user can enter the next command to execute.
Windows command processor cmd.exe interprets an ampersand outside a double quoted argument string as AND operator usually used to specify multiple commands on one command line, see single line with multiple commands using Windows batch file. If there is after & nothing on a command line interpreted by cmd.exe, the Windows command processor ignores the AND operator.
Therefore do not append & on a Windows command line.
There are two more minor issues in the batch file on command line:
"C:/Windows/System32/SysinternalsSuite/PsExec.exe" \\server -i -u **** -p **** c:\\directory\\sub\\test.bat
The directory separator on Windows is \ and not / as explained by Microsoft on documentation page Naming Files, Paths, and Namespaces. The Windows kernel replaces by default all / by \ in a file/folder string before passing the string to the appropriate file system function. But the usage of Linux/Mac directory separator / can nevertheless result in unexpected behavior.
Example:
Run in a Windows command prompt window:
for %I in (C:/Windows/*.exe) do #echo %I
The found executables in Windows directory are output with C: and the file name without path. So assigned to loop variable I is a string which references an executable file in current directory of drive C:. But the current directory on drive C: on execution of this command line is most likely not C:\Windows which would cause issues on really processing the file name assigned to loop variable I instead of just printing it to console window.
Run in same command prompt window now:
for %I in (C:\Windows\*.exe) do #echo %I
The same file names are output as before, but this time with full path.
Conclusion: Do not use / in file/folder strings on Windows and depend on automatic correction of Windows kernel. / is used on Windows mainly for beginning of an option.
The usage of \\ in a batch file between two directory names and between a directory name and a file name is also always wrong and must be corrected by Windows kernel before passing the file/folder name string to the file system by removing one backslash. \\ is valid only at beginning of a UNC path.
So I am using PHP exec() to run a batch file on my server:
echo exec("printCountries.bat");
The batch file opens Microsoft Access 2007 and runs a macro to print a form and then close Access:
START /MIN /B msaccess.exe "C:\inetpub\wwwroot\system\reports.accdb" /X printCountries
I can run the batch file from the command line successfully and the form prints to our network printer (this is for a company intranet) and closes Access. But when I run the PHP script, the batch file only runs the Access Process but does not perform the command line switches or open the database file.
I have configured PHP to have the right privileges on IIS, I am just stumped as to why the command line switches don't work and the batch file won't open the database.
Any ideas?
here is the echo output:
C:\inetpub\wwwroot\scale>START /MIN /B msaccess.exe "C:\inetpub\wwwroot\system\reports.accdb" /X printCountries
It looks like you have some access rights problem.
Did you try to run in PHP this echo exec("whoami");
What username you get?
Something like "nt authority\iusr" ?
You have to give to the default IIS user (i.e. IIS_IUSRS) full access to the path that your scripts lives.
In addition you can change (only TEMPORARILY huh?) the default application pool user from ApplicationPoolIdentity to LocalService or LocalSystem to test the results...
If I were you, I would created a new Application in IIS then I would created a new Application Pool and I would assigned it to this app. Then I created a new user that will have access to all the appropriate directories (web dir and where the bat is located).
If nothing of the above worked I would test my php application from my command line (locally) using the php command in my local command prompt.
I am neither good with PHP, nor with Access. However, when you invoke the batch file from PHP, please create an instance of cmd.exe and pass "/c printCountries.bat" to cmd.exe. In other words, the command run by PHP exec should look something like this (assuming PATH is set correctly):
cmd.exe /c printCountries.bat
Also, inside printContries.bat, I think you will need to wait until the access process terminates. So it should look like
START /WAIT /MIN /B msaccess.exe "C:\inetpub\wwwroot\system\reports.accdb" /X printCountries
I am trying to use PHP to compile and upload an Arduino sketch through the command line. Right now a user uploads an ino or pde file through a form and it is transferred to a directory for later use. Using the uploaded file's location as a variable, I would like PHP to run the command line version of Ardunio to compile and upload it.
After an inital try with using exec() and system(), I switched to popen(). Running the following code I can get Arduino to open then it closes without uploading the sketch:
pclose(popen('"C:\Program Files\Arduino\arduino.exe" --port COM3 --upload "C:\sketches\uploads\cube\a\a.ino"));
Running that code and its variations through the Windows Command Line works so I know the input string is not the issue. Also, looking at the Windows Task Manager shows it opening for a second or so then closing. Could someone point me in the right direction?
For popen (or any of the other process functions) to work correctly on Windows you need to escape backslashes like this:
pclose(popen('"C:\\Program Files\\Arduino\\arduino.exe" --port COM3 --upload "C:\\sketches\\uploads\\cube\\a\\a.ino"'));
alternatively try replacing the backslashes with forward slashes. The following should also work on recent versions of Windows:
pclose(popen('"C:/Program Files/Arduino/arduino.exe" --port COM3 --upload "C:/sketches/uploads/cube/a/a.ino"'));
(Your code snippet was also missing a trailing single quote, but I suspect that's a typo.)
I have a php webpage located on Webserver1, which is from Host1.
I also have a bash script located in Gameserver1 which is from Host2.
Is there any way to send a command from Webserver1 to Gameserver1 to execute the bash file? The webpage and file are on different VPSs. Both are running Debian 7.
The script is literally one line, to execute a java command via a screen, so the server can start if a player notices it's down. The command's available already so it doesn't need to be a secure way of hiding what the command is.
There are 2 ways I can think of. either create a bash file in Webserver1 that connects through ssh and executes the bash script you need on Gameserver1. then run it through php with exec() command.
Or you can create a php file in Gameserver1 that uses exec() to execute the bash script you need on Gameserver1 and call it using file_get_contents() on Webserver1, which is not that secure since anyone can call that file and run your script.
I'm using shell_exec() to print a PDF that is stored on a LAN automatically to a printer on the LAN through Adobe Reader using the following PHP code (all on one line):
shell_exec("'C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe'
/t \\hnurensp01\RepairTickets\179694.pdf \\hnurenfp01\Accounts_FS-1128MFP");
What I expect this to do is open adobe reader, open the PDF on the network and print to the network printer. When running the PHP script with this line, it doesn't open adobe reader or print it. However, when I copy that code and execute in a command prompt (client-side), it works and prints. There is only slight modifications to the command line (all on one line):
"C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe"
/t \\hnurensp01\RepairTickets\179694.pdf \\hnurenfp01\Accounts_FS-1128MFP
Is it to do with the PHP script executing on the server-side? I've tried running the same command line on the server and it works too. It just seems to be when it's going through PHP, it does nothing.
My end result must be printing out a server-side PDF with as little interaction from the end-user as possible. Note: this is a WAMP environment.
Any ideas?
Thanks.
UPDATE:
Tried put the code into a batch file and calling it that way, still didn't work. Tried using exec() and shell_exec() but still no joy. For some reason when I run the batch file by double-clicking it, it works fine. It's when I call it using PHP, it doesn't do anything except open two instances of acrord32.exe that doesn't close and therefore the PHP script seems to never complete. I'm soo confused...
Try this:
echo "'C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe' /t \\hnurensp01\RepairTickets\179694.pdf \\hnurenfp01\Accounts_FS-1128MFP"
It returns:
'C:\Program Files\Adobe\Reader 10.0\Reader\AcroRd32.exe' /t \hnurensp01\RepairTickets9694.pdf \hnurenfp01\Accounts_FS-1128MFP
In PHP, the backslash serves as a 'special' character, since it's used to produce tabs and newlines \t and \n. The proper way to escape a backslash, is by prepending another one: \\ produces \ as output.
This is why your PHP script doesn't work. The double backslashes will be printed to the shell as if you only typed one! You will need to escape every backslash in that line of code:
shell_exec("'C:\\Program Files\\Adobe\\Reader 10.0\\Reader\\AcroRd32.exe'
/t \\\\hnurensp01\\RepairTickets\\179694.pdf \\\\hnurenfp01\\Accounts_FS-1128MFP");