远程连接中VBScript SendKeys失效问题求助
解决远程桌面注销后WshShell.SendKeys失效的数据库自动备份问题
问题根源
你遇到的核心问题是:WshShell.SendKeys完全依赖交互式桌面会话才能工作。当你注销远程桌面后,当前用户的桌面会话会被断开,任务计划默认会在非交互式的后台会话中运行任务——这个环境里没有活跃的GUI窗口,也无法接收模拟按键输入,所以你的SendKeys完全起不了作用,甚至SSMS可能都没法正常启动并加载脚本。
用SSMS GUI + SendKeys的方式本来就不是自动化备份的可靠方案,它依赖用户会话和GUI环境,很容易因为会话断开、窗口焦点变化等问题失败。我们需要改用纯命令行的方式来执行备份,彻底摆脱对GUI的依赖。
正确解决方案:用命令行工具执行SQL备份
推荐使用SQL Server自带的sqlcmd工具(或者PowerShell的SqlServer模块)来直接执行备份脚本,不需要启动SSMS,全程后台运行,不管用户是否登录都能正常工作。
1. 调整备份脚本(确保SQL语句正确)
先确认你的Create_backups_of_all_DB.sql里的备份语句是完整可执行的,比如针对所有用户数据库的备份模板:
DECLARE @BackupPath NVARCHAR(500) = N'C:\BackUps\AutoBackups\'; DECLARE @DBName NVARCHAR(128); DECLARE db_cursor CURSOR FOR SELECT name FROM sys.databases WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb'); OPEN db_cursor; FETCH NEXT FROM db_cursor INTO @DBName; WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @BackupFileName NVARCHAR(500) = @BackupPath + @DBName + '_' + CONVERT(VARCHAR(8), GETDATE(), 112) + '.bak'; BACKUP DATABASE @DBName TO DISK = @BackupFileName WITH INIT, COMPRESSION; FETCH NEXT FROM db_cursor INTO @DBName; END CLOSE db_cursor; DEALLOCATE db_cursor;
(这段脚本会自动备份所有用户数据库,生成带日期的备份文件,启用压缩节省空间)
2. 重写批处理文件(替换原来的内容)
删掉原来依赖VBS和SendKeys的逻辑,直接用sqlcmd执行脚本,然后调用压缩和移动的批处理:
@echo off :: 用sqlcmd执行备份脚本(根据你的SQL实例和认证方式调整参数) sqlcmd -S .\SQLEXPRESS -E -i "C:\BackUps\AutoBackups\Create_backups_of_all_DB.sql" :: 等待备份完成(可以根据数据库大小调整等待时间,或者用更智能的判断) TIMEOUT /T 600 /NOBREAK :: 执行压缩和移动操作 call "C:\BackUps\AutoBackups\CreateRar.bat"
参数说明:
-S .\SQLEXPRESS:替换成你的SQL Server实例名称(比如默认实例用-S localhost)-E:使用Windows身份认证(如果用SQL账号,换成-U 用户名 -P 密码)-i:指定要执行的SQL脚本文件路径
3. 调整CreateRar.bat(用命令行压缩)
确保你的WinRAR安装目录在系统PATH里,或者直接指定rar.exe的完整路径,示例:
@echo off :: 压缩所有备份文件为带日期的RAR "C:\Program Files\WinRAR\rar.exe" a -ep1 -m5 "C:\BackUps\AutoBackups\DB_Backup_%date:~0,4%%date:~5,2%%date:~8,2%.rar" "C:\BackUps\AutoBackups\*.bak" :: 删除原备份文件 del "C:\BackUps\AutoBackups\*.bak" :: 移动RAR文件到目标位置 move "C:\BackUps\AutoBackups\*.rar" "D:\Your_Target_Folder\"
参数说明:
-a:添加文件到压缩包-ep1:排除文件的绝对路径,只保留文件名-m5:最高压缩率(可以根据需要调整为m0到m5)
4. 配置任务计划的关键设置
打开任务计划程序,编辑你的任务:
- 在常规选项卡:选择“不管用户是否登录都运行”,勾选“不存储密码”(如果用Windows认证),确保运行账号有SQL Server备份权限和文件系统读写权限
- 在触发器选项卡:设置你需要的每日执行时间
- 在操作选项卡:确保启动程序的路径是你的批处理文件,起始目录设置为
C:\BackUps\AutoBackups - 在设置选项卡:勾选“允许任务按需运行”,“如果任务失败,重试次数”可以设为3次,每次间隔5分钟
为什么原来的方法行不通?
再强调一下:
SendKeys是模拟用户在GUI窗口的按键操作,必须依赖活跃的交互式桌面会话- 注销远程桌面后,用户会话被断开,任务计划在后台的非交互式会话中运行,没有GUI环境,SSMS无法正常接收按键,甚至可能无法启动
- 这种依赖GUI的自动化方案非常脆弱,任何窗口焦点变化、会话断开都会导致失败,而命令行方式是SQL Server自动化运维的标准做法,稳定可靠
内容的提问来源于stack exchange,提问作者Tomas
相关产品推荐
相关产品推荐

