检查环境:

1. 检查是否装过了ftp服务器

如果没有提示内容折,本机没有安装。

root@hadoops:~# rpm -qa|grep vsftpd
root@hadoops:~# rpm -qa|grep anonftp

2.全新安装:apt-get install vsftpd


重新安装:apt-get --reinstall install vsftpd

卸载并清除配置文件:apt-get -purge remove vsftpd

3. 我们可以通过pgrep vsftpd 来查看vsftpd服务器是否运行起来;

  root@hadoops:~# pgrep vsftpd

     4248

4. 编辑配置文件/etc/vsftpd.conf. 打开配置文件后可以看到许多以“#”开始的行,这些行都是注释行,大多是帮助信息,可以仔细阅读。

  1. # Example config file /etc/vsftpd.conf
  2. #
  3. # The default compiled in settings are fairly paranoid. This sample file
  4. # loosens things up a bit, to make the ftp daemon more usable.
  5. # Please see vsftpd.conf.5 for all compiled in defaults.
  6. #
  7. # READ THIS: This example file is NOT an exhaustive list of vsftpd options.
  8. # Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
  9. # capabilities.
  10. #
  11. #
  12. # Run standalone? vsftpd can run either from an inetd or as a standalone
  13. # daemon started from an initscript.
  14. listen=YES
  15. #
  16. # Run standalone with IPv6?
  17. # Like the listen parameter, except vsftpd will listen on an IPv6 socket
  18. # instead of an IPv4 one. This parameter and the listen parameter are mutually
  19. # exclusive.
  20. #listen_ipv6=YES
  21. #
  22. # Allow anonymous FTP? (Disabled by default)
  23. anonymous_enable=YES
  24. #
  25. # Uncomment this to allow local users to log in.
  26. local_enable=YES
  27. #
  28. # Uncomment this to enable any form of FTP write command.
  29. write_enable=YES
  30. #
  31. # Default umask for local users is 077. You may wish to change this to 022,
  32. # if your users expect that (022 is used by most other ftpd's)
  33. local_umask=000
  34. anon_umask=000
  35. #
  36. # Uncomment this to allow the anonymous FTP user to upload files. This only
  37. # has an effect if the above global write enable is activated. Also, you will
  38. # obviously need to create a directory writable by the FTP user.
  39. anon_upload_enable=YES
  40. file_open_mode=0755
  41. #
  42. # Uncomment this if you want the anonymous FTP user to be able to create
  43. # new directories.
  44. anon_mkdir_write_enable=YES
  45. #
  46. # Activate directory messages - messages given to remote users when they
  47. # go into a certain directory.
  48. dirmessage_enable=YES
  49. #
  50. # If enabled, vsftpd will display directory listings with the time
  51. # in your local time zone. The default is to display GMT. The
  52. # times returned by the MDTM FTP command are also affected by this
  53. # option.
  54. use_localtime=YES
  55. #
  56. # Activate logging of uploads/downloads.
  57. xferlog_enable=YES
  58. #
  59. # Make sure PORT transfer connections originate from port 20 (ftp-data).
  60. connect_from_port_20=YES
  61. #
  62. # If you want, you can arrange for uploaded anonymous files to be owned by
  63. # a different user. Note! Using "root" for uploaded files is not
  64. # recommended!
  65. #chown_uploads=YES
  66. #chown_username=whoever
  67. #
  68. # You may override where the log file goes if you like. The default is shown
  69. # below.
  70. #xferlog_file=/var/log/vsftpd.log
  71. #
  72. # If you want, you can have your log file in standard ftpd xferlog format.
  73. # Note that the default log file location is /var/log/xferlog in this case.
  74. xferlog_std_format=YES
  75. #
  76. # You may change the default value for timing out an idle session.
  77. #idle_session_timeout=600
  78. #
  79. # You may change the default value for timing out a data connection.
  80. #data_connection_timeout=120
  81. #
  82. # It is recommended that you define on your system a unique user which the
  83. # ftp server can use as a totally isolated and unprivileged user.
  84. #nopriv_user=ftpsecure
  85. #
  86. # Enable this and the server will recognise asynchronous ABOR requests. Not
  87. # recommended for security (the code is non-trivial). Not enabling it,
  88. # however, may confuse older FTP clients.
  89. #async_abor_enable=YES
  90. #
  91. # By default the server will pretend to allow ASCII mode but in fact ignore
  92. # the request. Turn on the below options to have the server actually do ASCII
  93. # mangling on files when in ASCII mode.
  94. # Beware that on some FTP servers, ASCII support allows a denial of service
  95. # attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
  96. # predicted this attack and has always been safe, reporting the size of the
  97. # raw file.
  98. # ASCII mangling is a horrible feature of the protocol.
  99. #ascii_upload_enable=YES
  100. #ascii_download_enable=YES
  101. #
  102. # You may fully customise the login banner string:
  103. #ftpd_banner=Welcome to blah FTP service.
  104. #
  105. # You may specify a file of disallowed anonymous e-mail addresses. Apparently
  106. # useful for combatting certain DoS attacks.
  107. #deny_email_enable=YES
  108. # (default follows)
  109. #banned_email_file=/etc/vsftpd.banned_emails
  110. #
  111. # You may restrict local users to their home directories. See the FAQ for
  112. # the possible risks in this before using chroot_local_user or
  113. # chroot_list_enable below.
  114. #chroot_local_user=YES
  115. #
  116. # You may specify an explicit list of local users to chroot() to their home
  117. # directory. If chroot_local_user is YES, then this list becomes a list of
  118. # users to NOT chroot().
  119. # (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
  120. # the user does not have write access to the top level directory within the
  121. # chroot)
  122. #chroot_local_user=YES
  123. #chroot_list_enable=YES
  124. # (default follows)
  125. #chroot_list_file=/etc/vsftpd.chroot_list
  126. #
  127. # You may activate the "-R" option to the builtin ls. This is disabled by
  128. # default to avoid remote users being able to cause excessive I/O on large
  129. # sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
  130. # the presence of the "-R" option, so there is a strong case for enabling it.
  131. #ls_recurse_enable=YES
  132. #
  133. # Customization
  134. #
  135. # Some of vsftpd's settings don't fit the filesystem layout by
  136. # default.
  137. #
  138. # This option should be the name of a directory which is empty. Also, the
  139. # directory should not be writable by the ftp user. This directory is used
  140. # as a secure chroot() jail at times vsftpd does not require filesystem
  141. # access.
  142. secure_chroot_dir=/var/run/vsftpd/empty
  143. #
  144. # This string is the name of the PAM service vsftpd will use.
  145. pam_service_name=vsftpd
  146. #
  147. # This option specifies the location of the RSA certificate to use for SSL
  148. # encrypted connections.
  149. rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
  150. # This option specifies the location of the RSA key to use for SSL
  151. # encrypted connections.
  152. rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
  153. local_root=/home/ftp
  154. anon_root=/home/ftp
说明上传文件的权限问题,其中添加
  1. local_umask=000
  2. anon_umask=000
这里有个权限的计算方法,目录的初始权限是 777 ,文件的初始权限是 666
计算方法为:用初始的权限 - 权限umask的权限 = 新建目录或文件的权限

新建目录的权限就是777-022=755

新建文件的权根就是666-022=644

下面就是我上传文件的权限为755
 
5.这里添加local_root=/home/ftp 指定ftp登录的根目录

使用如下命令关闭ftp服务:
    root@hadoops:~# killall vsftpd    //或是 pkill vsftpd

root@hadoops:~# pgrep vsftpd   //查看vsftpd服务器是否已经关闭

重新启动ftp服务
root@hadoops:~$ sudo service vsftpd restart
查看ftp服务是否启动
root@hadoops:~# ps -e | grep ftp
6.更改/home/ftp的权限

更改/home/ftp/upload的权限

7.java编程连接ftp服务器
  1. package com.csr.linux.util;
  2. import java.io.DataInputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.io.OutputStream;
  8. import java.util.ArrayList;
  9. import java.util.List;
  10. import java.util.StringTokenizer;
  11. import com.csr.configSite.ConfigAll;
  12. import sun.net.TelnetInputStream;
  13. import sun.net.TelnetOutputStream;
  14. import sun.net.ftp.FtpClient;
  15. /**
  16. * ftp上传,下载
  17. * @author why 2009-07-30
  18. *
  19. */
  20. public class FtpUtil {
  21. private String ip = ConfigAll.ftpIp;
  22. private String username = ConfigAll.ftpUsername;
  23. private String password = ConfigAll.ftpPassword;
  24. private int port = -1;
  25. private String path = "";
  26. FtpClient ftpClient = null;
  27. OutputStream os = null;
  28. FileInputStream is = null;
  29. public FtpUtil(){
  30. ftpClient = new FtpClient();
  31. try {
  32. if(this.port != -1){
  33. ftpClient.openServer(this.ip,this.port);
  34. }else{
  35. ftpClient.openServer(this.ip);
  36. }
  37. ftpClient.login(this.username, this.password);
  38. if (this.path.length() != 0){
  39. ftpClient.cd(this.path);// path是ftp服务下主目录的子目录
  40. }
  41. ftpClient.binary();// 用2进制上传、下载
  42. System.out.println("已登录到\"" + ftpClient.pwd() + "\"目录");
  43. ftpClient.sendServer("quote PASV");
  44. // return true;
  45. }catch (IOException e){
  46. e.printStackTrace();
  47. // return false;
  48. }
  49. }
  50. /**
  51. * 连接ftp服务器
  52. *
  53. * @throws IOException
  54. */
  55. // public boolean connectServer(){
  56. // ftpClient = new FtpClient();
  57. // try {
  58. // if(this.port != -1){
  59. // ftpClient.openServer(this.ip,this.port);
  60. // }else{
  61. // ftpClient.openServer(this.ip);
  62. // }
  63. // ftpClient.login(this.username, this.password);
  64. // if (this.path.length() != 0){
  65. // ftpClient.cd(this.path);// path是ftp服务下主目录的子目录
  66. // }
  67. //
  68. // ftpClient.binary();// 用2进制上传、下载
  69. // System.out.println("已登录到\"" + ftpClient.pwd() + "\"目录");
  70. // ftpClient.sendServer("quote PASV");
  71. // return true;
  72. // }catch (IOException e){
  73. // e.printStackTrace();
  74. // return false;
  75. // }
  76. // }
  77. /**
  78. * 断开与ftp服务器连接
  79. *
  80. * @throws IOException
  81. */
  82. public boolean closeServer(){
  83. try{
  84. if (is != null) {
  85. is.close();
  86. }
  87. if (os != null) {
  88. os.close();
  89. }
  90. if (ftpClient != null) {
  91. ftpClient.closeServer();
  92. }
  93. System.out.println("已从服务器断开");
  94. return true;
  95. }catch(IOException e){
  96. e.printStackTrace();
  97. return false;
  98. }
  99. }
  100. /**
  101. * 检查文件夹在当前目录下是否存在
  102. * @param dir
  103. * @return
  104. */
  105. private boolean isDirExist(String dir){
  106. String pwd = "";
  107. try {
  108. pwd = ftpClient.pwd();
  109. ftpClient.cd(dir);
  110. ftpClient.cd(pwd);
  111. }catch(Exception e){
  112. return false;
  113. }
  114. return true;
  115. }
  116. /**
  117. * 在当前目录下创建文件夹
  118. * @param dir
  119. * @return
  120. * @throws Exception
  121. */
  122. private boolean createDir(String dir){
  123. try{
  124. ftpClient.ascii();
  125. StringTokenizer s = new StringTokenizer(dir, "/"); //sign
  126. s.countTokens();
  127. String pathName = ftpClient.pwd();
  128. while(s.hasMoreElements()){
  129. pathName = pathName + "/" + (String) s.nextElement();
  130. try {
  131. ftpClient.sendServer("MKD " + pathName + "\r\n");
  132. } catch (Exception e) {
  133. e = null;
  134. return false;
  135. }
  136. ftpClient.readServerResponse();
  137. }
  138. ftpClient.binary();
  139. return true;
  140. }catch (IOException e1){
  141. e1.printStackTrace();
  142. return false;
  143. }
  144. }
  145. /**
  146. * ftp上传
  147. * 如果服务器段已存在名为filename的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
  148. *
  149. * @param filename 要上传的文件(或文件夹)名
  150. * @return
  151. * @throws Exception
  152. */
  153. public boolean upload(String filename){
  154. String newname = "";
  155. if(filename.indexOf("/") > -1){
  156. newname = filename.substring(filename.lastIndexOf("/") + 1);
  157. }else{
  158. newname = filename;
  159. }
  160. return upload(filename, newname);
  161. }
  162. /**
  163. * ftp上传
  164. * 如果服务器段已存在名为newName的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
  165. *
  166. * @param fileName 要上传的文件(或文件夹)名
  167. * @param newName 服务器段要生成的文件(或文件夹)名
  168. * @return
  169. */
  170. public boolean upload(String fileName, String newName){
  171. try{
  172. String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
  173. File file_in = new File(savefilename);//打开本地待长传的文件
  174. if(!file_in.exists()){
  175. throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
  176. }
  177. if(file_in.isDirectory()){
  178. upload(file_in.getPath(),newName,ftpClient.pwd());
  179. }else{
  180. uploadFile(file_in.getPath(),newName);
  181. }
  182. if(is != null){
  183. is.close();
  184. }
  185. if(os != null){
  186. os.close();
  187. }
  188. return true;
  189. }catch(Exception e){
  190. e.printStackTrace();
  191. System.err.println("Exception e in Ftp upload(): " + e.toString());
  192. return false;
  193. }finally{
  194. try{
  195. if(is != null){
  196. is.close();
  197. }
  198. if(os != null){
  199. os.close();
  200. }
  201. }catch(IOException e){
  202. e.printStackTrace();
  203. }
  204. }
  205. }
  206. /**
  207. * 真正用于上传的方法
  208. * @param fileName
  209. * @param newName
  210. * @param path
  211. * @throws Exception
  212. */
  213. private void upload(String fileName, String newName,String path) throws Exception{
  214. String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
  215. File file_in = new File(savefilename);//打开本地待长传的文件
  216. if(!file_in.exists()){
  217. throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
  218. }
  219. if(file_in.isDirectory()){
  220. if(!isDirExist(newName)){
  221. createDir(newName);
  222. }
  223. ftpClient.cd(newName);
  224. File sourceFile[] = file_in.listFiles();
  225. for(int i = 0; i < sourceFile.length; i++){
  226. if(!sourceFile[i].exists()){
  227. continue;
  228. }
  229. if(sourceFile[i].isDirectory()){
  230. this.upload(sourceFile[i].getPath(),sourceFile[i].getName(),path+"/"+newName);
  231. }else{
  232. this.uploadFile(sourceFile[i].getPath(),sourceFile[i].getName());
  233. }
  234. }
  235. }else{
  236. uploadFile(file_in.getPath(),newName);
  237. }
  238. ftpClient.cd(path);
  239. }
  240. /**
  241. * upload 上传文件
  242. *
  243. * @param filename 要上传的文件名
  244. * @param newname 上传后的新文件名
  245. * @return -1 文件不存在 >=0 成功上传,返回文件的大小
  246. * @throws Exception
  247. */
  248. public long uploadFile(String filename, String newname) throws Exception{
  249. long result = 0;
  250. TelnetOutputStream os = null;
  251. FileInputStream is = null;
  252. try {
  253. java.io.File file_in = new java.io.File(filename);
  254. if(!file_in.exists())
  255. return -1;
  256. os = ftpClient.put(newname);
  257. result = file_in.length();
  258. is = new FileInputStream(file_in);
  259. byte[] bytes = new byte[1024];
  260. int c;
  261. while((c = is.read(bytes)) != -1){
  262. os.write(bytes, 0, c);
  263. }
  264. }finally{
  265. if(is != null){
  266. is.close();
  267. }
  268. if(os != null){
  269. os.close();
  270. }
  271. }
  272. return result;
  273. }
  274. /**
  275. * 从ftp下载文件到本地
  276. *
  277. * @param filename 服务器上的文件名
  278. * @param newfilename 本地生成的文件名
  279. * @return
  280. * @throws Exception
  281. */
  282. public long downloadFile(String filename, String newfilename){
  283. long result = 0;
  284. TelnetInputStream is = null;
  285. FileOutputStream os = null;
  286. try{
  287. is = ftpClient.get(filename);
  288. java.io.File outfile = new java.io.File(newfilename);
  289. os = new FileOutputStream(outfile);
  290. byte[] bytes = new byte[1024];
  291. int c;
  292. while ((c = is.read(bytes)) != -1) {
  293. os.write(bytes, 0, c);
  294. result = result + c;
  295. }
  296. }catch (IOException e){
  297. e.printStackTrace();
  298. }finally{
  299. try {
  300. if(is != null){
  301. is.close();
  302. }
  303. if(os != null){
  304. os.close();
  305. }
  306. } catch (IOException e) {
  307. e.printStackTrace();
  308. }
  309. }
  310. return result;
  311. }
  312. /**
  313. * 取得相对于当前连接目录的某个目录下所有文件列表
  314. *
  315. * @param path
  316. * @return
  317. */
  318. public List getFileList(String path){
  319. List list = new ArrayList();
  320. DataInputStream dis;
  321. try {
  322. dis = new DataInputStream(ftpClient.nameList(this.path + path));
  323. String filename = "";
  324. while((filename = dis.readLine()) != null){
  325. list.add(filename);
  326. }
  327. } catch (IOException e) {
  328. e.printStackTrace();
  329. }
  330. return list;
  331. }
  332. public static void main(String[] args){
  333. FtpUtil ftp = new FtpUtil();
  334. // ftp.connectServer();
  335. boolean result = ftp.upload("D:/2.xml", "/upload/2.xml");
  336. System.out.println(result?"上传成功!":"上传失败!");
  337. List list = ftp.getFileList("/upload");
  338. for(int i=0;i<list.size();i++){
  339. String name = list.get(i).toString();
  340. System.out.println(name);
  341. }
  342. ftp.closeServer();
  343. /**
  344. FTP远程命令列表
  345. USER PORT RETR ALLO DELE SITE XMKD CDUP FEAT
  346. PASS PASV STOR REST CWD STAT RMD XCUP OPTS
  347. ACCT TYPE APPE RNFR XCWD HELP XRMD STOU AUTH
  348. REIN STRU SMNT RNTO LIST NOOP PWD SIZE PBSZ
  349. QUIT MODE SYST ABOR NLST MKD XPWD MDTM PROT
  350. 在服务器上执行命令,如果用sendServer来执行远程命令(不能执行本地FTP命令)的话,所有FTP命令都要加上\r\n
  351. ftpclient.sendServer("XMKD /test/bb\r\n"); //执行服务器上的FTP命令
  352. ftpclient.readServerResponse一定要在sendServer后调用
  353. nameList("/test")获取指目录下的文件列表
  354. XMKD建立目录,当目录存在的情况下再次创建目录时报错
  355. XRMD删除目录
  356. DELE删除文件
  357. */
  358. }
  359. }
运行结果如下:




ubuntu上安装vsftp-使用java进行匿名链接的更多相关文章

  1. ZH奶酪:如何在Ubuntu上安装Java/管理多个JAVA/设置JAVA_HOME

    0.简介 Java的地位及重要性,大家都懂的,很多软件都依赖于jdk,在Ubuntu上安装Java的选择有很多,openJDK,Oracle Jdk... 1.安装默认 JRE/JDK(可选) 这是最 ...

  2. 在Ubuntu上安装JDK、Ant、Jmeter和Jenkins

    一.前期准备 1. 在win7下载VMware.Ubuntu(用迅雷下比较快) 2. 安装完VMware后新建虚拟机,选择iso: 3. 具体配置参考如下,至此Ubantu安装完成 二.在Ubuntu ...

  3. Ubuntu 上安装 Freemind 并支持中文

    Ubuntu 上安装 Freemind 并支持中文 JAVA 运行时 Freemind 是一个使用 Java 编写的思维导图工具,在安装时,需要到 Java 运行时(使用 OpenJRE 或 Orac ...

  4. Ubuntu上安装jdk,Jboss

    Ubuntu上安装jdk 1.使用wget命令或sft方式从oracle官方下载tar.gz格式的jdk1.7,由于ubuntu不支持rpm安装,需要转换,所以不选择rpm格式的jdk 2.使用tar ...

  5. Ubuntu上安装QQ2015

    先不卖关子直接上图:Ubuntu 14.04.5 LTS Deb包下载地址: http://www.longene.org/download/WineQQ7.8-20151109-Longene.de ...

  6. 在 Linux ubuntu 上安装 *.sh 文件

    简单说来就两步: 增加可执行权限 执行 事情是这样的,打算在 ubuntu 上安装一个 NetBeans IDE 来学习 Java,但是下载下来的文件是 .sh 格式的.图形界面下右键没有执行的选项. ...

  7. Ubuntu上安装与配置JDK1.8

    Ubuntu上安装与配置JDK1.8 一.下载 下载JDK,由于是Ubuntu. 所以去官网下载tar.gz格式的就可以(ubuntu使用浏览器下载网速比較慢,所以推荐到window上下载好). ht ...

  8. ubuntu 下安装eclipse &amp;java环境配置

    前面有一篇的博客写的是ubuntu下安装eclipse和java环境的配置.当时是安装网上的攻略进行的 ,当然也是能够成功的. 近期把那台电脑送人了 ,仅仅好在自己的这台电脑上又一次安装一次了 ,唯一 ...

  9. [异常解决] ubuntu上安装JLink驱动遇到的坑及给后来者的建议

    一.前言 最近将整个电脑格式化,改成了linux操作系统 希望这样能让自己在一个新的世界探索技术.提升自己吧- win上的工具用多了,就不想变化了- 继上一篇<ubuntu上安装虚拟机遇到的问题 ...

随机推荐

  1. RichTextEditor 文本编辑

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  2. Inno Setup入门(二十)——Inno Setup类参考(6)

    存储框 存储框也是典型的窗口可视化组件,同编辑框类似,可以输入.显示文本,但是和编辑框不同的是,编辑框只能编辑.显示单行文本,而存储框则可以对多行文本进行操作.存储框的类定义如下:< xmlna ...

  3. OpenLayers 3 的地图基本操作

    <body> <div id="map"> <div id="menu"> <button id="zoom ...

  4. 444A/CF

    题目链接[http://codeforces.com/problemset/problem/444/A] 题意:给出一个无向图,找出一个联通子图,定义密度#=v(顶点值的和)/e(边值的和). 条件: ...

  5. centos6.5 安装git

    1.安装编译git时需要的包 # yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel # yum ins ...

  6. encodeURIComponent与URLDecoder.decode用法

    在输入地址栏时有时一些信息需要在地址栏看不见,我们就需要对其信息在前台转码后台解码 js:encodeURIComponent编码与解码 今天在js往jsp和servlet传参的时候出现:JavaSc ...

  7. 基础-session,cookie,jsp,EL,JSTL

    会话可以简单理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. kookie是在服务器端创建的,返回给浏览器,在浏览器的目录中保存了,下一次 ...

  8. math ceil以及math floor,math:round

    ◎Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数:◎Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数:◎Math.round()执行标准舍入,即它总 ...

  9. 批量文件重命名工具-极力推荐 advanced renamer

    http://www.advancedrenamer.com/  功能太强大了,自己慢慢探索吧.

  10. 用Visual Studio 2015 编写驱动之前一定要注意的问题!!!

    如果你确定要使用Visual Studio 2015 编写驱动,那么在你安装Visual Studio 2015 和WDK之前,一定一定要注意一件事情,那就是确保SDK和WDK版本保持一致,切记切记! ...