John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

Suppose I'm about to open a file on \\machine\share\path\file.ext. It will fail unless this session is "logged into" that machine, and if it doesn't have an account name and password that matches the one I'm running under here. Calling system "NET USE ..." is one way, but I've been advised that newer versions have a nasty "enhancement" to the NET USE command-line utility, and pop open an explorer window immediatly to the referenced location, which also steals focus away from the current program.

Also, calling a separate program doesn't give good access to error values.

It looks like Win32::NetResource::AddConnection is what I'm looking for, but I can't make heads or tails of the documentation as found in Dave Roth's book.

Has anyone done this? What's a good way to do it?

—John

Replies are listed 'Best First'.
Re: Using Win32 network shares
by Kanji (Parson) on Apr 05, 2002 at 01:22 UTC

    I could never get Win32::NetResource to work for me, but Jenda's Win32::FileOp works like a charm and is embarrsingly easy if you don't mind mapping a drive in the process...

    #!perl use Win32::FileOp qw/ Map /; Map 'X:' => ' \\\\machine\\share', { user => 'foo', passwd => 'bar' }; open FILE, 'x:/path/file.ext' or die "...";

        --k.


      Yea, that's certainly a much more usable function. The parameters and form make sense on a cold reading, and a short description fully describes the options.

      I'll have to look into the other things in his suite.

      But, I specifically don't want to map a drive letter. That would peturb the user's system, it would have to find the letter that wasn't being used already (his function can use "next available" but doesn't return what it chose), etc.

        "(his function can use "next available" but doesn't return what it chose), etc."

        Yes it does. From his doc

        $drive = Map $share;

        Don't forget that NetResource can do a deviceless connection. You would need to use the UNC to get to the share. That was explained on p62. where it pointed out

        my %NetResource = ( LocalName => "R:", RemoteName => "\\\\Public\\Depot" );

        Remember it said if LocalName was left blank.....

Re: Using Win32 network shares
by Marza (Vicar) on Apr 05, 2002 at 01:25 UTC

    What do you not understand? The two things from his book worked for me. However, I did remove the $ from the RemoteName assignment.

    use Win32::NetResource; use Win32::WinError; use strict; use warnings; my %NetResource = ( LocalName => "R:", RemoteName => "\\\\Public\\Depot" ); print $NetResource{RemoteName}; my $User = ""; my $Password = ""; if ( Win32::NetResource::AddConnection( \%NetResource, $Password, $Use +r, 1) ) { print "Successful!\n"; } else { print NetError(); } sub NetError { my ( $Error, $Text, $Provider, $Result); $Error = Win32::GetLastError(); if( ERROR_EXTENDED_ERROR == $Error ) { Win32::NeResource::WNetGetLastError( $Error, $Text, $Provider +); $Result = "Error $Error: $Text (generated by $Provider)"; } else { $Text = Win32::FormatMessage( $Error ); $Result = "Error $Error: $Text"; } return $Result; }

    Keep in mind if the user and password are blank that says to keep it local to the machine you are accessing. If you are accessing a wide open share then you will have no problems. Otherwise, it wants an id and password which is bad since the password is plaintext. But if you are the sole user of the script and people won't see it....

    And don't forget that if you use this to disconnect and or allow for finding the share already mounted.

      Thanks, that example showed me how to use that module properly. It works fine without the LocalName attribute filled in, and logs on without mapping.
      What do you not understand?

      Well, the book doesn't explain what the first parameter is. I got the module anyway, and its own documentation is better. But there are no examples. What's a CONNECTIBLE vs CONTAINER? etc.

      Your example helps, e.g. only some of the possible fields in %NetResource are used. But I still don't know what the last parameter, $Connection or $Result for you, does. Your example uses TRUE/FALSE return and GetLastError for checking after the call, not this output parameter.

      Keep in mind if the user and password are blank that says to keep it local to the machine you are accessing. I don't understand.

      if you use this to disconnect and or allow for finding the share already mounted. I didn't parse that, either.

      it wants an id and password which is bad since the password is plaintext. But if you are the sole user of the script and people won't see it....

      Yes, I know the risks of having the password present in the script. In my application, it is uniquely not a problem! This is for my backup script. If you can access the files on this machine to read the script, you would not need to break into the backup machine.

        Always review the module docs! Most of the time they are pretty clear. Even Daves books has mistakes. One that drove me nuts was the option SV_TYPE_WORKSTATION for get servers. You read Daves book and it says all NT Workstations and yet you get everything. Well what that really does is get you anything that is running the Workstation service! BTW: Dave himself explained that one. Get on the Activestate win32 perl for admins list. He watches that and usually responds to stuff.

        As to your questions:

        A connectible is anything that you are allowed to connect to and use(ie a share or a printer).

        A container is simply an object that contains other objects(ie a domain is a container object that can contain users, computers and other objects).

        This stuff is more Windows 2000 than Perl related so I can describe it offline if you need more help.

        $connection is either 1 or 0. This is to tell Windows if the share is going to be a persistent connection(ie reboot and it is still there) so in your case as I saw above you don't want to perminanty mount so 0 would be good. However, dismounting is would be best. Use the

          CancelConnection($Name, $Connection, $Force)

        to get rid of the connection when you are done.

        $Result as used in the error message is simply used to build an error message which gets returned to the funcation caller

        "Keep in mind if the user and password are blank that says to keep it local to the machine you are accessing. I don't understand."

        Well I could have said that better. If you leave these blank. It will use the ID and password of the account that is logged on the computer that is running the script. Security would need to allow the access. Since this is a backup script; everything should already be set up.