"Diez B. Roggisch" <de***@nospam.web.dewrote:
>A search suggested that the form open(r"\\server\folder\folder"), but
I tried many combinations guessing what it wants for that path in my
case (r"\\WORKGROUP\VISTA", "\\VISTA\PUBLIC", etc), and none have
worked so far.
The combination you want is \\server\sharename\folder\filename, so if
the Vista machine is called VISTA and has a folder shared as PUBLIC then
"\\VISTA\PUBLIC" might work. But several things can go wrong with this.
>
You need to create network shares in windows first. Once these are
established, *all* programs using file-IO - including python - can
access files.
It isn't absolutely essential to create a network share first: most
windows apis, including those used by Python, will be very happy with a
UNC path:
>>open(r'\\10.10.25.121\rootc\default.tag', 'r').read()
'\tTAGS\tUNSORTED\n'
The first problem you need to address is whether or not the two systems
know each other's names. This can be problematic: that's why I used an
IP address in the example I gave. If you don't have a domain controller
on the network then the machines which are on the network use a complex
system of voting to decide which will be the 'browse master', but they
don't always agree on the outcome :^)
The second problem is that if you don't establish a connection first,
you cannot specify a username and password when opening the file. That
means you get whatever the default is. Again not usually a problem if
your machines are in a domain, but in a workgroup it can be messy.
So while it is not essential, it is probably easier to establish a
connection. Of course that can be done fairly easily from within
Pythonusing win32api.NetUseAdd, ctypes, or even os.system("NET USE
\\server\share /user:yourname pa5sW0rc!")
Note that you don't need to assign a drive letter when creating the
connection, just get the authentication over with and then you can use a
UNC name for the the actual file access.
----- netuse.py -------
from __future__ import with_statement
import ctypes
from ctypes import *
from ctypes.wintypes import *
import getpass
import os
def _stdcall(dllname, restype, funcname, *argtypes):
# a decorator for a generator.
# The decorator loads the specified dll, retrieves the
# function with the specified name, set its restype and argtypes,
# it then invokes the generator which must yield twice: the first
# time it should yield the argument tuple to be passed to the dll
# function (and the yield returns the result of the call).
# It should then yield the result to be returned from the
# function call.
def decorate(func):
api = getattr(WinDLL(dllname), funcname)
api.restype = restype
api.argtypes = argtypes
def decorated(*args, **kw):
iterator = func(*args, **kw)
nargs = iterator.next()
if not isinstance(nargs, tuple):
nargs = (nargs,)
try:
res = api(*nargs)
except Exception, e:
return iterator.throw(e)
return iterator.send(res)
return decorated
return decorate
# Structure for NetUseAdd:
class USE_INFO_2(Structure):
_fields_ = [("local", LPWSTR),
("remote", LPWSTR),
("password", LPWSTR),
("status", DWORD),
("asg_type", DWORD),
("refcount", DWORD),
("usecount", DWORD),
("username", LPWSTR),
("domain", LPWSTR)]
@_stdcall("netapi32", c_int, "NetUseAdd", LPWSTR, DWORD, POINTER(USE_INFO_2), POINTER(DWORD))
def NetUseAdd(local, remote, password, asg_type=0, username=None, domainname=None):
"""Add a network connection. Returns 0 if successful"""
useinfo = USE_INFO_2(local, remote, password, 0, 0, 0, 0, username, domainname)
ParmError = DWORD()
res = yield(None, 2, useinfo, ParmError)
if res != 0:
raise RuntimeError("Could not create connection", res)
yield res
@_stdcall("netapi32", c_int, "NetUseDel", LPWSTR, LPWSTR, DWORD)
def NetUseDel(usename, forcecond=0):
res = yield(None, usename, forcecond)
if res != 0:
raise RuntimeError("Could not delete connection", res)
yield res
if __name__=='__main__':
username = "ZZZZZZ"
password = getpass.getpass("Password:")
sharename = r"\\10.10.25.121\rootc"
filename = "default.tag"
try:
with open(os.path.join(sharename, filename), "r") as f:
print f.read()
except IOError, e:
print "without net use, got", e
else:
raise RuntimeError("We connected without doing the net use!")
NetUseAdd(None, sharename, password, username=username)
with open(os.path.join(sharename, "default.tag"), "r") as f:
print f.read()
NetUseDel(sharename)
-----------------------
--
Duncan Booth
http://kupuguy.blogspot.com