文章来源:http://blog.csdn.net/huanglong8/article/details/53574158
最近的开发工作中,有一个小需求需要实现。其主要目的就是通过API实现对远程主机的登录及共享访问。在查阅MSDN之前,我先通过命令行,对这种Samba(net)共享有一个初步的理解。
关于samba的说明及意义
http://www.jtyun.com.cn/forum.php?mod=viewthread&tid=103
http://blog.csdn.net/shenwansangz/article/details/46346275
Windows中设置共享的方法很简单。在属性菜单中即可找到。但需要注意的是,如果需要设置无账户密码访问的共享目录,需要在属性安全菜单中,添加 Everyone 用户,并设置相应的读写权限。在远程访问时,就无需输入账户密码了。
设置好共享后,通过命令行进行远程登录访问。
1.直接查看共享列表
资源管理器中可以直接输入\TEST-PC或\192.168.1.5。首先必须是处于同一段网络中。
命令行方式
net view \192.168.1.5
2.命令行登录
net use \\192.168.1.5 test /user:administrator
test是密码,/user后是账户名,此项缺省值。
登录后,可以通过net view命令来查看之前可能因为登录失败而无法查看到的共享列表了。
3.命令行共享映射
net use K: \\192.168.1.5\Share
在电脑上就会出现一个磁盘驱动器,它将远程的共享目录映射到本地磁盘中,方便用户直接访问,并保持长时间的连接。
4.删除驱动器,断开远程连接
net use K: /del
net use \\192.168.1.5 /del
net use * /del /y 断开所有
注意,如果在连接中,出现53错误提示,通常可能是网络不稳定情况,需要先ping以下,然后再连接即可。
注意,如果在连接中,出现1219错误提示,可能是之前有连接过此ip,这时,可以通过断开连接,或断开所有连接进行重置,再登录就可以了。
以上就是net最基础的登录访问,其他net命令行可参考
http://www.cnblogs.com/chenjq0717/archive/2010/05/09/1730934.html
通常windows提供的命令行,在其winapi中都可以找到相应的原型。罗列如下:
Net资源初始化
NETRESOURCE net
char cmd[128];
sprintf(cmd,"\\\\%s","192.168.1.5");
net.dwScope = RESOURCE_GLOBALNET;
net.dwType = RESOURCETYPE_DISK;
net.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
net.dwUsage = RESOURCEUSAGE_CONNECTABLE;
net.lpLocalName = (LPSTR)malloc(sizeof(LPSTR)*128);
net.lpRemoteName = (LPSTR)malloc(sizeof(LPSTR)*128);
strcpy(net.lpRemoteName, cmd);
strcpy(net.lpLocalName,"");
net.lpComment = NULL;
net.lpProvider = NULL;
登录及共享映射的API
__checkReturn
DWORD APIENTRY WNetAddConnection2A(
__in LPNETRESOURCEA lpNetResource,
__in_opt LPCSTR lpPassword,
__in_opt LPCSTR lpUserName,
__in DWORD dwFlags
);
lpNetResource是一个结构体,主要存放本地驱动器名称和远程地址及共享目录名称
lpPassword是登录密码,可以为空
lpUserName是登录账户,可以为空
dwFlags是连接方式,具体的可以查MSDN,通常,我们设置为CONNECT_UPDATE_PROFILE
打开枚举,建立共享访问通道
__checkReturn
DWORD APIENTRY WNetOpenEnumA(
__in DWORD dwScope,
__in DWORD dwType,
__in DWORD dwUsage,
__in_opt LPNETRESOURCEA lpNetResource,
__out LPHANDLE lphEnum
);
dwScope 资源范围,通常设置为RESOURCE_GLOBALNET
dwType资源类型,通常设置为RESOURCETYPE_DISK
dwUsage资源方式,通常设置为0
lpNetResource和登录api相同,需要的是同一个指针
lphEnum共享的句柄,主要通过这个句柄进行共享的访问
遍历枚举句柄,列出共享名称
__checkReturn
DWORD APIENTRY WNetEnumResourceA(
__in HANDLE hEnum,
__inout LPDWORD lpcCount,
__out_bcount(*lpBufferSize) LPVOID lpBuffer,
__inout LPDWORD lpBufferSize
);
hEnum 获取到的枚举句柄
lpcCount返回的共享个数
lpBuffer一个保存了共享名称的数组指针
lpBufferSize数组长度,太短会溢出
删除或登出共享
__checkReturn
DWORD APIENTRY WNetCancelConnection2A(
__in LPCSTR lpName,
__in DWORD dwFlags,
__in BOOL fForce
);
lpName 登录的IP或映射的驱动器
dwFlags连接方式,通常为CONNECT_UPDATE_PROFILE
fForce强制断开,true或false
注意,使用以上API需要链接到mpr.lib库
#pragma comment(lib,”mpr.lib”)
完整的代码示例已整理分享
http://download.csdn.net/detail/huanglong8/9708200
在进行系统集成等需要注意的是权限问题,因为使用此API,需要用户权限,系统权限是无法登录成功的。之所以在VS或者命令行中调试成功是因为启动的窗口本来就是用户权限了。这里测试bug可以启用具有 system权限的 桌面系统,参考:
这里的做法是
1.可以让具备user权限的程序进行过程调用,这样权限是可以继承下来的,例如托盘或其他应用程序。
2.如果只有system权限,那么调用时需要获取user权限,需要获取桌面程序的token来调用,具体参考: