You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WIX安装器执行BackupDatabase2014.bat时抛出0x80070001错误求助

问题:WIX Bootstrapper执行SQL Server备份BAT脚本失败

场景与配置

使用WIX Bootstrapper制作应用安装包,预期执行流程:

  • 备份SQL Server 2014数据库
  • 移除SQL Server 2014实例
  • 删除相关注册表项
  • 安装SQL Server 2022实例
  • 将2014备份恢复到2022实例

Bundle.wxs中的Chain配置:

<Chain>
  <ExePackage  SourceFile="..\prerequisites\BackupDatabase2014.bat" DisplayName="Backing up 2014 Database.."  Compressed ="yes" Vital ="no" Permanent ="yes" />
  <ExePackage  SourceFile="..\prerequisites\RemoveDatabase2014.bat" DisplayName="Uninstalling 2014 database.."  Compressed ="yes" Vital ="no" Permanent ="yes" />
  <ExePackage  SourceFile="..\prerequisites\RemoveFiles.bat" DisplayName="Removing Existing Database Keys.."  Compressed ="yes" Vital ="no" Permanent ="yes" />
  <PackageGroupRef Id="Sql2022Express"/>
  <ExePackage  SourceFile="..\prerequisites\RestoreDatabase2014.bat" DisplayName="Restoring 2014 Database records.."  Compressed ="yes" Vital ="no" Permanent ="yes" />
</Chain>

问题现象

单独运行BackupDatabase2014.bat可成功备份数据库,但通过WIX生成的EXE执行时返回错误:

Applying execute package: BackupDatabase2014.bat, action: Install, path: C:\ProgramData\Package Cache\812A85A2036657975578443EC126F48F631CEC9E\BackupDatabase2014.bat, arguments: '"C:\ProgramData\Package Cache\812A85A2036657975578443EC126F48F631CEC9E\BackupDatabase2014.bat"'
 Error 0x80070001: Process returned error: 0x1
 Error 0x80070001: Failed to execute EXE package.
 Error 0x80070001: Failed to configure per-machine EXE package.

备份脚本内容

BackupDatabase2014.bat完整代码:

@echo off
SETLOCAL EnableExtensions

rem Check if the script is running with administrative privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
    echo This script requires administrative privileges. Please run it as an administrator.
    exit /b 1
)

echo Checking for SQL Server instance XYZInstance...
reg query "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" /v XYZINSTANCE | findstr /i "MSSQL12.XYZINSTANCE" > nul 2>&1
if %errorlevel% neq 0 (
    echo XYZInstance instance not found in the registry. Exiting...
    exit /b 1
)

echo Setting backup folder path...
set "BackupFolderPath=C:\Database2014Backup"
echo Checking if the backup folder exists...
if not exist "%BackupFolderPath%" (
    echo Creating backup folder...
    mkdir "%BackupFolderPath%"
    if %errorlevel% neq 0 (
        echo Failed to create the backup folder. Exiting...
        exit /b 1
    )
)

echo Granting permissions...
icacls "%BackupFolderPath%" /grant "NT AUTHORITY\SYSTEM":(OI)(CI)F
if %errorlevel% neq 0 (
    echo Failed to grant permissions to the backup folder. Exiting...
    exit /b 1
)

echo Setting variables for backup...
set "ServerName=%COMPUTERNAME%\XYZInstance"
set "DatabaseName=XYZInstance"
set "BackupFileName=%DatabaseName%_Backup_%date:~4,2%-%date:~7,2%-%date:~10,4%.bak"
set "BackupFilePath=%BackupFolderPath%\%BackupFileName%"

echo Checking if the database exists...
sqlcmd -S %ServerName% -Q "IF EXISTS(SELECT 1 FROM sys.databases WHERE name = '%DatabaseName%') SELECT 1 ELSE SELECT 0;" -h-1 -s" " -W > nul
if %ERRORLEVEL% EQU 0 (
    echo Performing database backup...
    sqlcmd -S %ServerName% -Q "BACKUP DATABASE [%DatabaseName%] TO DISK='%BackupFilePath%'"
    if %errorlevel% neq 0 (
        echo Database backup failed. Exiting...
        exit /b 1
    )

    echo Checking if the backup was successful...
    if exist "%BackupFilePath%" (
        echo Database backup completed successfully.
    ) else (
        echo Database backup failed. Backup file does not exist.
        exit /b 1
    )
) else (
    echo Database %DatabaseName% does not exist. Skipping backup.
)

exit /b 0

解决方案

1. 修改WIX ExePackage配置,确保脚本在标准命令行环境运行

WIX直接调用BAT时可能缺失系统环境变量,改用cmd /c启动脚本,并指定64位执行上下文(针对64位系统):

<ExePackage SourceFile="..\prerequisites\BackupDatabase2014.bat" 
            DisplayName="Backing up 2014 Database.." 
            Compressed="yes" 
            Vital="no" 
            Permanent="yes"
            InstallCommand="cmd /c &quot;[SourceFile]&quot;"
            Platform="x64" />
  • InstallCommand:强制通过cmd.exe执行脚本,确保加载完整环境变量
  • Platform="x64":避免32位进程注册表重定向,确保能正确读取SQL Server的64位注册表项

2. 优化BAT脚本的兼容性与错误排查

移除冗余的管理员权限检查

WIX安装包已以管理员权限运行,net session在WIX的执行上下文可能返回异常,直接删除以下代码块:

rem Check if the script is running with administrative privileges
net session >nul 2>&1
if %errorLevel% neq 0 (
    echo This script requires administrative privileges. Please run it as an administrator.
    exit /b 1
)

固定sqlcmd路径,避免环境变量缺失

SQL Server 2014的sqlcmd默认路径为C:\Program Files\Microsoft SQL Server\120\Tools\Binn\sqlcmd.exe,在脚本开头添加路径定义,并替换所有sqlcmd调用:

set "SqlCmdPath=C:\Program Files\Microsoft SQL Server\120\Tools\Binn\sqlcmd.exe"

修改后的数据库检查与备份命令:

echo Checking if the database exists...
"%SqlCmdPath%" -S %ServerName% -Q "IF EXISTS(SELECT 1 FROM sys.databases WHERE name = '%DatabaseName%') SELECT 1 ELSE SELECT 0;" -h-1 -s" " -W > nul
if %ERRORLEVEL% EQU 0 (
    echo Performing database backup...
    "%SqlCmdPath%" -S %ServerName% -Q "BACKUP DATABASE [%DatabaseName%] TO DISK='%BackupFilePath%'"
    if %errorlevel% neq 0 (
        echo Database backup failed. Exiting...
        exit /b 1
    )

替换日期格式为系统兼容方式

%date%的格式依赖系统区域设置,可能生成非法文件名,改用wmic生成统一格式的日期:

for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "BackupFileName=%DatabaseName%_Backup_%dt:~4,2%-%dt:~6,2%-%dt:~0,4%.bak"

添加日志记录,方便排查错误

在脚本开头添加日志文件定义,将所有输出写入日志:

set "LogFolder=C:\Database2014Backup"
if not exist "%LogFolder%" mkdir "%LogFolder%"
for /f "tokens=2 delims==" %%a in ('wmic OS Get localdatetime /value') do set "dt=%%a"
set "LogFile=%LogFolder%\BackupLog_%dt:~0,8%_%dt:~8,4%.txt"
echo Starting backup at %date% %time% >> "%LogFile%"

然后将所有echo命令修改为追加到日志,例如:

echo Checking for SQL Server instance XYZInstance... >> "%LogFile%"

3. 调整脚本错误处理逻辑

将部分严格的exit /b 1改为警告并继续执行(根据实际需求),例如注册表检查失败时,允许脚本跳过备份而非直接退出:

echo Checking for SQL Server instance XYZInstance... >> "%LogFile%"
reg query "HKLM\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL" /v XYZINSTANCE | findstr /i "MSSQL12.XYZINSTANCE" > nul 2>&1
if %errorlevel% neq 0 (
    echo XYZInstance instance not found in the registry. Skipping backup... >> "%LogFile%"
    exit /b 0
)

内容的提问来源于stack exchange,提问作者Suman jha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 07:46:18