After writing a file from AX, need to kick of a .cmd file to FTP it. Runs fine on client, but can't get it to work on server. For now I have server static method in a sandbox class, but eventually it will be submitted via RunBaseBatch. I've got code using System.IO.File::Exists, and that all appears to be working fine. For now I'm testing with a .cmd file that just renames a file based on command line parameters.
if (allGood)
{
try
{
// Run a .cmd file
perms = new Set(Types::Class);
perms.add(new InteropPermission(InteropKind::ClrInterop));
perms.add(new FileIOPermission(cmdExe, #io_read)); // C:\Windows\system32\cmd.exe
perms.add(new FileIOPermission(wrkPath + '\\' + testCmd, #io_read)); // mytest.cmd
perms.add(new FileIOPermission(wrkPath + '\\' + renFil1, #io_readwrite)); // tst.1
perms.add(new FileIOPermission(wrkPath + '\\' + renFil2, #io_readwrite)); // tst.2
process = new System.Diagnostics.Process();
processStartInfo = new System.Diagnostics.ProcessStartInfo();
processStartInfo.set_FileName(cmdExe);
processStartInfo.set_WorkingDirectory(wrkPath);
startArgs = '/C '
+ '\"' + wrkPath + '\\' + testCmd + '\" '
+ '\"' + wrkPath + '\" ' + renFil1 + ' ' + renFil2;
processStartInfo.set_Arguments(startArgs);
process.set_StartInfo(processStartInfo);
procStarted = process.Start();
process.WaitForExit(500);
}
catch (Exception::CLRError)
{
info(strfmt("CLR error occurred while executing the command file %1 in directory %2", testCmd, wrkPath));
sysExc = ClrInterop::getLastException();
while (sysExc)
{
info(sysExc.get_Message());
sysExc = sysExc.get_InnerException();
}
allGood = false;
}
}
CodeAccessPermission::revertAssert();
wrkPath is a UNC path with embedded spaces, so the start args need quotation marks.
When I run this, it returns immediately, and WaitForExit just continues, but the script hasn't been executed. The file isn't renamed. When I open a command window and type what I think is the same command line, cmd /C "\\server\path\mytest.cmd" "\\server\path" tst.1 tst.2, it does what I expect. It also works if I change the method to client.
Do I need some special permissions, or is it just not possible to run .cmd files on server? I've also tried using the .cmd file directly in set_FileName, and as .bat instead of .cmd. When I did those, the .start() just hangs (and I have to do a hard close of the rich client).
*This post is locked for comments
We eventually found that the account involved was not what we thought. Run the process, then check the Event Viewer on the server. That will help pinpoint which files/accounts are involved.
Hi,
I am experiencing the same issue, my code is working fine if i runs it from client but not working if i runs from server (batch process). Even i have given permission to the service account to all the folders and scripts (bat command). can you tell me am i missing something?
thanks in advance.
The process was running as ax_admin. I wasn't around when this was setup, so it's possible they changed the host machine's account that you referenced. ax_admin does have authority to the paths and files involved.
Anyway, no need for further replies. I now have read access to the key file (it was SFTP, not plain FTP).
Most of the .cmd was setting up environment variables for paths and for parameters to the FTP. There was a check for existence of the file to be sent, which I can do directly. And the set_FileName is now psftp.exe (PuTTY's SFTP). Which I think takes us back to gl00mie's original question of why not run it directly? Still somewhat frustrated that a .cmd wouldn't run, but there you have it.
If the code listed above successfully runs on client but doesn't work on server then check if the account under which you run the AOS has an access to the \\server\path\. If you run the AOS under the Network Service account then it is the host machine's account (aos_host_name$) that must be checked. In my case a sample code like yours runs fine both on server and on client.
BTW, you don't have to request FileIOPermissions in the code above.
I didn't include the declarations, but comment shows the value:
perms.add(new FileIOPermission(cmdExe, #io_read)); // C:\Windows\system32\cmd.exe
and cmdExe is used later...
processStartInfo.set_FileName(cmdExe);
So I am using the full path to the exe. Also used full path when I tried to run the cmd directly (other tests I referred to near the end of the original post): set_FileName(wrkPath + '\\' + testCmd).
As far as why I am using shell script, wasn't my call really. I didn't write the script, and there are security issues involved (FTP passwords, ...). I've found other examples that appear to be running a .cmd or a .bat, so it seems like it should be possible.
First, you should specify the full file name for the executable image (c:\windows\system32\cmd.exe), and second, why do you try to run a shell script if you can do it's job via. NET?
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 291,134 Super User 2024 Season 2
Martin Dráb 229,928 Most Valuable Professional
nmaenpaa 101,156