VSS

1.setup environment variable: //指向ss.exe所在的路径
path=%path%;C:\Program Files\Microsoft Visual Studio\VSS\win32


2.指向VSS数据库的所在目录
set SSDIR=\\gqa-eric-lv\VSS\
set SSDIR=\\Guruvss\erp$\

3.登陆VSS:
ss CP -Yeric,eric123 -I- -s\\gqa-eric-lv\vss

4.获取任一目录的任一文件到本机(下例将$/ASP.Net/DataGridTest/index.aspx文件get到D:\tmp目录)
ss get -GLD:\tmp $/ASP.Net/DataGridTest/index.aspx
(ss get, -GLpath Copies a file to the specified folder, not to the current or working folder. )

5.分屏显示目录ASP.Net中的所有文件和文件夹(包括子文件):
ss dir $/ASP.Net -R|more (另外,有-I -V 两个参数,作用未知)

6.set Current Project:
ss cp $/SQL-sample

7.vss命令行是大小写不敏感的;命令行中的命令不需要全名,同sql一样,只要是可以识别的名字及可,如Dir就是directory的缩写;
(遵守UNC通用命名规则,Universal Naming Convention)

8.一些通用的命令行选项:
Option
Description

-C
为指定项(可以是多项)做注释 (Dir例外)

-O
重定向命令

-V
操作某项的指定版本

-R
Perform a command recursively.

-S
Turn SmartMode on or off for the command.

-G
Change the way the Get command works on any file retrieved to the local drive.

-W
指明本机副本是否只读(使用此参数,表示writable)

-N
在长短文件名两种模式间切换

-I-
任何环境下都不提示输入

-Y
指定用户名和密码

-?, -H
两个参数的作用都是获得在线的帮助

9.命令中有空格时,用双引号括起整个选项,如用ss CP "-Yeric Lv",eric123 而不用ss CP -Y"eric lv",eric123,

10.启动图形界面:ssexp -s\\gqa-eric-lv\vss

11.ss命令中,/表示VSS的当前目录,$/表示根目录,常用操作命令如下:
 ss Add TEST.C "My long filename.H" ,把TEST.C和"My long filename.H"两个文件添加到当前项目;
 ss Add -R *,把当前目录的所有文件及文件夹(包括子文件夹、文件)添加到当前项目;
 ss ADD -D- *.DLL,添加当前目录的所有DLL文件到当前项目,但不保留VSS上的历史文件(以节省空间);
 ss Checkout TEST.C TEST.H      Checkout当前项目中的两个文件
 ss Checkout $/TESTDATA/TEST.C Checkout指定项目中的文件
 ss Checkout -R $/TESTDATA      循环Check项目$/TESTDATA
 ss Comment TEST.C -V5      改变TEST.C的版本号为5的版本注释
 ss Comment TEST.C          改变TEST.C的最新版本的注释
 ss Comment $/TESTDATA      改变项目$/TESTDATA的注释
 ss Create $/WORD           VSS的根目录下,创建项目WORD
 ss Create WORD             VSS的当前目录下,创建项目WORD
 ss Cp $/WORD               设置$/WORD为Current Project
 ss Cp ..                   跳转到当前项目的父项目
 ss Delete $/PRJ/TEST.C     删除文件TEST.C (delete命令删除的文件,可以用直接add命令回复,如Add test.C)
 ss Delete $/PRJ            删除项目 (不可以有两个同名的文件被delete,因为没有真正删除)
 ss -S Delete *.*           删除所有文件,-S表示删除VSS上的文件之后,删除本机文件
 ss Destroy $/PRJ/TEST.C    持久删除文件(不可恢复)
 ss Destroy $/PRJ           持久删除项目


12.其他的更改操作有:label,merge,move,password,purge,recover,rename,rollback,share,undocheckout,workfold,branch等命令,这些命令会改变VSS数据库的内容或者环境。

13.VSS命令行中的比较/查找/显示等不改变数据库和环境的命令:   diff,dir,FileType,Get,help,history,links,paths,project,properties,status,view,whoami

14.显示最近的Version,Label信息:SS properties

15.显示Checkout的文件:SS Status

====================================================================
vss 命令行执行相关操作搜集整理

参考资料:
1.msdn;
2.http://blog.gameres.com/show.asp?BlogID=155&column=0
3.http://dev.csdn.net/article/51/article/52/52913.shtm

有时候,常常取固定的文件到固定的目录,每次鼠标操作很机械。最直接的想法便是,做成批处理文件。这就需要搜集到vss命令行执行的相关操作:

1.设置vss命令行程序ss.exe的路径:
PATH=%PATH%;X:\……\Microsoft Visual Studio\Common\VSS\win32

2.设置vss数据库的路径(注意):
set ssdir=\\cmserver\Project

3.设置vss的登录用户名:
set ssuser=yourAccount

4.设置vss的登录密码:
set sspwd=yourPwd

5.vss Check Out单个文件:
ss Checkout $/vssPath/fileName

6.vss Check In 单个文件:
ss checkin $/vssPath/fileName -C"your comment"

7.vss Undo Check Out单个文件:
ss Undocheckout $/vssPath/fileName

8.vss Check Out整个工程包含项目的所有子项目(子目录)(recursively):
ss Checkout $/vssPath/ -R

9.vss Check In 整个工程包含项目的所有子项目(子目录)(recursively):
ss checkin $/vssPath/* -R -C"your comment"

10.取单个文件最新版本:
ss Get $/vssPath/fileName

11.取整个工程到本地 :
ss Get $/vssPath/* -R

12.取vss服务器上的文件到指定地方(注意"-GL"后面没有空格!) :
ss get -GLX:\dest $/vssPath/fileName.txt

13.其他的更改操作有:label,merge,move,password,purge,recover,rename,rollback,share,undocheckout,workfold,branch等命令,这些命令会改变VSS数据库的内容或者环境。


14.VSS命令行中的比较/查找/显示等不改变数据库和环境的命令:   diff,dir,FileType,Get,help,history,links,paths,project,properties,status,view,whoami

15.显示最近的Version,Label信息:SS properties

16.显示Checkout的文件:SS Status


注意:
当执行命令行过程中,有提示输入“Y/N”时,可以在命令行中直接做成命令的参数,屏蔽问题。
-i-y 回答yes
-i-n 回答no

msdn上说到,当你在命令行界面下,使用像“get”,"check out" 这样的命令时,vss将把文件放置到你的当前目录,而不是像在窗口界面下一样,把相对应的文件放置在你设置的工作目录下。(现在,不明白的是,在命令行方式下,工作路径究竟有何用途?)

VSS does not, by default, change your current folder when you issue an ss CP command (change current project); nor does it change your project if you move from folder to folder. That is, the working folder has, by default, no effect on the command line and vice versa.

另外,对于执行类似于:
ss Get -GL"C:\Program Files\eclipse\workspace\abxx" $/kao_step3/abxx -R -i-y
语句时,好像对整个目录的文件都取了,而不管文件的版本号?
(现象是,执行起来,比在windows环境下对整个目录取最新版本要慢。)

 

 

 

 

 

最近工作需要将三四百个DLL文件汇入到VSS数据库中,并且一个个打上Label号,label号取的DLL的版本号(就是选中,点击鼠标邮件,属性里面可以看到的版本号),初步算了一下,这样几百个文件,一个Check out/Check in,再找到Label号,打上Label号,少说也要花上一两天的时间,这样实在是太慢了。下午希望能够通过在DotNet中编程来操作VSS数据库,于是查帮助文档,没有看到相关资料,倒是看到说VSS有命令行可以使用。于是网上搜了一下,也没看到几篇介绍VSS命令行的文章,还是看帮助文档吧,看了一个下午,一个晚上。再结合C#或者C/C++的使用,基本上以后可以实现自动Check Out/Check In并且自动打Label号了。简单总结了一下,下面是VSS的一些常用命令和操作:

1.setup environment variable: //指向ss.exe所在的路径
path=%path%;C:\Program Files\Microsoft Visual Studio\VSS\win32

2.指向VSS数据库的所在目录
set SSDIR=\\gqa-eric-lv\VSS\
set SSDIR=\\Guruvss\erp$\

3.登陆VSS:
ss CP -Yeric,eric123 -I- -s\\gqa-eric-lv\vss

4.获取任一目录的任一文件到本机(下例将$/ASP.Net/DataGridTest/index.aspx文件get到D:\tmp目录)
ss get -GLD:\tmp $/ASP.Net/DataGridTest/index.aspx
(ss get, -GLpath Copies a file to the specified folder, not to the current or working folder. )

5.分屏显示目录ASP.Net中的所有文件和文件夹(包括子文件):
ss dir $/ASP.Net -R|more (另外,有-I -V 两个参数,作用未知)

6.set Current Project:
ss cp $/SQL-sample

7.vss命令行是大小写不敏感的;命令行中的命令不需要全名,同sql一样,只要是可以识别的名字及可,如Dir就是directory的缩写;
(遵守UNC通用命名规则,Universal Naming Convention)

8.一些通用的命令行选项:
-C 为指定项(可以是多项)做注释 (Dir例外)
-O 重定向命令
-V 操作某项的指定版本
-R Perform a command recursively.
-S Turn SmartMode on or off for the command.
-G Change the way the Get command works on any file retrieved to the local drive.
-W 指明本机副本是否只读(使用此参数,表示writable)
-N 在长短文件名两种模式间切换
-I 任何环境下都不提示输入
-Y 指定用户名和密码
-?, -H 两个参数的作用都是获得在线的帮助

9.命令中有空格时,用双引号括起整个选项,如用ss CP "-Yeric Lv",eric123 而不用ss CP -Y"eric lv",eric123,

10.启动图形界面:ssexp -s\\gqa-eric-lv\vss

11.ss命令中,/表示VSS的当前目录,$/表示根目录,常用操作命令如下:
ss Add TEST.C "My long filename.H" ,把TEST.C和"My long filename.H"两个文件添加到当前项目;
ss Add -R *,把当前目录的所有文件及文件夹(包括子文件夹、文件)添加到当前项目;
ss ADD -D- *.DLL,添加当前目录的所有DLL文件到当前项目,但不保留VSS上的历史文件(以节省空间);
ss Checkout TEST.C TEST.H Checkout当前项目中的两个文件
ss Checkout $/TESTDATA/TEST.C Checkout指定项目中的文件
ss Checkout -R $/TESTDATA 循环Check项目$/TESTDATA
ss Comment TEST.C -V5 改变TEST.C的版本号为5的版本注释
ss Comment TEST.C 改变TEST.C的最新版本的注释
ss Comment $/TESTDATA 改变项目$/TESTDATA的注释
ss Create $/WORD VSS的根目录下,创建项目WORD
ss Create WORD VSS的当前目录下,创建项目WORD
ss Cp $/WORD 设置$/WORD为Current Project
ss Cp .. 跳转到当前项目的父项目
ss Delete $/PRJ/TEST.C 删除文件TEST.C (delete命令删除的文件,可以用直接add命令回复,如Add test.C)
ss Delete $/PRJ 删除项目 (不可以有两个同名的文件被delete,因为没有真正删除)
ss -S Delete *.* 删除所有文件,-S表示删除VSS上的文件之后,删除本机文件
ss Destroy $/PRJ/TEST.C 持久删除文件(不可恢复)
ss Destroy $/PRJ 持久删除项目

12.其他的更改操作有:label,merge,move,password,purge,recover,rename,rollback,share,undocheckout,workfold,branch等命令,这些命令会改变VSS数据库的内容或者环境。

13.VSS命令行中的比较/查找/显示等不改变数据库和环境的命令: diff,dir,FileType,Get,help,history,links,paths,project,properties,status,view,whoami

14.显示最近的Version,Label信息:SS properties

15.显示Checkout的文件:SS Status

Technorati : Microsoft, VSS

 

 

 

 

命令行中使用VSS
2006年11月29日 星期三 12:33
1.setup environment variable: //指向ss.exe所在的路径
path=%path%;C:\Program Files\Microsoft Visual Studio\VSS\win32

2.指向VSS数据库的所在目录
set SSDIR=\\gqa-eric-lv\VSS\
set SSDIR=\\Guruvss\erp$\

3.登陆VSS:
ss  CP -Yeric,eric123 -I- -s\\gqa-eric-lv\vss

4.获取任一目录的任一文件到本机(下例将$/ASP.Net/DataGridTest/index.aspx文件get到D:\tmp目录)
ss get -GLD:\tmp $/ASP.Net/DataGridTest/index.aspx
(ss get, -GLpath Copies a file to the specified folder, not to the current or working folder. )

5.分屏显示目录ASP.Net中的所有文件和文件夹(包括子文件):
ss dir $/ASP.Net -R|more (另外,有-I -V 两个参数,作用未知)

6.set Current Project:
ss cp $/SQL-sample

7.vss命令行是大小写不敏感的;命令行中的命令不需要全名,同sql一样,只要是可以识别的名字及可,如Dir就是directory的缩写;
(遵守UNC通用命名规则,Universal Naming Convention)

8.一些通用的命令行选项:

Option


Description

-C


为指定项(可以是多项)做注释 (Dir例外)

-O


重定向命令

-V


操作某项的指定版本

-R


Perform a command recursively.

-S


Turn SmartMode on or off for the command.

-G


Change the way the Get command works on any file retrieved to the local drive.

-W


指明本机副本是否只读(使用此参数,表示writable)

-N


在长短文件名两种模式间切换

-I-


任何环境下都不提示输入

-Y


指定用户名和密码

-?, -H


两个参数的作用都是获得在线的帮助
9.命令中有空格时,用双引号括起整个选项,如用ss  CP "-Yeric Lv",eric123 而不用ss  CP -Y"eric lv",eric123,

10.启动图形界面:ssexp  -s\\gqa-eric-lv\vss

11.ss命令中,/表示VSS的当前目录,$/表示根目录,常用操作命令如下:
 ss Add TEST.C "My long filename.H" ,把TEST.C和"My long filename.H"两个文件添加到当前项目;
 ss Add -R *,把当前目录的所有文件及文件夹(包括子文件夹、文件)添加到当前项目;
 ss ADD -D- *.DLL,添加当前目录的所有DLL文件到当前项目,但不保留VSS上的历史文件(以节省空间);
 ss Checkout TEST.C TEST.H      Checkout当前项目中的两个文件
 ss Checkout $/TESTDATA/TEST.C  Checkout指定项目中的文件
 ss Checkout -R $/TESTDATA      循环Check项目$/TESTDATA
 ss Comment TEST.C -V5      改变TEST.C的版本号为5的版本注释
 ss Comment TEST.C          改变TEST.C的最新版本的注释
 ss Comment $/TESTDATA      改变项目$/TESTDATA的注释
 ss Create $/WORD           VSS的根目录下,创建项目WORD
 ss Create WORD             VSS的当前目录下,创建项目WORD
 ss Cp $/WORD               设置$/WORD为Current Project
 ss Cp ..                   跳转到当前项目的父项目
 ss Delete $/PRJ/TEST.C     删除文件TEST.C (delete命令删除的文件,可以用直接add命令回复,如Add test.C)
 ss Delete $/PRJ            删除项目 (不可以有两个同名的文件被delete,因为没有真正删除)
 ss -S Delete *.*           删除所有文件,-S表示删除VSS上的文件之后,删除本机文件
 ss Destroy $/PRJ/TEST.C    持久删除文件(不可恢复)
 ss Destroy $/PRJ           持久删除项目


12.其他的更改操作有:label,merge,move,password,purge,recover,rename,rollback,share,undocheckout,workfold,branch等命令,这些命令会改变VSS数据库的内容或者环境。

13.VSS命令行中的比较/查找/显示等不改变数据库和环境的命令:   diff,dir,FileType,Get,help,history,links,paths,project,properties,status,view,whoami

14.显示最近的Version,Label信息:SS properties

15.显示Checkout的文件:SS Status

 

 

 

 

使用命令行操作VSS

一.        环境变量配置

1)        添加环境变量 名称为:Path;值为:VSS应用程序所在目录 例如:D:\Program files\Microsoft Visual Sourcesafe。

2)        添加环境变量 名称为:SSDIR 值为:VSS源代码数据库所在目录 例如:F:\SourceSafe。若VSS源代码数据库在局域网的其他电脑,则需要将VSS源代码文件夹设置共享文件夹,然后将SSDIR环境变量设置为:\\server\sourcesafe

3)        命行中输入ss ,如果执行成功,则说明环境变量设置成功。

二.        SS命令使用

Ø 使用ss Get命令获得源代码

1)        在命令行中定位当前目录到想要下载源代码所在的目录。

2)        在命令行中执行 ss Get $/[project] –R,此命令会递归获得项目的完整代码 [project]替换VSS中的项目。

3)        在命令行中执行 ss Get [file],此命令可以获得当前项目中指定的文件 [file] 替换为VSS项目中的文件。

 

Ø 使用 ss Chekout命令签出源代码

1)        在命令行中执行 ss Checkout $/[project]/[file],此命令会将指项目的指定文件签出到当前命令行所在的目录。

2)        在命令行中执行 ss Checkout -R $/[project],此命令将会递归签出项目所有文件。

3)        在命令行中执行 ss Checkout [file1] [file2],此命令将可以同时签出多个文件。

Ø 使用 ss Checkin 命令签出源代码

1)        在命令行中执行 ss Checkin [file],此命令将可以指定的文件签入。

2)        在命令行中执行 ss Checkin * -P ,此命令将可以签入所有签出的文件。

 

 

----------------------------------------------------------------------------------------------------

VSS,即Visual Source Safe,是微软公司开发的Windows平台上优秀的Source版本控制器。不同于CVS的是,它不是开源,因此支持VSS的只有Windows平台。但微软发布了VSS的API。任何开发者都可以通过ssapi.dll文件,开发自定义的VSS插件或其他工具。Ssapi.dll是ActiveX组件,自然能支持多种开发语言。但想要支持Java,就得使用JNI了。
本文使用JNI实现访问VSS的Java api。
1.VSS Java API

定义VSS Java API。

package org.colimas.scm.vss;

/**
 * VSS Operator class that will call native method.
 * @author tyrone
 *
 */
public class VSSOperator {

     private static String LIBPATH="vssperator.dll";

     public static String ROOT="$/";
     /**
      * load dll
      *
      */
     public VSSOperator(){
       String path=Thread.currentThread().getContextClassLoader().getResource("./").getPath();
       path=path+LIBPATH;
       System.load(path);
     }
     /**
      * load dll
      *
      */
     public VSSOperator(String libPath){
       System.load(libPath);
     }
     /**
      * Connect to VSS
      * @param path srcsafe.ini file path.
      * @param id   user id
      * @param pass password
      * @return
      */
     public native boolean connection(String path,String id,String pass);
     /**
      * disconnect from VSS
      *
      */
     public native void disconnection();
     /**
      * get current project.
      * @return
      */
     public native String getCurrentProject();
     /**
      * get database name
      * @return
      */
     public native String getDatabaseName();
     /**
      * get item names from specified path.
      * @param path
      * @return
      */
     public native String[] getItemNames(String path);
     /**
      * get specified file(s) from VSS to local.
      * @param itemName
      * @param localPath
      * @param flag
      * @return
      */
     public native boolean getFile(String itemName,String localPath,int flag);

     /**
      * get specified version of one file from VSS to local.
      * @param itemName
      * @param localPath
      * @param version
      * @param flag
      * @return
      */
     public native boolean getVersion(String itemName,String localPath,int version,int flag);
     /**
      * checkout specified file(s) from vss to local.
      * @param itemName
      * @param localPath
      * @param comment
      * @param flag
      * @return
      */
     public native boolean checkout(String itemName,String localPath,String comment,int flag);
     /**
      * check file(s) in VSS
      * @param itemName
      * @param localPath
      * @param comment
      * @param flag
      * @return
      */
     public native boolean checkin(String itemName,String localPath,String comment,int flag);
     /**
      * undo check out action
      * @param itemName
      * @param localPath
      * @param flag
      * @return
      */
     public native boolean undoCheckout(String itemName,String localPath,int flag);
}

每个native方法都由VC++实现。

2.VSS的API
CodeProject网站上有一些VSS API的相关文章,本文借鉴了下面link的内容。http://www.codeproject.com/samples/SSBrowser.asp
从该网站上下载source,内有一个头文件ssauto.h是访问VSS API的关键。该文件定义了VSSAPI涉及到的所有接口,本文使用的接口有:
IVSSDatabase:VSS数据库接口。该接口负责创建连接和获得IVSSItem。
IVSSItem:VSS内的某个文件或工程,该接口负责返回文件或项目信息,Checkout,Checkin,获得文件等。
IVSSItems:VSS内某些文件或工程,IVSSItem集合。


3.Native方法实现

3.1 搭建开发环境

3.1.1.使用javah命令生成JNI的头文件。
D:/ >javah -classpath ./;D:/MyProject/colima
s/ra/SCMResources/bin/classes org.colimas.scm.vss.VSSOperator
生成一个叫org_colimas_scm_vss_VSSOperator.h的文件。

3.1.2.创建VC++的Dynamic Link Library支持MFC的工程。将org_colimas_scm_vss_VSSOperator.h文件和ssauto.h文件添加到工程内。
3.1.3.在StdAfx.h头文件加入:
#include "ssauto.h"
#include <atlbase.h>
#include <comdef.h>
extern "C" const GUID __declspec(selectany) LIBID_SourceSafeTypeLib =
 {0x783cd4e0,0x9d54,0x11cf,{0xb8,0xee,0x00,0x60,0x8c,0xc9,0xa7,0x1f}};
extern "C" const GUID __declspec(selectany) IID_IVSSItem =
 {0x783cd4e1,0x9d54,0x11cf,{0xb8,0xee,0x00,0x60,0x8c,0xc9,0xa7,0x1f}};
extern "C" const GUID __declspec(selectany) IID_IVSSItems =
 {0x783cd4e5,0x9d54,0x11cf,{0xb8,0xee,0x00,0x60,0x8c,0xc9,0xa7,0x1f}};
extern "C" const GUID __declspec(selectany) IID_IVSSDatabase =
 {0x783cd4e2,0x9d54,0x11cf,{0xb8,0xee,0x00,0x60,0x8c,0xc9,0xa7,0x1f}};
extern "C" const GUID __declspec(selectany) CLSID_VSSItem =
 {0x783cd4e3,0x9d54,0x11cf,{0xb8,0xee,0x00,0x60,0x8c,0xc9,0xa7,0x1f}};
extern "C" const GUID __declspec(selectany) CLSID_VSSDatabase =
 {0x783cd4e4,0x9d54,0x11cf,{0xb8,0xee,0x00,0x60,0x8c,0xc9,0xa7,0x1f}};
extern "C" const GUID __declspec(selectany) IID_IVSS =
 {0x783cd4eb,0x9d54,0x11cf,{0xb8,0xee,0x00,0x60,0x8c,0xc9,0xa7,0x1f}};

//并为一些接口定义智能指针
_COM_SMARTPTR_TYPEDEF(IVSSItem, IID_IVSSItem);
_COM_SMARTPTR_TYPEDEF(IVSSItems, IID_IVSSItems);

3.1.4.在Option的Directory内加入JDK include和include/win32路径。

3.2 方法实现

在VC++源程序内加入
#include "org_colimas_scm_vss_VSSOperator.h"
并定义全局变量。

IVSSDatabase *pVdb;
IClassFactory *pClf;
3.2.1 connection方法实现
JNI定义为
JNIEXPORT jboolean JNICALL Java_org_colimas_scm_vss_VSSOperator_connection
(JNIEnv *env, jobject, jstring VSSini, jstring User, jstring Password)
在注册表中查找VSS API组件
  CLSIDFromProgID(L"SourceSafe", &clsid )
     //实例化类工厂。
  CoGetClassObject( clsid, CLSCTX_ALL, NULL,
   IID_IClassFactory, (void**)&pClf )
     //实例化IVSSDatabase
  pClf->CreateInstance( NULL, IID_IVSSDatabase,
     (void **) &pVdb )
     //创建一个VSS连接。
pVdb->Open(bstrPath, bstrUName, bstrUPass)
代码如下:
JNIEXPORT jboolean JNICALL Java_org_colimas_scm_vss_VSSOperator_connection
(JNIEnv *env, jobject, jstring VSSini, jstring User, jstring Password)
{
//将参数转换为C++基本类型。
     const unsigned short * psz_VSSini=env->GetStringChars(VSSini, 0);
     const unsigned short * psz_User=env->GetStringChars(User, 0);
     const unsigned short * psz_Password=env->GetStringChars(Password, 0);
//再将这些变量转化为COM能识别的类型。
  BSTR bstrPath = SysAllocString(psz_VSSini);
  BSTR bstrUName = SysAllocString(psz_User);
  BSTR bstrUPass = SysAllocString(psz_Password);
     CLSID clsid;
     jboolean result=JNI_FALSE;
  CoInitialize(0);
  if(S_OK == CLSIDFromProgID(L"SourceSafe", &clsid ))
  {
    if(S_OK == CoGetClassObject( clsid, CLSCTX_ALL, NULL,
   IID_IClassFactory, (void**)&pClf ))
    {
   if(S_OK == pClf->CreateInstance( NULL, IID_IVSSDatabase,
     (void **) &pVdb ))
   {
     if(S_OK == pVdb->Open(bstrPath, bstrUName, bstrUPass))
     {
#ifdef _DEBUG
     AfxMessageBox("Open successfully",MB_OK,0);
#endif
             result=JNI_TRUE;
     }else{
#ifdef _DEBUG
             AfxMessageBox("Open failed",MB_OK,0);
#endif
          }
   }else
        {
             AfxMessageBox("Init failed",MB_OK,0);
        }
    }
  }else
      {
            AfxMessageBox("You didnot install VSS yet",MB_OK,0);
      }
  //CoUninitialize();

  SysFreeString(bstrPath);
  SysFreeString(bstrUName);
  SysFreeString(bstrUPass);
      return result;
}
3.2.2 disconnectin实现

JNIEXPORT void JNICALL Java_org_colimas_scm_vss_VSSOperator_disconnection
(JNIEnv *, jobject)
{
     pVdb->Release();
     pClf->Release();
     CoUninitialize();
#ifdef _DEBUG
     AfxMessageBox("Close successfully",MB_OK,0);
#endif
}

3.2.3 getDatabaseName和getCurrentProject实现

JNIEXPORT jstring JNICALL Java_org_colimas_scm_vss_VSSOperator_getDatabaseName
(JNIEnv * env, jobject)
{
     if(pVdb==NULL)
       return NULL;
     CComBSTR bstrDatabase;
//调用IVSSDatabase方法
     if(S_OK==pVdb->get_DatabaseName(&bstrDatabase))
     {
       return env->NewString(bstrDatabase,bstrDatabase.Length());
     }else{
#ifdef _DEBUG
     AfxMessageBox("Get DB failed",MB_OK,0);
#endif
       return NULL;
     }
}

/*
 *Get current project in vss
 */
JNIEXPORT jstring JNICALL Java_org_colimas_scm_vss_VSSOperator_getCurrentProject
(JNIEnv *env, jobject)
{
     if(pVdb==NULL)
       return NULL;
     CComBSTR bstrProject;
//调用IVSSDatabase方法
     if(S_OK==pVdb->get_CurrentProject(&bstrProject))
     {

       return env->NewString(bstrProject,bstrProject.Length());
     }else
       return NULL;
}

3.2.4 getFile实现

JNIEXPORT jboolean JNICALL Java_org_colimas_scm_vss_VSSOperator_getFile
(JNIEnv *env, jobject, jstring itemName, jstring localPath, jint flag)
{
     jboolean result=JNI_FALSE;
     if(pVdb==NULL)
       return result;
     IVSSItemPtr vssRootItem;
     const unsigned short * lpath=env->GetStringChars(itemName,0);
     const unsigned short * llocalPath=env->GetStringChars(localPath,0);
//获得Item实例
     if(pVdb->get_VSSItem(CComBSTR(lpath), FALSE, &vssRootItem)==S_OK)
     {
//获得文件,并将文件下载到本地目录。
       if(vssRootItem->Get(&CComBSTR(llocalPath),flag)==S_OK)
       {
            result=JNI_TRUE;
       }
     }
     return result;
}

3.2.5 getItemNames实现

JNIEXPORT jobjectArray JNICALL Java_org_colimas_scm_vss_VSSOperator_getItemNames
(JNIEnv *env, jobject, jstring path)
{
     if(pVdb==NULL)
       return NULL;
     jobjectArray nameArray;
     IVSSItemPtr vssRootItem;
     const unsigned short * lpath=env->GetStringChars(path,0);
//获得父Item。
     if(pVdb->get_VSSItem(CComBSTR(lpath), FALSE, &vssRootItem)==S_OK)
     {
//获得所有子Item集合
       IVSSItemsPtr vss_items;
       if(vssRootItem->get_Items(_variant_t(false), &vss_items)==S_OK)
       {
            long l_count;
            CComBSTR name;
//获得子Item个数
            vss_items->get_Count(&l_count);
            nameArray=env->NewObjectArray(l_count,env->FindClass("java/lang/String"),env->NewStringUTF(""));
//遍历
            for (long i = 0; i < l_count; i++)
            {
              IVSSItemPtr vss_ChildItem;
//获得子Item
              if(vss_items->get_Item(_variant_t(i+1L), &vss_ChildItem)==S_OK)
              {
//获得子Item名称
                   vss_ChildItem->get_Name(&name);
                   jstring jname=env->NewString(name,name.Length());
                   env->SetObjectArrayElement(nameArray,i,jname);
              }else
                   break;
            }
       }
     }
     return nameArray;
}

3.2.6 getVersion实现

JNIEXPORT jboolean JNICALL Java_org_colimas_scm_vss_VSSOperator_getVersion
(JNIEnv *env, jobject, jstring itemName, jstring localPath, jint version,jint flag)
{
     jboolean result=JNI_FALSE;
     if(pVdb==NULL)
       return result;
     IVSSItemPtr vssRootItem;
     const unsigned short * lpath=env->GetStringChars(itemName,0);
     const unsigned short * llocalPath=env->GetStringChars(localPath,0);
//获得Item实例
     if(pVdb->get_VSSItem(CComBSTR(lpath), FALSE, &vssRootItem)==S_OK)
     {
       IVSSItemPtr vss_oldItem;
       //long l_version=version;
//获得该Item某个版本实例
       if(vssRootItem->get_Version(_variant_t(version), &vss_oldItem)==S_OK){
//下载到本地。
            if(vss_oldItem->Get(&CComBSTR(llocalPath),flag)==S_OK)
            {
              result=JNI_TRUE;
            }
       }
     }
     return result;
}

3.2.7 checkout实现

JNIEXPORT jboolean JNICALL Java_org_colimas_scm_vss_VSSOperator_checkout
(JNIEnv *env, jobject , jstring itemName, jstring localPath, jstring comment,jint flag)
{
     jboolean result=JNI_FALSE;
     if(pVdb==NULL)
       return result;
     IVSSItemPtr vssRootItem;
     const unsigned short * lpath=env->GetStringChars(itemName,0);
     const unsigned short * l_localPath=env->GetStringChars(localPath,0);
     const unsigned short * l_comment=env->GetStringChars(comment,0);
     //获得Item实例
     if(pVdb->get_VSSItem(CComBSTR(lpath), FALSE, &vssRootItem)==S_OK)
     {
//checkout到本地目录
       if(vssRootItem->Checkout(CComBSTR(l_comment),CComBSTR(l_localPath),flag)==S_OK)
       {
            result=JNI_TRUE;
       }else
            AfxMessageBox("checked it out fail",MB_OK);
     }

     return result;
}

3.2.8 checkin实现

JNIEXPORT jboolean JNICALL Java_org_colimas_scm_vss_VSSOperator_checkin
(JNIEnv *env, jobject, jstring itemName, jstring localPath, jstring comment, jint flag)
{
     jboolean result=JNI_FALSE;
     if(pVdb==NULL)
       return result;
     IVSSItemPtr vssRootItem;
     const unsigned short * lpath=env->GetStringChars(itemName,0);
     const unsigned short * l_localPath=env->GetStringChars(localPath,0);
     const unsigned short * l_comment=env->GetStringChars(comment,0);
//获得Item实例
     if(pVdb->get_VSSItem(CComBSTR(lpath), FALSE, &vssRootItem)==S_OK)
     {
//checkin
       if(vssRootItem->Checkin(CComBSTR(l_comment),CComBSTR(l_localPath),flag)==S_OK)
       {
            result=JNI_TRUE;
       }else
       {
            AfxMessageBox("checked it in fail",MB_OK);
       }
     }

     return result;
}


3.2.9 undoCheckout实现

JNIEXPORT jboolean JNICALL Java_org_colimas_scm_vss_VSSOperator_undoCheckout
(JNIEnv *env, jobject, jstring itemName, jstring localPath, jint flag)
{
     jboolean result=JNI_FALSE;
     if(pVdb==NULL)
       return result;
     IVSSItemPtr vssRootItem;
     const unsigned short * lpath=env->GetStringChars(itemName,0);
     const unsigned short * l_localPath=env->GetStringChars(localPath,0);
//获得Item实例

     if(pVdb->get_VSSItem(CComBSTR(lpath), FALSE, &vssRootItem)==S_OK)
     {
//undo
       if(vssRootItem->UndoCheckout(CComBSTR(l_localPath),flag)==S_OK)
       {
            result=JNI_TRUE;
       }else
            AfxMessageBox("undochecked it out fail",MB_OK);
     }
     return result;
}


4.测试

VSS API用到一些Flag。我将他们定义到Java接口文件内。Flag的具体作为不做叙述。
package org.colimas.scm.vss;
/**
 *@authortyrone
 *
 */
publicinterface VSSFlag {
 publicintVSSFLAG_USERRONO = 1;
 publicintVSSFLAG_USERROYES = 2;
 publicintVSSFLAG_TIMENOW = 4;
 publicintVSSFLAG_TIMEMOD = 8;
 publicintVSSFLAG_TIMEUPD = 12;
 publicintVSSFLAG_EOLCR = 16;
 publicintVSSFLAG_EOLLF = 32;
 publicintVSSFLAG_EOLCRLF = 48;
 publicintVSSFLAG_REPASK = 64;
 publicintVSSFLAG_REPREPLACE = 128;
 publicintVSSFLAG_REPSKIP = 192;
 publicintVSSFLAG_REPMERGE = 256;
 /**
  *Specifiesafulltextcomparison.
   *UsethisflagwiththeCheckin,Get,orUndoCheckoutmethodstocomparethetextcontentsofthelocalcopyandtheSourceSafemastercopy.Ifthelocalcopyisup-to-date,SourceSafedoesnotreplaceitwiththemastercopy.
  */
 publicintVSSFLAG_CMPFULL = 512;
 /**
  *Specifiesatimestampcomparison.
   *UsethisflagwiththeCheckin,Get,orUndoCheckoutmethodstocomparedate/timestampofthelocalcopyandtheSourceSafemastercopy.Ifthelocalcopyisup-to-date,SourceSafedoesnotreplaceitwiththemastercopy.
  */
 publicintVSSFLAG_CMPTIME = 1024;
 publicintVSSFLAG_CMPCHKSUM = 1536;
 /**
  *Specifiesnocomparisonmechanism.
   *UsethisflagwiththeCheckin,Get,
   *orUndoCheckoutmethodstoalwaysreplacethelocalcopywiththeSourceSafemastercopy.
  */
 publicintVSSFLAG_CMPFAIL = 2048;
 /**
  *Indicatesthatacommandshouldnotberecursive(actonanentireprojecttree).Thisisthedefault.
  */
 publicintVSSFLAG_RECURSNO = 4096;
 /**
  *Indicatesthatacommandshouldberecursive(actonanentireprojecttree).
   *UsethisflagwiththeCheckin,Checkout,Get,orSharemethods.
  */
 publicintVSSFLAG_RECURSYES = 8192;
 /**
  *Usedtooverridetheworkingfolderspecifications.
  */
 publicintVSSFLAG_FORCEDIRNO = 16384;
 /**
  *Usedtomaintaintheworkingfoldersettings.Thisisthedefault.
  */
 publicintVSSFLAG_FORCEDIRYES = 32768;
 publicintVSSFLAG_KEEPNO = 65536;
 publicintVSSFLAG_KEEPYES = 131072;
 /**
  *Indicateswhetherthelocalcopyshouldbedeleted
  *afteranAdd,Checkin,orUndoCheckout.
  */
 publicintVSSFLAG_DELNO = 262144;
 /**
  *Indicatesthatthelocalcopyofafileisdeletedwhenitischeckedin.
  */
 publicintVSSFLAG_DELYES = 524288;
 /**
  *IndicatesthatthelocalcopyofafileisnotreplacedbyanUndoCheckoutoperation.
   *Whenthisflagisset,thelocalcopyisnotreplacedwiththeSourceSafemastercopyanditsread-onlyflagissettotrue.
  */
 publicintVSSFLAG_DELNOREPLACE = 786432;
 /**
  *IndicatesthatVisualSourceSafeauto-detectsthefiletodeterminewhetheritistextorbinary.
  */
 publicintVSSFLAG_BINTEST = 1048576;
 /**
  *Indicatesthatafileisbinary.
   *      Whenthisflagisset,SourceSafesetstheaddedfiletypetobinary.
  */
 publicintVSSFLAG_BINBINARY = 2097152;
 /**
  *Indicatesthatafileistext.
  */
 publicintVSSFLAG_BINTEXT = 3145728;
 /**
  *Indicatesthatanaddedfileretainsitshistoricalversions.
  */
 publicintVSSFLAG_DELTAYES = 4194304;
 /**
  *Indicatesthatanaddedfiledoesnotretainitshistoricalversions.
  */
 publicintVSSFLAG_DELTANO = 8388608;
 publicintVSSFLAG_UPDASK = 16777216;
 publicintVSSFLAG_UPDUPDATE = 33554432;
 publicintVSSFLAG_UPDUNCH = 50331648;
 /**
  *IndicatesthatthelocalcopyshouldbereplacedwiththeSourceSafemastercopyoncommandsthatdoanautomaticGet.
  */
 publicintVSSFLAG_GETYES = 67108864;
 /**
  *IndicatesthatthelocalcopyshouldnotbereplacedwiththeSourceSafemastercopyoncommandsthatdoanautomaticGet.
  */
 publicintVSSFLAG_GETNO = 134217728;

 /**
  *Indicatesthatacheckoutisexclusive.
  *SourceSafeallowsthefilestobecheckedoutbymorethanoneuser.
  */
 publicintVSSFLAG_CHKEXCLUSIVEYES = 268435456;
 /**
  *Indicatesthatacheckoutisnon-exclusive.Multiplecheckoutsareallowedwiththisoption.
  *SourceSafeallowsthefilestobecheckedoutbymorethanoneuser.
  */
 publicintVSSFLAG_CHKEXCLUSIVENO = 536870912;
 publicintVSSFLAG_HISTIGNOREFILES = 1073741824;
}

 

使用JUNIT编写测试用例如下:
package org.colimas.scm.vss;

import junit.framework.TestCase;

publicclass VSSOperatorTest extends TestCase {

  private VSSOperator op=new VSSOperator("D:/MyProject/colimas/ra/vssperator/debug/vssperator.dll");
  String path="c://vssdb//srcsafe.ini";
  String id="id";
  String pass="pass";
  String itemName="$/test";
  String localPath="d:/test/";
  publicvoid testGetFile() {
    assertEquals(op.connection(path, id, pass),true);
    assertEquals(op.getFile(itemName, localPath, 0),true);
    op.disconnection();
  }

  publicvoid testGetVersion() {
    assertEquals(op.connection(path, id, pass),true);
    assertEquals(op.getVersion("$/ImageConfirm/Main.bas", localPath, 14,0),true);
    op.disconnection();
  }

  publicvoid testCheckout() {
    assertEquals(op.connection(path, id, pass),true);
    assertEquals(op.checkout(itemName, localPath, "checkout",0),true);
    op.disconnection();
  }

  publicvoid testCheckin() {
    assertEquals(op.connection(path, id, pass),true);
    assertEquals(op.checkout(itemName, localPath, "checkout",0),true);
    op.disconnection();
    assertEquals(op.connection(path, id, pass),true);
    assertEquals(op.checkin(itemName, localPath, "checkout",0),true);
    op.disconnection();
  }

  publicvoid testUndoCheckout(){
    assertEquals(op.connection(path, id, pass),true);
    assertEquals(op.checkout(itemName, localPath, "checkout",0),true);
    op.disconnection();

    assertEquals(op.connection(path, id, pass),true);
    assertEquals(op.undoCheckout(itemName, localPath,0),true);
    op.disconnection();
  }
}

你可能感兴趣的:(vss)