Jump to content

Attempt to obtain CMD results fails


Recommended Posts

I've had no problem reading the output from CMD lines via STDOUT in the past, but I can't get the following function to work correctly. All I ever get is a blank line from the StdoutRead function.

Func _NFS_GetExportedShares( $argIn_NFS_ServerNameStr, $argIn_WaitFirst )

    Local $Lf_Stat, $Lf_PID, $Lf_CmdReplyStr, $Lf_NumExpShares = 0

    $Lf_PID = Run( @ComSpec & " /c ShowMount -e " & $argIn_NFS_ServerNameStr, "", @SW_HIDE, _
                    $STDOUT_CHILD + $STDERR_CHILD )

    If ($Lf_PID = 0) Or (@error <> 0) Then
        Return SetError( @error, 0, -1 )
    EndIf

    If $argIn_WaitFirst Then
        $Lf_Stat = ProcessWaitClose( $Lf_PID, 10 )      ; Wait no more than 10 seconds for completion
        If $Lf_Stat = 0 Then                            ; Timed out!
            Return SetError( 1, 0 , -2 )
        EndIf
    EndIf

    $Lf_CmdReplyStr = ""
    Do
        $Lf_CmdReplyStr &= StdoutRead( $Lf_PID ) & @LF
    Until @error <> 0

    If ($Lf_CmdReplyStr = "") Or (StringLen( $Lf_CmdReplyStr ) < 2) Then
        Return SetError( 1, 0 , -3 )
    EndIf

    Local $Lf_RawCmdOutAra = StringSplit( $Lf_CmdReplyStr, @LF )
    If @error <> 0 Then
        Return SetError( 1, 0 , -4 )
    EndIf

    $Lf_NumExpShares = $Lf_RawCmdOutAra[0]
    If $Lf_NumExpShares <= 1 Then                       ; If unkown server name or no shared exports
        Return SetError( 1, 0 , -5 )
    EndIf

;~  If StringLower( StringLeft( $Lf_RawCmdOutAra[1], 17 ) ) <> "exports list on " Then
;~      Return SetError( 1, 0 , -6 )
;~  EndIf


    Local $Lf_ReturnAra[$Lf_NumExpShares -1]

    For $i = 1 To $Lf_NumExpShares
        $Lf_ReturnAra[$i -1] = $Lf_RawCmdOutAra[$i]
    Next

    Return SetError ( 0, 0, $Lf_RawCmdOutAra )

EndFunc

 

I didn't post a fully executable script because it won't work unless you have an NFS server on your system. What am I doing wrong, please?

 

Link to comment
Share on other sites

Did you try with $RUN_CREATE_NEW_CONSOLE in the Run params? Like:

$Lf_PID = Run( @ComSpec & " /c ShowMount -e " & $argIn_NFS_ServerNameStr, "", @SW_HIDE, _
                    BitOR($STDOUT_CHILD, $STDERR_CHILD, $RUN_CREATE_NEW_CONSOLE) )

And then of course have you tried with/without x64 (#AutoIt3Wrapper_UseX64=n) and with #RequireAdmin?

Does the command work when you run it manually? Does _NFS_GetExportedShares return an error, or just blank?

We ought not to misbehave, but we should look as though we could.

Link to comment
Share on other sites

Thank you most kindly, @mistersquirrle

I tried all of your helpful suggestions, but, alas, I still got nothing but a blank line. And the command line works correctly whether I run it as a normal user or as an administrator. I've attached a text file with the results from the command line, but suffice to say the command line works perfectly.

This is a pretty odd problem, isn't it?

 

results.txt

Link to comment
Share on other sites

20 minutes ago, Jos said:

Isn't the output part of stderr?

I'm not sure I understand your reply, but your comment has helped me move forward with my problem, although the full solution still eludes me. Here's what helped (and could be exactly what you meant):

$Lf_PID = Run( @ComSpec & " /c ShowMount -e " & $argIn_NFS_ServerNameStr, "", @SW_HIDE, $STDERR_MERGED )

I hadn't realized that $STDERR_MERGED was different than $STDOUT_CHILD + $STDERR_CHILD, but it did produce a non-blank line!  I got...

'ShowMount' is not recognized as an internal or external command,
operable program or batch file.

So that's real progress!  Now, do you have any ideas as to how to setup the CMD() call in order to get the info I want? Perhaps when AutoIt executes the command it doesn't take into account the proper environment variable(s)?

ETA: And I did need to wait for the process to complete in order to get that output

Edited by Mbee
Link to comment
Share on other sites

The only place I found "showmount.exe" was in the directory "C:\Windows\WinSxS\amd64_microsoft-windows-nfs-admincmdtools_31bf3856ad364e35_10.0.19041.1_none_6a9f2a3a3265ab31", which is obviously not a good directory to use normally.

ETA: I just searched the entire C drive, and that's the only place it shows up aside from a prefetch file.

Edited by Mbee
Link to comment
Share on other sites

4 minutes ago, Werty said:

You wrote you had it working "in the past" using CMD, does that work for you now also?

What I meant is that I've received completely correct information from the same format of "Run()" function call in the past, but this is the first time I've tried to run the "Showmount" command.

I've got an idea of how to solve this, but I need to try it first...

Edited by Mbee
Link to comment
Share on other sites

  • Developers

Well I am looking at your code on my phone so could have missed something, but I thought you were only reading stdout with stdoutread() and don't have an stderrread() in the code?

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

2 minutes ago, Jos said:

Well I am looking at your code on my phone so could have missed something, but I thought you were only reading stdout with stdoutread() and don't have an stderrread() in the code?

That's correct, @Jos. I've never needed to make separate calls in the past, since until now specifying "$STDOUT_CHILD + $STDERR_CHILD" and then calling StdoutRead() worked fine. I now see that the only time that will work is if there is no error output. I love learning of my mistakes!

Link to comment
Share on other sites

Well, I figured that there was something about running a command via AutoIt that didn't match the environment of running it via the command line, so I tried the following (snippet):

Local $Lf_Stat, $Lf_TempPath, $Lf_PID, $Lf_RawCmdOutAra[1], $Lf_NumShares = 0

    $Lf_TempPath = _TempFile()

    $Lf_PID = Run( @ComSpec & " /c ShowMount -e " & $argIn_NFS_ServerNameStr & " > " & $Lf_TempPath, _
                        "", @SW_HIDE, $STDERR_MERGED )

    If ($Lf_PID = 0) Or (@error <> 0) Then
        Return SetError( @error, 0, -1 )
    EndIf

    ProcessWaitClose( $Lf_PID )

    $Lf_Stat = _FileReadToArray( $Lf_TempPath, $Lf_RawCmdOutAra )
    If $Lf_Stat <> 1 Then
        Return SetError( 1, 0 , -2 )
    EndIf

Unfortunately, it produced a zero-length file.

Link to comment
Share on other sites

I have another idea. What if I create a batch file that outputs to a temp file, then read that temp file to an array?  I'll let you know...

Hmmm.... I'm getting a weird response (attached file)

Local $Lf_Stat, $Lf_TempPath, $Lf_BatHdl, $Lf_PID, $Lf_RawCmdOutAra[1], $Lf_NumShares = 0

    Local $Lf_TempReplyPath = _TempFile()
    Local $Lf_TempBatPath = _TempFile( @TempDir, "_", ".bat" )
    $Lf_BatHdl = FileOpen( $Lf_TempBatPath, $FO_OVERWRITE + $FO_ANSI )
    FileWriteLine( $Lf_BatHdl, @ComSpec & " ShowMount -e " & $argIn_NFS_ServerNameStr & " > " & $Lf_TempReplyPath )
    FileClose( $Lf_BatHdl )

    $Lf_Stat = ShellExecuteWait( $Lf_TempBatPath )
    If @error <> 0 Then
        Return SetError( @error, 0, -1 )
    EndIf

    $Lf_Stat = _FileReadToArray( $Lf_TempReplyPath, $Lf_RawCmdOutAra )
    If $Lf_Stat <> 1 Then
        Return SetError( 1, 0 , -2 )
    EndIf

~dsckcek.tmp

Edited by Mbee
Added snippet
Link to comment
Share on other sites

6 hours ago, Mbee said:

The only place I found "showmount.exe" was in the directory "C:\Windows\WinSxS\amd64_microsoft-windows-nfs-admincmdtools_31bf3856ad364e35_10.0.19041.1_none_6a9f2a3a3265ab31", which is obviously not a good directory to use normally.

ETA: I just searched the entire C drive, and that's the only place it shows up aside from a prefetch file.

If the only place you can find showmount.exe is that folder, how do you expect your AutoIt script to magically find and run it? Is that folder location part of your PATH environment variable?

On my Win10 system, I have the same folder as you noted with showmount.exe in it. Trying to run it from a CMD prompt gives me a popup window with an error message stating that showmount.exe is a 16-bit application and unsupported on my 64-bit version of Windows. Then once I dismiss the popup window, the command prompt window shows this:

This version of C:\Windows\WinSxS\amd64_microsoft-windows-nfs-admincmdtools_31bf3856ad364e35_10.0.19041.1_none_6a9f2a3a3265ab31\showmount.exe is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.

So are you even sure you can run that command, and that you're not just generating error messages from trying to run it?

Link to comment
Share on other sites

18 hours ago, TimRude said:

If the only place you can find showmount.exe is that folder, how do you expect your AutoIt script to magically find and run it? Is that folder location part of your PATH environment variable?

Thanks for your reply. Earlier, I brought up the possibility that calling Run() with @ComSpec within a script might not carry over the necessary environment, including environment strings. But please consider (1): If I run the command via the CMD line, it works perfectly, and (2) that every other such call works perfectly. For example, you don't need to define an environment variable to perform a CMD such as...

Run( @ComSpec & " /c " & 'Dir /b "' & @ProgramFilesDir & '"', "", @SW_HIDE, $STDOUT_CHILD )
 

18 hours ago, TimRude said:

On my Win10 system, I have the same folder as you noted with showmount.exe in it. Trying to run it from a CMD prompt gives me a popup window with an error message stating that showmount.exe is a 16-bit application and unsupported on my 64-bit version of Windows.

My guess is that you're not running Windows 10 PRO. Only the Pro version comes with the NFS Client installed. Also, you have to ensure that the NFS Client service is running. Perhaps if your system isn't configured that way, you will get the results you see. Another possibility is that the directory in question is present on non-Pro systems so that the NFS Client could be installed?

Edited by Mbee
Link to comment
Share on other sites

Now, this is strange. There are three files in that weird directory...

nfsadmin.exe
rpcinfo.exe
showmount.exe

The earlier version of the app I'm developing did not invoke "showmount", but it did include an invocation of "nfsadmin", as follows...

$L_PID = Run( @ComSpec & " /c nfsadmin client start", @SystemDir, @SW_HIDE, $STDOUT_CHILD )

Which has always worked correctly, even without reference to that directory path. I changed the line in the function in my OP to include a reference to @SystemDir, as follows...

Local $Lf_CmdLine = '"showmount -e ' & CUBE & '"'
$Lf_PID = Run( @ComSpec & " /c " & $Lf_CmdLine, @SystemDir, @SW_HIDE, $STDERR_MERGED )

But that does NOT work. Why does the former work without specifying the WinSxS directory, but the latter won't? Note again that if I include the WinSxS path in the "showmount" command line, it works correctly. But that's such an ugly "solution" that there's got to be a better way. That better way should look just like the "nfsadmin" call.

Any suggestions as to how to get the "showmount" command to work without specifying path to the WinSxS directory?

Link to comment
Share on other sites

On 5/13/2023 at 10:24 PM, argumentum said:

you either add the path to SET Path=%PATH%;c:\newPath or, run from the specific folder or, call with full path. Not much that can be done.

Thanks for your reply, @argumentum! But I just now solved the problem. I went into Control Panel -> Programs and Features -> Turn Windows features on or off -> Services for NFS. All the options were already checked down through all levels, so I unchecked them all, rebooted, and then re-enabled them all. Afterwards, "ShowMount.exe" and the other NFS client tools were all where they should have been all along: In @SystemDir.

Don't know how that got messed up, but everything is working fine now. I'm going to add some code in my script to check for the presence of the necessary NFS Client tools in Windows\System32 first, and if they're not there, I'm going to advise the user to do the same thing. Actually, I'm going to ensure that they're either running Windows 10 Pro (don't know about 11, don't have it on any of my boxes) or otherwise have the Client for NFS (NfsClnt) installed. That last is because I've read of tricks that allow you to install the NFS Client on a non-Pro, Non-Enterprise edition of Windows 10.

Many, many thanks to all of you for your time and knowledge!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...