This week I had a report of an application locking up while executing the shell function. Actually it was executing shell(“ipconfig /all”) in my modification of Ken Ray’s GetMACAddress function to return the machine’s LAN ip.

System administrators tend to like to turn things off so normal human beings can’t make a mess of their nice machines. One thing they can do is set a Windows registry entry to disable cmd.exe for the user. So by checking HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System\DisableCMD”=dword:1 we can find out if cmd.exe is disabled for the current user. What this does is when cmd.exe is run it opens the console but all you get is a blocked by admin message and no command prompt. If Bill would just change this so it stopped cmd.exe from launching at all then we wouldn’t have such a problem. LiveCode is therefore able to run cmd.exe and just sits there waiting for it to terminate but it never does.

So I wrote a safer shell function to check for this situation and also possible execution errors from hash rules and renaming of cmd.exe etc. If the registry setting is there it will attempt to execute the command directly using process commands rather than via shell.

function safeShell pCommand
   -- assume the shellCommand has been set appropriately
   set the hideConsoleWindows to true
   set the itemDel to "\"
   if item -1 of the shellCommand is "cmd.exe" AND \ 
          charToNum(queryRegistry("HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System\DisableCMD")) = 1 then
      -- don't use cmd.exe because shell() won't return
      -- don't revert to command.com because there seems to be a problem in the engine
      return executeProcess(pCommand)
   else
      try
         -- still check for empty if your are expecting a result
         -- because there's no execution error on os x
         return shell(pCommand)
      catch e
         -- execution error on windows shellCommand doesn't exist
         -- hopefully this catches hash rule blocks
         return "Error executing command"
      end try
   end if
end safeShell

function executeProcess pProcess,pElevate
   local tReturn
   if pElevate then
      open elevated process pProcess for text read
   else
      open process pProcess for text read
   end if
   repeat forever
      # Loop until there are no more lines to read.
      read from process pProcess for 1 line
      if the result = "" or the result = "timed out" then
         -- something to add
         put it after tReturn
      else
         close process pProcess
         return tReturn
      end if
   end repeat
end executeProcess
 

Comments are closed.