如何写批处理文件

1.Strong-name verfication:  (Sn.) 

http://www.cnblogs.com/winston/archive/2008/04/23/1026489.html

主要是 用来解决DLL Hell的问题。

2. echo

直接用echo表示显示此命令后的字符
echo off
表示在此语句后所有运行的命令都不显示命令行本身

@
echo off相象,但它是加在每个命令行的最前面,表示运行时不显示这一行的命令行(只能影响当前行)。

3. call

调用另一个批处理文件(如果不用call而直接调用别的批处理文件,那么执行完那个批处理文件后将无法返回当前文件并执行当前文件的后续命令)。
4. Pause

 运行此句会暂停批处理的执行并在屏幕上显示Press any key to continue...的提示,等待用户按任意键后继续
5. rem

表示此命令后的字符为解释行(注释),不执行,只是给自己今后参考用的(相当于程序中的注释)。

Rem ::等效

6Parameters

批处理文件还可以像C语言的函数一样使用参数(相当于DOS命令的命令行参数),这需要用到一个参数表示符“%”

  %[1-9]表示参数,参数是指在运行批处理文件时在文件名后加的以空格(或者Tab)分隔的字符串。变量可以从%0%9%0表示批处理命令本身,其它参数字符串用%1%9顺序表示。

7ERRORLEVER

Usage: if errorlevel <数字> 待执行的命令

很多DOS程序在运行结束后会返回一个数字值用来表示程序运行的结果(或者状态),通过if errorlevel命令可以判断程序的返回值,根据不同的返回值来决定执行不同的命令(返回值必须按照从大到小的顺序排列)。如果返回值等于指定的数字,则条件成立,运行命令,否则运行下一句。

8.Choice

choice 使用此命令可以让用户输入一个字符(用于选择),从而根据用户的选择返回不同的errorlevel,然后于if errorlevel配合,根据用户的选择运行不同的命令。

注意:choice命令为DOS或者Windows系统提供的外部命令,不同版本的choice命令语法会稍有不同,请用choice /?查看用法。

choice
的命令语法:

CHOICE [/C choices] [/N] [/CS] [/T timeout /D choice] [/M text]

描述:
该工具允许用户从选择列表选择一个项目并返回所选项目的索引。

参数列表:
/C choices
指定要创建的选项列表。默认列表是 "YN"
/N
在提示符中隐藏选项列表。提示前面的消息得到显示,
选项依旧处于启用状态。
/CS
允许选择分大小写的选项。在默认情况下,这个工具
是不分大小写的。
/T timeout
做出默认选择之前,暂停的秒数。可接受的值是从 0
9999。如果指定了 0,就不会有暂停,默认选项

会得到选择。
/D choice
nnnn 秒之后指定默认选项。字符必须在用 /C
项指定的一组选择中; 同时,必须用 /T 指定 nnnn
/M text
指定提示之前要显示的消息。如果没有指定,工具只
显示提示。

注意:
ERRORLEVEL
环境变量被设置为从选择集选择的键索引。列出的第一个选
择返回 1,第二个选择返回 2,等等。如果用户按的键不是有效的选择,
该工具会发出警告响声。如果该工具检测到错误状态,它会返回 255
ERRORLEVEL
值。如果用户按 Ctrl+Break Ctrl+C 键,该工具会返回 0
ERRORLEVEL 值。在一个批程序中使用 ERRORLEVEL 参数时,将参数降

序排列。

示例:
CHOICE /?
CHOICE /C YNC /M "
确认请按 Y,否请按 N,或者取消请按 C"
CHOICE /T 10 /C ync /CS /D y
CHOICE /C ab /M "
选项 1 请选择 a,选项 2 请选择 b
"
CHOICE /C ab /N /M "
选项 1 请选择 a,选项 2 请选择 b
"

如果我运行命令:CHOICE /C YNC /M "确认请按 Y,否请按 N,或者取消请按 C
"
屏幕上会显示:

确认请按 Y,否请按 N,或者取消请按 C [Y,N,C]?

例:test.bat的内容如下(注意,用if errorlevel判断返回值时,要按返回值从高到低排列)
:
@echo off
choice /C dme /M "defrag,mem,end"
if errorlevel 3 goto end
if errorlevel 2 goto mem
if errotlevel 1 goto defrag

9 For Command

只要条件符合,它将多次执行同一命令。

语法:

对一组文件中的每一个文件执行某个特定命令。

FOR %%variable IN (set) DO command [command-parameters]

%%variable
指定一个单一字母可替换的参数。
(set)
指定一个或一组文件。可以使用通配符。
command
指定对每个文件执行的命令。
command-parameters
为特定命令指定参数或命令行开关。

例如一个批处理文件中有一行:
for %%c in (*.bat *.txt) do type %%c

则该命令行会显示当前目录下所有以battxt为扩展名的文件的内容。

10. IF

1. IF-EXIST
首先用记事本在C:/建立一个test1.bat批处理文件,文件内容如下:

Eg 1.

@echo off
IF EXIST /AUTOEXEC.BAT TYPE /AUTOEXEC.BAT
IF NOT EXIST /AUTOEXEC.BAT ECHO /AUTOEXEC.BAT does not exist
然后运行它:

C:/>TEST1.BAT

如果C:/存在AUTOEXEC.BAT文件,那么它的内容就会被显示出来,如果不存在,批处理就会提示你该文件不存在。
Eg 2.
接着再建立一个test2.bat文件,内容如下:
@ECHO OFF
IF EXIST /%1 TYPE /%1
IF NOT EXIST /%1 ECHO /%1 does not exist

执行
:
C:/>TEST2 AUTOEXEC.BAT
该命令运行结果同上。


说明:
(1) IF EXIST
是用来测试文件是否存在的,格式为

IF EXIST [
路径+文件名] 命令

(2) test2.bat
文件中的%1是参数,DOS允许传递9个批参数信息给批处理文件,分别为%1~%9(%0表示test2命令本身) ,这有点象编程中的实参和形参的关系,%1是形参,AUTOEXEC.BAT是实参。


3)
更进一步的,建立一个名为TEST3.BAT的文件,内容如下:

@echo off
IF "%1" == "A" ECHO XIAO
IF "%2" == "B" ECHO TIAN
IF "%3" == "C" ECHO XIN

如果运行:

C:/>TEST3 A B C
屏幕上会显示:
XIAO
TIAN
XIN

如果运行:

C:/>TEST3 A B
屏幕上会显示
XIAO
TIAN

在这个命令执行过程中,DOS会将一个空字符串指定给参数%3

2IF-ERRORLEVEL

建立TEST4.BAT,内容如下:
@ECHO OFF
XCOPY C:/AUTOEXEC.BAT D:

IF ERRORLEVEL 1 ECHO 文件拷贝失败
IF ERRORLEVEL 0 ECHO
成功拷贝文件


然后执行文件
:
C:/>TEST4

如果文件拷贝成功,屏幕就会显示成功拷贝文件,否则就会显示文件拷贝失败


IF ERRORLEVEL
是用来测试它的上一个DOS命令的返回值的,注意只是上一个命令的返回值,而且返回值必须依照从大到小次序顺序判断。
因此下面的批处理文件是错误的:
@ECHO OFF
XCOPY C:/AUTOEXEC.BAT D:/
IF ERRORLEVEL 0 ECHO
成功拷贝文件

IF ERRORLEVEL 1 ECHO
未找到拷贝文件

IF ERRORLEVEL 2 ECHO
用户通过ctrl-c中止拷贝操作

IF ERRORLEVEL 3 ECHO
预置错误阻止文件拷贝操作

IF ERRORLEVEL 4 ECHO
拷贝过程中写盘错误


无论拷贝是否成功,后面的:

未找到拷贝文件

用户通过ctrl-c中止拷贝操作

预置错误阻止文件拷贝操作

拷贝过程中写盘错误
都将显示出来。

有点类似于其他语言中的 switch 不加 break的情况。

以下就是几个常用命令的返回值及其代表的意义:

backup
0
备份成功

1
未找到备份文件

2
文件共享冲突阻止备份完成

3
用户用ctrl-c中止备份

4
由于致命的错误使备份操作中止


diskcomp
0
盘比较相同

1
盘比较不同

2
用户通过ctrl-c中止比较操作

3
由于致命的错误使比较操作中止

4
预置错误中止比较


diskcopy
0
盘拷贝操作成功

1
非致命盘读/写错

2
用户通过ctrl-c结束拷贝操作

3
因致命的处理错误使盘拷贝中止

4
预置错误阻止拷贝操作


format
0
格式化成功

3
用户通过ctrl-c中止格式化处理

4
因致命的处理错误使格式化中止

5
在提示“proceed with formaty/n?”下用户键入n结束


xcopy
0
成功拷贝文件

1
未找到拷贝文件

2
用户通过ctrl-c中止拷贝操作

4
预置错误阻止文件拷贝操作

5
拷贝过程中写盘错误


3
IF STRING1 == STRING2

建立TEST5.BAT,文件内容如下:

@echo off
IF "%1" == "A" FORMAT A:

执行:

C:/>TEST5 A
屏幕上就出现是否将A:盘格式化的内容。


注意:为了防止参数为空的情况,一般会将字符串用双引号(或者其它符号,注意不能使用保留符号)括起来。
如:if [%1]==[A] 或者 if %1*==A*

11 GOTO

建立TEST6.BAT,文件内容如下:
@ECHO OFF
IF EXIST C:/AUTOEXEC.BAT GOTO _COPY
GOTO _DONE
:_COPY
COPY C:/AUTOEXEC.BAT D:/
:_DONE

注意:

(1)
标号前是ASCII字符的冒号":",冒号与标号之间不能有空格。

(2)
标号的命名规则与文件名的命名规则相同。

(3) DOS
支持最长八位字符的标号,当无法区别两个标号时,将跳转至最近的一个标号。

 

附上一个实例:(主要作用是注册pilot 或者client) 保存为Register.bat, 命令行运行命令为:(Register.bat /Pilot /Client /Cleanup)或(Register.bat /Pilot)或(Register.bat /Client)

@echo off
REM Register.bat - registers or unregisters SUS 2.0 Client Test Binaries

set _CLEANUP=0
set _CLIENT=0
set _PILOT=0
set _DEFAULT=1
set _VISTA=0
set _VISTA_OR_GREATER=0
set _Win2K=0
set _LEGACY_OS=0
set _STRESS=0
set _NOFWRESET=

REM GET THE LATEST VERSION OF REGASM.EXE

if /I "%PROCESSOR_ARCHITECTURE%"=="x86" (
for /f %%i in ('dir /s /b /on %windir%/microsoft.net/framework/regasm.exe') do set _REGASMEXE=%%i
)
if /I "%PROCESSOR_ARCHITECTURE%"=="amd64" (
for /f %%i in ('dir /s /b /on %windir%/microsoft.net/framework64/regasm.exe') do set _REGASMEXE=%%i
)
if /I "%PROCESSOR_ARCHITECTURE%"=="ia64" (
for /f %%i in ('dir /s /b /on %windir%/microsoft.net/framework64/regasm.exe') do set _REGASMEXE=%%i
)

echo We will use %_REGASMEXE%

REM DETERMINE IF OS IS VISTA
ver | find "6.0" > NUL
if "%ERRORLEVEL%" == "0" set _VISTA=1

REM DETERMINE IF OS IS VISTA OR GREATER
ver | find "6." > NUL
if "%ERRORLEVEL%" == "0" set _VISTA_OR_GREATER=1

REM DETERMIN IF OS IS LEGACY (XP, W2K3, W2K)
ver | find "5." > NUL
if "%ERRORLEVEL%" == "0" set _LEGACY_OS=1

REM DETERMINE IF OS IS W2K
ver | find "5.0" > NUL
if "%ERRORLEVEL%" == "0" set _Win2K=1

:ARGUMENTLOOP
if /I "%1"=="" goto REGISTER
if /I "%1"=="/client" set _CLIENT=1&set _DEFAULT=0
if /I "%1"=="/pilot" set _PILOT=1&set _DEFAULT=0
if /I "%1"=="/stress" set _STRESS=1&set _DEFAULT=0
if /I "%1"=="/cleanup" set _CLEANUP=1
if /I "%1"=="/NoFWReset" set _NOFWRESET=%1
shift                                         Rem注, 这个命令是用来挨个解析输入的参数的
goto ARGUMENTLOOP

:REGISTER

if "%_DEFAULT%"=="1" set _CLIENT=0&set _PILOT=1

if "%_CLEANUP%"=="1" (
   echo.
   echo Unregistering binaries...
   set _EXE_SWITCH=/unregserver
   set _DLL_SWITCH=/u /s
   set _REGASM_SWITCH=/unregister

   if "%_CLIENT%"=="1" (
      echo    Cleanup eventer hook dll
      del %SYSTEMROOT%/System32/EventerHook.dll
   )

   if exist %windir%/TestCleanup.bat (
          echo Deleting TestCleanup.bat from %windir%
          del %windir%/TestCleanup.bat /f /q
   )
) else (
   echo.
   echo Registering binaries...
   set _EXE_SWITCH=/regserver
   set _DLL_SWITCH=/s
   set _REGASM_SWITCH=

   echo    Copy WTT logger to windows dir
   REM Force the copy so that we don't get version mismatches.
   xcopy /q /y WTTLog.* %SYSTEMROOT%/System32
  
   REM Copy to %windir% so that this can be executed remotely from pilot
   REM without resolving any path. Doing the same thing in pilot for consistency.
   if exist TestCleanup.bat (
      echo Copying TestCleanup.bat to %windir%
      copy TestCleanup.bat %windir% /y
   )

   if "%_CLIENT%"=="1" (
rem      echo    Copy wuauclt_spoof.exe to windows dir
rem      xcopy /d /q /y wuauclt_spoof.exe %SYSTEMROOT%/System32

      if exist EventerHook.dll (
         echo    Copy eventer hook dll
         xcopy /d /q /y EventerHook.dll %SYSTEMROOT%/System32
      )

      if exist mucltui.dll (
         echo Copying mu related binaries
         xcopy /d /q /y mucltui.dll %SYSTEMROOT%/System32
      )

      if exist muweb.dll (
         echo Copying mu related binaries
         xcopy /d /q /y muweb.dll %SYSTEMROOT%/System32
      )

      if not exist %windir%/system32/msvcp60.dll xcopy /d /q /y W2KBins .

      if not "%PROCESSOR_ARCHITECTURE%"=="x86" (
         xcopy /q /y x86logger %SYSTEMROOT%/SysWow64
         xcopy /q /y x86MU %SYSTEMROOT%/SysWow64
      )
   )
)

if "%_STRESS%"=="1" (
    call :STRESS_REGISTRATION
    goto END
)

call :COMMON_REGISTRATION
if "%_PILOT%"=="1" call :PILOT_REGISTRATION
if "%_CLIENT%"=="1" call :CLIENT_REGISTRATION
goto END

:COMMON_REGISTRATION
echo    Client-side Utilities
call :DODLL ClientSideSrv.dll
call :DODLL SUSClientSide.dll

echo    Object Creator
call :DOEXE ObjectCreator.exe

echo    API Wrappers
call :DODLL COMWrappersLib.dll

echo    Data Store Helper
call :DODLL DataStoreHelper.dll

echo    Update Handler Helpers
call :DODLL MSIHandler.dll
call :DODLL CBSHandler.dll

echo    MUI Helpers
call :DODLL MUIHelper.dll

echo    API Script Framework Pilot and Client
call :DODLL SF_ScriptLauncher.dll

call :DODLL ObjectCreatorps.dll
call :DODLL TestServiceps.dll
call :DODLL DevAPICreatorServiceps.dll
call :DODLL CTAUClientps.dll
call :DODLL ReporterAPIWrapper.dll
call :DODLL ReporterLogParser.dll
call :DODLL DriverHandler.dll
call :DODLL Infhelper.dll
call :DODLL SUS_ELH.dll
call :DODLL LogonPxy.dll
call :DODLL SF_PilotTrnsltrps.dll
call :DODLL appexpreval.dll
call :DODLL InstallAtShutdown.dll
call :DODLL CrimsonEventParser.dll

if "%_VISTA%"=="1" (
  @echo.
  echo Vista. Copying MITA privates ...
  call :MITA_PRIVATES
)

if "%_LEGACY_OS%"=="1" (
  @echo.
  echo Legacy OS. Copying MITA privates ...
  call :MITA_PRIVATES
)

if not "%_CLEANUP%"=="1" (
   echo Turning off Strong-Name verification for Server test/Site dev binaries
   for /f %%i in ('dir /s /b *.dll') do sn.exe -Vr %%i >NUL
   for /f %%i in ('dir /s /b *.exe') do sn.exe -Vr %%i >NUL
) else (
   echo Resetting strong-Name verification for Server test/Site dev binaries
   sn -Vx
)

call :MODIFYFIREWALL

goto :EOF

:MITA_PRIVATES

REM If Win7, we already have all the right MITA binaries. If Vista or lower, we need to replace the testdriver.exe.config and ctauuidriver.exe
REM with the one compiled against MITA 6.0. Also, for legacy OS (XP,etc) we need to copy privates since OSBINROOT won't have anything.

if not "%_CLEANUP%"=="1" (

  ren TestDriver.exe.config TestDriver_Win7.exe.config
  ren TestDriver_DL.exe.config TestDriver.exe.config
 
  ren CTAUUIDriver.dll CTAUUIDriver_Win7.dll
  xcopy Downlevel/CTAUUIDriver.dll . /y
 
  if not exist mita.foundation.dll (
      @echo.
      echo MITA binaries are missing. Probably no OSBINROOT has been provided or this is legacy OS. Copying privates ...
      xcopy Mita_Privates/Vista/* . /y
  )
)

goto :EOF

:MODIFYFIREWALL
echo    Modifying Firewall
if not exist "fw.wsf" goto FIREWALLERROR
if not exist "punchholes.cmd" goto FIREWALLERROR
call punchholes.cmd %_CLEANUP% %_NOFWRESET%

goto :EOF

:PILOT_REGISTRATION
echo    Environment Variables
if "1"=="%_CLEANUP%" (
   if exist SetEnv.exe ( SetEnv SUSCTDataFiles /delete )
   set SUSCTDataFiles=
) else (
   if exist SetEnv.exe ( SetEnv SUSCTDataFiles %CD% )
   set SUSCTDataFiles=%CD%
)

echo    LUAUtility
call :DODLL LuaUtility.dll

echo    Session Management
call :DODLL tclient.dll
call :DODLL clxtshar.dll
call :DODLL SessionServer.dll

echo    API Script Framework Pilot Only
call :DOEXE SF_PilotTrnsltr.exe
call :DoRegASm SF_IPCCaller.dll

goto :EOF

:CLIENT_REGISTRATION
if "%_Win2K%"=="1" (
    echo register Wbemdisp on W2K
    net stop winmgmt
    if "0"=="%_CLEANUP%" (
      regsvr32 /u /s %windir%/System32/Wbem/Wbemdisp.dll
      call :DODLL W2KBins/Wbemdisp.dll
    ) else (
      regsvr32 /u /s W2KBins/Wbemdisp.dll
      call :DODLL %windir%/System32/Wbem/Wbemdisp.dll
    )
    net start winmgmt

    echo copy sc.exe to %windir%/system32
    copy /y W2KBins/sc.exe %windir%/System32/sc.exe
)

echo    Environment Variables

if "%_VISTA_OR_GREATER%"=="1" (
    leasvc -remove >NUL
    regsvr32 /u /s xAcc.dll
)

if "1"=="%_CLEANUP%" (
   SetEnv SUSCTDataFiles /delete
   set SUSCTDataFiles=

   if "%_VISTA_OR_GREATER%"=="1" (
       reg DELETE HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/Policies/System /v LocalAccountTokenFilterPolicy /f
       del /q %SYSTEMROOT%/objectcreator.exe >NUL
   )
) else (
   SetEnv SUSCTDataFiles %CD%
   set SUSCTDataFiles=%CD%

   if "%_VISTA_OR_GREATER%"=="1" (
    echo    LUAUtility
    call :DODLL LuaUtility.dll

       echo    Installing the LEA service...
       leasvc -install
       regsvr32 /s xAcc.dll

       REM we don't need this on one machine testing
       if NOT "%_PILOT%"=="1" (
            reg add HKLM/SOFTWARE/Microsoft/Windows/CurrentVersion/Policies/System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
       )
       xcopy /d /q /y objectcreator.exe %SYSTEMROOT% >NUL

       REM for SCE only. If vista, we should use UIAutomationCore.dll in system32 and ignore the one we copied to test folder
       del /q UIAutomationCore.dll >NUL
   )

   REM change network logon policy to "classic" for non-Vista
   if NOT "%_VISTA_OR_GREATER%"=="1" (
        REM we don't need this on one machine testing
        if NOT "%_PILOT%"=="1" (
            reg add HKLM/SYSTEM/CurrentControlSet/Control/Lsa /v forceguest /t REG_DWORD /d 0 /f
            reg add HKLM/SYSTEM/ControlSet001/Control/Lsa /v forceguest /t REG_DWORD /d 0 /f
        )
   )
)

if not exist %windir%/softwaredistribution md %windir%/softwaredistribution
copy /y autest.cab %windir%/softwaredistribution

echo    Test Service
call :REGSERVICE TestService TestService

echo    Logon Driver
if "%_Win2K%"=="1" (
  call :REGSERVICE W2KBins/LogonSrv LogonDriver
) else (
  call :REGSERVICE LogonSrv LogonDriver
)

echo    DevAPICreator Service
call :REGSERVICE DevAPICreatorService DevAPICreatorService

echo    AU Wrappers
call :DOEXE CTAUClient.exe

echo    API Script Framework Client Only
call :DODLL SF_PilotCallerps.dll
call :DOEXE SF_PilotCaller.exe

echo    WebRunner
call :DODLL ScreenShots.dll
call :DODLL Getdom.dll

echo    Registering MUCLTUI.DLL
call :DODLL mucltui.dll
call :DODLL muweb.dll
if not "%PROCESSOR_ARCHITECTURE%"=="x86" call :DOX86DLL mucltui.dll
if not "%PROCESSOR_ARCHITECTURE%"=="x86" call :DOX86DLL muweb.dll

echo    Registering NEWTWrapper.DLL
call :DODLL NEWTWrapper.dll

echo    Registering SQMUtil
call :DODLL SqmUtil.dll

echo    Add Microsft Trusted PCA certificate into trusted publisher store (For driver)
call    certmgr.exe -add trustedpca.cer -s TrustedPublisher -r LocalMachine
call    certmgr.exe -add msrootca.cer -s root -r LocalMachine -all
call    certmgr.exe -add mscspca.cer -s TrustedPublisher -r LocalMachine -all
call    certmgr.exe -add drivertest.cer -s TrustedPublisher -r LocalMachine -all

goto :EOF

:STRESS_REGISTRATION
call :DODLL ClientSideSrv.dll
call :DODLL RPFMSAAPlayback.dll

if not "%_CLEANUP%"=="1" (
   echo Turning off Strong-Name verification for Server test/Site dev binaries
   for /f %%i in ('dir /s /b *.dll') do sn.exe -Vr %%i >NUL
)

goto :EOF

:FIREWALLERROR
echo CAN NOT MODIFY FIREWALL!!!!!!
echo Either fw.wsf or punchholes.cmd is missing which will prevent tests from getting through firewall.
goto :EOF

:DODLL
regsvr32 %_DLL_SWITCH% %1
goto :EOF

:DOX86DLL
%windir%/SysWow64/regsvr32 %_DLL_SWITCH% %1
goto :EOF

:DORegAsm
%_REGASMEXE% %_REGASM_SWITCH% %1
goto :EOF

:DOEXE
%1 %_EXE_SWITCH%
goto :EOF

REM Args are <Service binary to register> <Service name>
:REGSERVICE
if "1"=="%_CLEANUP%" (
   net stop %2
   sc delete %2
) else (
   %1.exe -service
)
goto :EOF

:END
set _EXE_SWITCH=
set _DLL_SWITCH=
set _CLEANUP=
set _CLIENT=
set _PILOT=
set _DEFAULT=
set _REGASMEXE=
set _VISTA_OR_GREATER=
set _VISTA=
set _LEGACY_OS=
set _Win2K=
set _NOFWRESET=
set _STRESS=

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值