关于校园通使用过程中的相关脚本


期末成绩查询

import requests
import pandas as pd
import json

studentcode_list = [] # 学号列表
my_url = "" # 地址
my_data = {"pageNum": "1", "pageSize": "13", "semesterID": "5", "examinationID": "-1"}
my_headers = {"Accept": "application/json, text/javascript, */*; q=0.01", 
			  "X-Requested-With": "XMLHttpRequest", 
			  "User-Agent": "Mozilla/5.0 (Linux; Android 10; V1914A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.101 Mobile Safari/537.36", 
			  "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 
			  "Accept-Encoding": "gzip, deflate", 
			  "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7"}
all_class_info = []
for stu_code in studentcode_list:
	my_cookies = {"studentCode": stu_code}
	resp = requests.post(url=my_url, headers=my_headers, cookies=my_cookies, data=my_data)
	resp_data = json.loads(resp.text)['data']['list']
	person_info = {'姓名': resp_data[0]['name']}
	for i in resp_data:
		person_info[i['itemName']] = i['score']
	all_class_info.append(person_info)
all_data_list = []
column_name = ['姓名', 'Linux网络操作系统', 'PHP编程+MySQL数据库', 'Python程序设计基础', '大学英语Ⅲ', '工程数学I', '形势与政策', '计算机组成原理', '马克思主义基本原理', '总分'] # 课程
all_data_list.append(column_name)
for per_data in all_class_info:
	per_data_list = []
	for col_key in column_name[:-1]:
		per_data_list.append(per_data[col_key])
	all_data_list.append(per_data_list)
df = pd.DataFrame(all_data_list)
df.to_excel('class.xlsx')

上课签到打卡自动化

需要校园通账号密码

# Python3
# Author: mochu7
import requests
import json
import datetime
import time

StudentAccount = [['张三', '账号', '密码'], ['李四', '账号', '密码'], ['王五', '账号', '密码']] # 校园通账号密码

def StudentLogin(StuId, StuPassword):
    login_url = "http://jxusptpay.com:80/StudentApp/Login/Login/StudentLogin"
    login_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0",
               "Accept": "application/json, text/javascript, */*; q=0.01",
               "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
               "Accept-Encoding": "gzip, deflate", "X-Requested-With": "XMLHttpRequest",
               "Content-Type": "multipart/form-data; boundary=---------------------------42502287411117441599485456745"}
    login_data = "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"student\"" \
                 "\r\n\r\n{}\r\n" \
                 "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"password\"" \
                 "\r\n\r\n{}\r\n" \
                 "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"platform\"" \
                 "\r\n\r\n1\r\n" \
                 "-----------------------------42502287411117441599485456745--\r\n".format(StuId, StuPassword)
    resp = session.post(url=login_url, headers=login_headers, data=login_data)
    resp_json = json.loads(resp.text)
    login_msg = resp_json['msg']
    print(resp.text)
    # print(resp.cookies)
    return login_msg, resp

def GetStuSign():
    SiginId = None
    GetStuSign_url = "http://www.jxusptpay.com:80/StudentApp/SignIn/StudentSignin/GetStudentSignIn"
    GetStuSign_headers = {"Accept": "application/json, text/javascript, */*; q=0.01",
                          "X-Requested-With": "XMLHttpRequest",
                          "User-Agent": "Mozilla/5.0 (Linux; Android 10; V1914A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.101 Mobile Safari/537.36",
                          "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryqzAkRL7L3HlcKLf7",
                          "Origin": "http://www.jxusptpay.com",
                          "Referer": "http://www.jxusptpay.com/StudentApp/SignIn/StudentSignin",
                          "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
                          "Connection": "close"}
    GetStuSign_data = "------WebKitFormBoundaryqzAkRL7L3HlcKLf7--\r\n"
    step1_resp = session.post(url=GetStuSign_url, headers=GetStuSign_headers, data=GetStuSign_data)
    # print(step1_resp.text)
    resp_json = json.loads(step1_resp.text)
    GetStuSign_msg = resp_json['msg']
    try:
        SiginId = resp_json['data']['id']
    except:
        pass
    return GetStuSign_msg, SiginId, step1_resp

def GpsSignIn(SiginId):
    GpsSignIn_url = "http://www.jxusptpay.com:80/StudentApp/SignIn/StudentSignin/GpsSignIn"
    GpsSignIn_headers = {"Accept": "application/json, text/javascript, */*; q=0.01",
                        "X-Requested-With": "XMLHttpRequest",
                        "User-Agent": "Mozilla/5.0 (Linux; Android 10; V1914A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.101 Mobile Safari/537.36",
                        "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundarypKKcS4ZECP9zCIJt",
                        "Origin": "http://www.jxusptpay.com",
                        "Referer": "http://www.jxusptpay.com/StudentApp/SignIn/StudentSignin",
                        "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
                        "Connection": "close"}
    GpsSignIn_data = "------WebKitFormBoundarypKKcS4ZECP9zCIJt\r\n" \
                    "Content-Disposition: form-data; name=\"signinId\"\r\n" \
                    "\r\n{}\r\n" \
                    "------WebKitFormBoundarypKKcS4ZECP9zCIJt\r\n" \
                    "Content-Disposition: form-data; name=\"itemId\"\r\n" \
                    "\r\n1\r\n" \
                    "------WebKitFormBoundarypKKcS4ZECP9zCIJt\r\n" \
                    "Content-Disposition: form-data; name=\"longitude\"\r\n" \
                    "\r\n115.82197462593913\r\n" \
                    "------WebKitFormBoundarypKKcS4ZECP9zCIJt\r\n" \
                    "Content-Disposition: form-data; name=\"latitude\"\r\n" \
                    "\r\n28.90447703508046\r\n" \
                    "------WebKitFormBoundarypKKcS4ZECP9zCIJt--\r\n".format(SiginId)
    step2_resp = session.post(url=GpsSignIn_url, headers=GpsSignIn_headers, data=GpsSignIn_data)
    print(step2_resp.text)

def FinalProcess(StuId, StuPassword):
    login_msg, resp = StudentLogin(StuId, StuPassword)
    if login_msg == "登入成功":
        GetStuSign_msg, SiginId, step1_resp = GetStuSign()
        if GetStuSign_msg == "操作成功":
            # 签到
            GpsSignIn(SiginId)
        else:
            print(step1_resp.text)
    elif login_msg == "登入服务器用户名或密码错误":
        print(login_msg)
    else:
        print(resp.text)


if __name__ == "__main__":
    start_time = datetime.datetime.now()
    print('\n[+] 脚本启动时间:{}'.format(start_time.strftime('%Y-%m-%d %H:%M:%S')))
    session = requests.session()
    for info in StudentAccount:
        name, username, password = info[0], info[1], info[2]
        print(name)
        FinalProcess(username, password)
        # time.sleep(60) # 五分钟内登录服务器次数不得超过5次
    end_time = datetime.datetime.now()
    print('[+] 脚本运行时间:{} 秒\n'.format((end_time-start_time).total_seconds()))

归寝签到打卡自动化

需要校园通账号密码

# Python3
# Author: mochu7
import requests
import json
import datetime
import time

StudentAccount = [['张三', '账号', '密码'], ['李四', '账号', '密码'], ['王五', '账号', '密码']] # 校园通账号密码

def StudentLogin(StuId, StuPassword):
    login_url = "http://jxusptpay.com:80/StudentApp/Login/Login/StudentLogin"
    login_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0",
               "Accept": "application/json, text/javascript, */*; q=0.01",
               "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
               "Accept-Encoding": "gzip, deflate", "X-Requested-With": "XMLHttpRequest",
               "Content-Type": "multipart/form-data; boundary=---------------------------42502287411117441599485456745"}
    login_data = "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"student\"" \
                 "\r\n\r\n{}\r\n" \
                 "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"password\"" \
                 "\r\n\r\n{}\r\n" \
                 "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"platform\"" \
                 "\r\n\r\n1\r\n" \
                 "-----------------------------42502287411117441599485456745--\r\n".format(StuId, StuPassword)
    resp = session.post(url=login_url, data=login_data, headers=login_headers)
    resp_json = json.loads(resp.text)
    login_msg = resp_json['msg']
    print(resp.text)
    # print(resp.cookies)
    return login_msg, resp

def GetDorMac():
    GetDorMac_msg = None
    DoorMac = None
    StuIsLogin_url = "https://www.jxusptpay.com/StudentApp/doorLock/openDoor/StudentIsSign"
    step1_resp = session.post(url=StuIsLogin_url)
    resp_json = json.loads(step1_resp.text)
    GetDorMac_msg = resp_json['msg']
    try:
        DoorMac = resp_json['data']['door']['doorBluetoothMac']
    except:
        pass
    return GetDorMac_msg, DoorMac, step1_resp

def GetToken():
    GetToken_msg = None
    ProveToken = None
    RelPerPro_url = "https://www.jxusptpay.com/StudentApp/doorLock/openDoor/RealPersonProving"
    step2_resp = session.post(url=RelPerPro_url)
    resp_json = json.loads(step2_resp.text)
    ProveToken = resp_json['data']['token']
    GetToken_msg = resp_json['msg']
    # ProveToken存在时效,时间较短,大概30秒左右
    return GetToken_msg, ProveToken, step2_resp

def Biopsy(ProveToken):
    Biopsy_msg = None
    RealId = None
    file_perfix = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
    Biopsy_url = "http://121.36.226.29:80/FaceRecognition/FaceRecognition/FaceRecognition/BiopsyToFile"
    Biopsy_headers = {"Accept": "application/json, text/javascript, */*; q=0.01",
                     "User-Agent": "Mozilla/5.0 (Linux; Android 10; V1914A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.101 Mobile Safari/537.36",
                     "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryyG2D8PGa3bWIwLdg",
                     "Origin": "http://www.jxusptpay.com", "X-Requested-With": "com.aheadedu.stuteams.stumanagement",
                     "Referer": "http://www.jxusptpay.com/StudentApp/doorLock/openDoor/dormitorySign",
                     "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
                     "Connection": "close"}
    Biopsy_data = "------WebKitFormBoundaryyG2D8PGa3bWIwLdg\r\n" \
                  "Content-Disposition: form-data; name=\"multipartFile\"; filename=\"{}.mp4\"\r\n" \
                  "Content-Type: video/mp4\r\n\r\n" \
                  "ftypmp42isimmp42...\x00\r\n" \
                  "------WebKitFormBoundaryyG2D8PGa3bWIwLdg\r\n" \
                  "Content-Disposition: form-data; name=\"token\"\r\n\r\n" \
                  "{}\r\n" \
                  "------WebKitFormBoundaryyG2D8PGa3bWIwLdg--\r\n".format(file_perfix, ProveToken)
    step3_resp = session.post(url=Biopsy_url, headers=Biopsy_headers, data=Biopsy_data, timeout=6)
    resp_json = json.loads(step3_resp.text)
    RealId = resp_json['data']['id']
    Biopsy_msg = resp_json['msg']
    return Biopsy_msg, RealId, step3_resp

def DorStuSign(DoorMac, RealId):
    StuSignin_url = "http://www.jxusptpay.com:80/StudentApp/doorLock/openDoor/StudentSign"
    StuSign_headers = {"Accept": "application/json, text/javascript, */*; q=0.01", "X-Requested-With": "XMLHttpRequest",
                     "User-Agent": "Mozilla/5.0 (Linux; Android 10; V1914A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/85.0.4183.101 Mobile Safari/537.36",
                     "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary9ENXVdDjergUgb4W",
                     "Origin": "http://www.jxusptpay.com",
                     "Referer": "http://www.jxusptpay.com/StudentApp/doorLock/openDoor/dormitorySign",
                     "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
                     "Connection": "close"}
    StuSign_data = "------WebKitFormBoundary9ENXVdDjergUgb4W\r\n" \
                   "Content-Disposition: form-data; name=\"signId\"\r\n" \
                   "\r\n1\r\n" \
                   "------WebKitFormBoundary9ENXVdDjergUgb4W\r\n" \
                   "Content-Disposition: form-data; name=\"realId\"\r\n" \
                   "\r\n{}\r\n" \
                   "------WebKitFormBoundary9ENXVdDjergUgb4W\r\n" \
                   "Content-Disposition: form-data; name=\"mac\"\r\n" \
                   "\r\n{}\r\n" \
                   "------WebKitFormBoundary9ENXVdDjergUgb4W--\r\n".format(RealId, DoorMac)
    resp4 = session.post(url=StuSignin_url, headers=StuSign_headers, data=StuSign_data)
    print(resp4.text)

def FinalProcess(StuId, StuPassword):
    login_msg, resp = StudentLogin(StuId, StuPassword)
    if login_msg == "登入成功":
        # 获取门锁MAc地址
        GetDorMac_msg, DoorMac, step1_resp = GetDorMac()
        if GetDorMac_msg == "当前无需签到":
            print(GetDorMac_msg)
        elif GetDorMac_msg == "当前时间段已签到":
            print(GetDorMac_msg)
        elif GetDorMac_msg == "操作成功":
            # 获取Token
            GetToken_msg, ProveToken, step2_resp = GetToken()
            if GetToken_msg == "操作成功":
                # 活体验证
                Biopsy_msg, RealId, step3_resp = Biopsy(ProveToken)
                if Biopsy_msg == "操作成功":
                    # 签到
                    DorStuSign(DoorMac, RealId)
                else:
                    # 活检错误处理,重复GetToken以及Biopsy步骤,直至操作成功
                    while True:
                        ProveToken = GetToken()[1]
                        Biopsy_msg, RealId, step3_resp = Biopsy(ProveToken)
                        if Biopsy_msg == "操作成功":
                            # 签到
                            DorStuSign(DoorMac, RealId)
                            break
            else:
                print(step2_resp.text)
        else:
            print(step1_resp.text)
    elif login_msg == "登入服务器用户名或密码错误":
        print(login_msg)
    else:
        print(resp.text)


if __name__ == "__main__":
    start_time = datetime.datetime.now()
    print('\n[+] 脚本启动时间:{}'.format(start_time.strftime('%Y-%m-%d %H:%M:%S')))
    session = requests.session()
    for info in StudentAccount:
        name, username, password = info[0], info[1], info[2]
        print(name)
        FinalProcess(username, password)
       # time.sleep(60) # 五分钟内登录服务器次数不得超过5次
    end_time = datetime.datetime.now()
    print('[+] 脚本运行时间:{} 秒\n'.format((end_time-start_time).total_seconds()))

Health Report Automatic

PS:某些词汇过不了CSDN审核,所以用英文

需要校园通账号密码

# Python3
# Author: mochu7
import requests
import random
import datetime
import json
import time

xxx_StudentAccount = [['xxx班-张三', '账号', '密码'], ['xxx班-李四', '账号', '密码'], ['xxx班-王五', '账号', '密码']] # 校园通账号密码
yyy_StudentAccount = [['yyy班-张三', '账号', '密码'], ['yyy班-李四', '账号', '密码'], ['yyy班-王五', '账号', '密码']]
Stu_dict = {"xxx":xxx_StudentAccount, "yyy":yyy_StudentAccount}
class_list = ["xxx", "yyy"]
# xxx yyy 为班号
#Temperature Range:36.2℃~37.2℃
Temperature_list = ['36.2', '36.3', '36.4', '36.5', '36.6', '36.7', '36.8', '36.9', '37.0', '37.1', '37.2']

def StudentLogin(StuId, StuPassword):
    login_url = "http://jxusptpay.com:80/StudentApp/Login/Login/StudentLogin"
    login_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:97.0) Gecko/20100101 Firefox/97.0",
               "Accept": "application/json, text/javascript, */*; q=0.01",
               "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
               "Accept-Encoding": "gzip, deflate", "X-Requested-With": "XMLHttpRequest",
               "Content-Type": "multipart/form-data; boundary=---------------------------42502287411117441599485456745"}
    login_data = "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"student\"" \
                 "\r\n\r\n{}\r\n" \
                 "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"password\"" \
                 "\r\n\r\n{}\r\n" \
                 "-----------------------------42502287411117441599485456745\r\n" \
                 "Content-Disposition: form-data; name=\"platform\"" \
                 "\r\n\r\n1\r\n" \
                 "-----------------------------42502287411117441599485456745--\r\n".format(StuId, StuPassword)
    login_resp = session.post(url=login_url, data=login_data, headers=login_headers)
    resp_json = json.loads(login_resp.text)
    login_msg = resp_json['msg']
    print(login_resp.text)
    # print(resp.cookies)
    return login_msg, login_resp

def GetVerifyCode():
    verify_url = "https://www.jxusptpay.com:443/SpReportData/reportdata/getVerifyCode"
    verify_resp = session.get(verify_url)
    resp_json = json.loads(verify_resp.text)
    verify_msg = resp_json['msg']
    VerifyCode = resp_json['data']
    return verify_msg, VerifyCode, verify_resp

def HealthReport(class_name, StuId, Temp, Current_date, VerifyCode):
    report_url = "https://www.jxusptpay.com:443/SpReportData/reportdata/report"
    report_data = {"studentCode":StuId,
                "classNo":class_name,
                "departmentCode":"02",
                "depName":"网络工程学院",
                "acaID":"1",
                "bodystatus":"正常",
                "animalHeat":None,
                "address":"江西软件职业技术大学",
                "isContactHubeiBack":"0",
                "isContactPatient":"0",
                "othercase":"无",
                "verifyCode": VerifyCode,
                "reporttime":Current_date,
                "morTem":Temp,
                "illsymptom":None,
                "quarantine":None,
                "quarantinePlace":None,
                "outStartTime":None,
                "outEndTime":None,
                "vehicle":None,
                "trainNumAndseatNum":None}
    resp = session.post(url=report_url, json=report_data)
    print(resp.text)

def FinalProcess(class_name, StuId, StuPassword):
    Temp = Temperature_list[random.randint(1, len(Temperature_list)) - 1]
    Current_date = datetime.datetime.now().strftime('%Y-%m-%d')
    login_msg, login_resp = StudentLogin(StuId, StuPassword)
    if login_msg == "登入成功":
        verify_msg, VerifyCode, verify_resp = GetVerifyCode()
        if verify_msg == "操作成功":
            HealthReport(class_name, StuId, Temp, Current_date, VerifyCode)
        else:
            print(verify_resp.text)
    else:
        print(login_resp.text)


if __name__ == "__main__":
    start_time = datetime.datetime.now()
    session = requests.session()
    print('\n[+] 脚本启动时间:{}'.format(start_time.strftime('%Y-%m-%d %H:%M:%S')))
    for class_name in class_list:
        for Stu in Stu_dict[class_name]:
            Stuname, StuId, StuPassword = Stu[0], Stu[1], Stu[2]
            print(Stuname)
            FinalProcess(class_name, StuId, StuPassword)
            # time.sleep(60) # 五分钟内登录服务器次数不得超过5次
    end_time = datetime.datetime.now()
    print('[+] 脚本运行时间:{} 秒\n'.format((end_time - start_time).total_seconds()))

设置服务器定时执行

利用Crontab即可

# 归寝签到,每天,时间范围:20:30-23:00
31 20 * * * /usr/bin/python /home/mochu7/Siginpy/DormitorySignin.py >> /home/mochu7/Siginpy/log/DormitorySigin.log
# 归寝签到日志定期清除,一周一次,每周星期天晚上23:30
30 23 * * 7 /usr/bin/echo "" > /home/mochu7/Siginpy/log/DormitorySigin.log

# 上课签到,周一至周五,时间范围:8:30-16:00
31 08 * * 1-5 /usr/bin/python /home/mochu7/Siginpy/ClassSignin.py >> /home/mochu7/Siginpy/log/ClassSigin.log
# 上课签到日志定期清除,一周一次,每周星期五晚上23:00
00 23 * * 5 /usr/bin/echo "" > /home/mochu7/Siginpy/log/ClassSigin.log

# Health Report,每天,一天打一次,早上7:00
00 07 * * * /usr/bin/python /home/mochu7/Siginpy/HealthReport.py >> /home/mochu7/Siginpy/log/HealthReport.log
# Health Report日志定期清除,一周一次,每周星期天晚上23:00
00 23 * * 7 /usr/bin/echo "" > /home/mochu7/Siginpy/log/HealthReport.log
笔者有幸接触过以下几种常用配置管理工具:VSS、SVN、Clearcase,在此做一个小小总结,并Ctrl+C了以前一些网友对比评论,不一定准确,只是希望过这些总结对自己和初学者有所帮助。如果想进一步了解这些工具,请baidu和google,如果想深入了解,敬请到图书馆借书并实践。一、 Visual Source Safe( 简称 VSS )VSS是微软产品,是配置管理一种很好入门级工具。VSS最初名字叫Source Safe,是一家小公司产品,92年曾经获了最佳小型管理工具奖,然后立即被微软收购。但是微软收购只是source safeWindows版本,在美国还有另外两家公司分别获得了继续开发和销售source safeMac版本和Unix版本许可,在MS买进vss之后,基本上没有对vss进行任何研发,MS内部自身也不用vss。SourceSafe长得很象早先土气文件管理器,确难看。但是难看不碍事,SourceSafe优点可以用8个字来概括“简单易用,一学就会”,这个优点是它老妈Microsoft遗传下来,是天生。虽然SourceSafe并不是免费,但是在国内人们以接近于零成本得到它,网上到处可以下载啊。当然Microsoft也不在乎这个小不点软件,它属于“买大件送小件”角色。如果你合法地得到Visual Studio,你就得到了免费SourceSafe。评价如下:易用性:★★★★★易学易用是 VSS 强项, VSS 采用标准 windows 操作界面,只要对微软产品熟悉,就能很快上手。 VSS 安装和配置非常简单,对于该产品,不需要外部培训(可以为公司省去一笔不菲费用)。只要参考微软完备随机文档,就可以很快用到实际工程当。功能:★★★VSS 配置管理功能比较基本,提供文件版本跟踪功能,对于 build 和基线管理, VSS 打标签功能可以提供支持。 VSS 提供 share (共享 ) 、 branch( 分支)和合并( merge) 功能,对于团队开发进行支持。 VSS 不提供对流程管理功能,如对变更流程进行控制。 VSS 不能提供对异地团队开发支持。此外 VSS 只能在 windows 平台上运行,不能运行在其他操作系统上。安全性:★★★VSS 安全性不高,对于 VSS 用户,可以在文件夹上设置不可读,可读,可读 / 写 , 可完全控制四级权限。但由于 VSS 文件夹是要完全共享给用户后,用户才能进入,所以用户对 VSS 文件夹都可以删除。这一点也是 VSS 一个比较大缺点。总体成本:★★★★VSS 没有采用对许可证进行收费方式,只要安装了 VSS ,对用户数目是没有限制。因此使用 VSS 费用是较低。技术支持:★★★★★由于 VSS 是微软产品,可以得到稳定技术支持。二、 SVN(Subversion) - CVS(Concurrent Version System)替代和升级版本先说说CVS,CVS是开源代码配置管理工具,其源代码和安装文件都可以免费下载。记得在学校读研时候,学校实验室代码全部都用CVS管理,为啥?很简单,两个字:免费!它与Eclipse配合,基本上Java代码编写,代码管理和版本管理都可以“免费”搞定了。SVN(Subversion)是近年来崛起版本管理工具,被誉为cvs接班人。目前,绝大多数开源软件都使用svn作为代码版本管理软件。虽然在 2006年时SVN使用族群仍然远少于传统CVS,但已经有许多开放源码团体决定将CVS转换为SVN。已经转换使用SVN包括了 FreeBSD、Apache Software Foundation、KDE、GNOME、GCC、Python、Samba、Mono 以及许多团体。许多开发团队换用SVN是因为 Trac、SourceForge、CollabNet、CodeBeamer等专案协同作业软件以及Eclipse、NetBeans等IDE提供SVN支援整合。 除此之外,一些自由软件开发协作网如SourceForge.net除了提供CVS外,现在也提供专案开发者使用SVN作为原码管理系统,JavaForge、Google Code以及 BountySource 则以SVN作为官方源码管理系统。2009年,绝大多数CVS服务已经改用SVN。CVS已经停止维护。易用性 : ★★★★Subversion支持linux和windows,更多是安装在linux下。svn服务器有2种运行方式:独立服务器和借助apache。2种方式各有利弊。目前业界评价SVN易用性正在提高。功能:★★★★SVN 功能除具备 VSS 功能外,还具有:它客户机 / 服务器存取方法使得开发者可以从任何因特网接入点存取最新代码;它无限制版本管理检出 (checkout :注 1)模式避免了因为排它检出模式而引起人工冲突;它客户端工具可以在绝大多数平台上使用。同样, SVN 也不提供对变更流程自动管理功能。安全性:★★★★一般来说, SVN 权限设置单一,无法完成复杂权限控制;但是 SVN 过 SVN ROOT 目录下脚本,提供了相应功能扩充接口,不但可以完成精细权限控制,还能完成更加个性化功能。总体成本:★★★★★SVN 是开发源码软件,无需支付购买费用。技术支持:★★★同样因为 SVN 是开发源码软件,没有生产厂家为其提供技术支持。如发现问题,常只能靠自己查找网上资料进行解决。三、 ClearCaseRational公司ClearCase是软件行业公认功能最强大、价格最昂贵配置管理软件。ClearCase主要应用于复杂产品并行开发、发布和维护,其功能划分为四个范畴:版本控制、工作空间管理(Workspace Management)、构造管理(Build Management)、过程控制(Process Control)。ClearCase过TCP/IP来连接客户端和服务器。另外,ClearCase拥有浮动License可以跨越UNIX和 Windows NT平台被共享。ClearCase功能比CVS、SourceSafe强大得多,但是其用户量却远不如CVS、SourceSafe多。主要原因是:ClearCase价格昂贵,如果没有批量折扣话,每个License大约5000美元。对于国用户而言,这无疑是天价。用户只有经过几天培训后(费用同样很昂贵),才能正常使用ClearCase。如果不参加培训话,用户基本上不可能无师自。易用性:★★★ClearCase 安装和维护远比 VSS 复杂,要成为一个合格 ClearCase 系统管理员,需要接收专门培训。 ClearCase 提供命令行和图形界面操作方式,但从 ClearCase 图形界面不能实现命令行所有功能。如果Unix/Linux服务器上安装了Samba服务,可以直接过Windows下Clearcase客户端直接访问源代码,相对比较简单。功能:★★★★★ClearCase 提供 VSS, SVN所支持功能,但不提供变更管理功能。 Rational 另提供了 ClearQuest 工具提供对变更管理功能,与 VSS不同, ClearCase 后台数据库是专有结构。 ClearCase 对于 windows 和 unix 平台都提供支持。 ClearCase 过多点复制支持多个服务器和多个点可扩展性,并擅长设置复杂开发过程。安全性:★★★★ClearCase 权限设置功能与 SVN 相比, SVN 有独立安全管理机制, ClearCase 没有专用安全性管理机制,依赖于操作系统。总体成本:★★要选用 ClearCase ,需要考虑费用除购买 license 费用外,还有必不可少技术服务费用,没有 Rational 公司专门技术服务,很难发挥出 ClearCase 威力。如现在网上虽有 ClearCase 破解软件,但尝试应用公司大多失败缘故。另外,对于 web 访问支持,对于变更管理支持功能都要另行购买相应软件。技术支持:★★★★★Rational 公司已被 IBM 公司收购,所以有可靠售后服务保证。四、总结工具对比一览表特性 VSS SVN ClearCase易用性 ★★★★ ★★★ ★★★功能 ★★★ ★★★★ ★★★★★安全性 ★★★ ★★★★ ★★★★总体成本 ★★★★ ★★ ★★★★★技术支持 ★★★★ ★★★ ★★★★★以上几种工具总结如下: 1. VSS 使用简便易学,但 VSS 功能和安全性较弱,且只对 windows 平台进行支持,建议作为项目配置管理入门时采用工具;2. SVN 安全性和版本管理功能较强,可以实现异地开发支持,但 SVN 安装和使用多采用命令行方式,学习曲线高,同时不提供对变更管理功能,对于小型团队,可以采用 SVN 进行管理。3. ClearCase 功能完善,安全性好,可以支持复杂管理,但学习曲线和学习成本高,需要集成 ClearQuest 才能完成完整配置管理功能。大公司如果采用异地多研发心同时开发模式,一般推荐使用ClearCase。
参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:博客之星2021 设计师:Hiro_C 返回首页

打赏作者

末 初

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值