«

Windows 无法设置默认打印机 0x00000709:不是驱动坏了,是注册表里有一条死记录

tenai 发布于 阅读:903 报错速查


报 0x00000709 时,多数人的第一反应是删掉打印机重装。但如果旧打印机已经删了、名字还挂在注册表里,你重装多少次都一样。先花两分钟确认这条记录。

最后更新 2026-10-20 适用 Windows 10 1803+ / Windows 11 脚本验证 PowerShell 5.1

一、30 秒判断:这是不是你的问题

三条全部命中,才是本文说的问题
  1. 报错出现在「右键 → 设为默认打印机」这一步,或添加共享打印机后系统自动设默认时。原文含「无法设置默认打印机」或「操作无法完成(错误 0x00000709)」。
  2. 通常是换过打印机、改过电脑名、删过旧打印机、或系统升级过之后才开始出现。
  3. 打印机本身是好的 —— 你手动选它、手动打印能出纸,只有"设为默认"这一步失败。

第三条最要紧:打印不了和设不了默认是两类问题。如果连打印任务都发不出去,或者报的是 0x0000011b,那是连接问题,先看那一篇。

二、适用环境

项目 说明
客户端 Windows 10 1803 及以上、Windows 11 全版本
打印机类型 本地打印机和共享打印机都会出现,共享打印机更常见
典型触发 删除过旧打印机、改过计算机名、换过 USB 端口、系统大版本升级
常见伴随 与 0x0000011b 同时出现 —— 但那是"连不上",不是"设不了默认"
不适用 报错发生在发送打印任务阶段;或打印机脱机、缺纸、驱动损坏

三、为什么会这样

Windows 把"默认是哪台打印机"记在用户注册表的一条 Device 值里,格式是 打印机名,winspool,端口名。删除打印机时,这条记录并不总是跟着清掉。于是你点"设为默认"时,系统要写入这条记录,却发现它指向一台已经不存在的设备 —— 写入失败,报 0x00000709。

一句话:不是驱动坏了,是"默认打印机"这条记录写不进去。

所以重装驱动、换 USB 口、重装系统,全都是白费 —— 记录不清理,重装完还是同一条残留。

另外还有一个叠加因素:Win10 之后默认开启「让 Windows 管理我的默认打印机」,它会按你的使用频率自动切换默认项。你手动设定的值,可能几分钟后就被它改回去了 —— 表现出来也像"设不了默认"。

四、方案 A:命令行直接设默认(先试这个,10 秒)

设置界面走的是 Shell 的一条写入路径,命令行走的是另一条。很多情况下界面点不动、命令行却一次成功。成了就不用往下看。

# 方式一:printui
rundll32 printui.dll,PrintUIEntry /y /n "3F-HP-M403"

# 方式二:COM 接口(对含空格/中文的打印机名更稳)
(New-Object -ComObject WScript.Network).SetDefaultPrinter("3F-HP-M403")

打印机名必须和「设置 → 打印机和扫描仪」里显示的完全一致。不确定就先跑 Get-Printer | Select-Object Name 看一眼。

五、方案 B:清理残留记录 + 关掉自动管理

A 无效,说明那条残留记录确实在挡路。把它清掉,同时关掉自动管理,避免设好又被改回去。

# 1. 先看一眼现在记的是什么(大概率指向一台已不存在的打印机)
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows' -Name Device

# 2. 直接删掉。不要手改 —— 格式是 打印机名,winspool,端口名,改错更麻烦
Remove-ItemProperty 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows' -Name Device

# 3. 关闭「让 Windows 管理我的默认打印机」
New-ItemProperty 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows' `
  -Name LegacyDefaultPrinterMode -PropertyType DWord -Value 1 -Force

# 4. 重启打印后台处理程序
Restart-Service Spooler -Force

对应的图形界面开关在:设置 → 蓝牙和其他设备 → 打印机和扫描仪 → 关闭「让 Windows 管理我的默认打印机」。改完记得注销重新登录一次,HKCU 的改动需要会话重载才完全生效。

改之前先导出备份

这些是当前用户级注册表,影响面只到你自己的账号,风险不高。但养成习惯:reg export "HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows" D:\backup\win.reg,出问题能一键还原。

六、方案 C:彻底重装打印子系统(A、B 都无效才用)

# 1. 先记录现有打印机清单(后面要照着装回来)
Get-Printer | Select-Object Name, DriverName, PortName | Format-Table -AutoSize

# 2. 删除所有打印机
Get-Printer | Remove-Printer

# 3. 删除驱动包(会弹出图形界面,勾选要删的驱动)
rundll32 printui.dll,PrintUIEntry /s /t2

# 4. 重启服务后按清单重装
Restart-Service Spooler -Force
这一步会清掉本机所有打印机

共享打印机、本地打印机、虚拟打印机(含 PDF 打印机)全部会消失。执行前把第 1 步的清单存下来,否则你会花更多时间装回去。有打印服务器的话,这一步务必先跟使用人打个招呼。

七、一键脚本

把检测、设默认、清理残留、回滚做成一个脚本。只读检测能直接告诉你 Device 是否指向一台已不存在的打印机 —— 这一条判断基本能确定病因,不用猜。

# 只读检测:当前默认、Device 记录、是否残留
.\Fix-DefaultPrinter0709.ps1 -Action Detect

# 命令行设默认
.\Fix-DefaultPrinter0709.ps1 -Action SetDefault -PrinterName "3F-HP-M403"

# 预览将清理什么(不实际改动)
.\Fix-DefaultPrinter0709.ps1 -Action Repair -WhatIf

# 确认后执行:备份 + 清理残留 + 关自动管理 + 重启服务
.\Fix-DefaultPrinter0709.ps1 -Action Repair

# 回滚(自动管理开关还原,Device 不自动写回)
.\Fix-DefaultPrinter0709.ps1 -Action Rollback
展开完整脚本(保存为 Fix-DefaultPrinter0709.ps1 后使用)
#Requires -Version 5.1
<#
.SYNOPSIS
    Windows 0x00000709「无法设置默认打印机」排障工具

.DESCRIPTION
    四种动作:
      Detect      只读检测:当前默认打印机、注册表 Device 值、自动管理开关、残留判断
      SetDefault  用 COM 接口设置默认打印机(绕过设置界面,专治界面点不动的场景)
      Repair      备份并清理残留 Device 值 + 关闭"让 Windows 管理默认打印机" + 重启 Spooler
      Rollback    还原 Repair 的改动

.PARAMETER Action
    要执行的动作,默认 Detect。

.PARAMETER PrinterName
    SetDefault 时使用的打印机名称,必须与 Get-Printer 输出完全一致。

.EXAMPLE
    .\Fix-DefaultPrinter0709.ps1 -Action Detect

.EXAMPLE
    .\Fix-DefaultPrinter0709.ps1 -Action SetDefault -PrinterName "3F-HP-M403"

.EXAMPLE
    .\Fix-DefaultPrinter0709.ps1 -Action Repair -WhatIf

.NOTES
    最后更新:2026-10-20
    适用:Windows 10 1803+ / Windows 11;PowerShell 5.1 与 7 均可
#>

[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
param(
    [ValidateSet('Detect', 'SetDefault', 'Repair', 'Rollback')]
    [string]$Action = 'Detect',

    [string]$PrinterName
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

$WinKey    = 'HKCU:\Software\Microsoft\Windows NT\CurrentVersion\Windows'
$SvcName   = 'Spooler'
$BackupDir = Join-Path $env:TEMP 'itdb-0709'
$BackupFile = Join-Path $BackupDir 'device-backup.txt'

function Write-Head([string]$text) {
    Write-Host ''
    Write-Host $text -ForegroundColor Yellow
    Write-Host ('-' * 34) -ForegroundColor DarkGray
}

function Get-DefaultPrinterName {
    $p = Get-CimInstance -ClassName Win32_Printer -Filter 'Default = TRUE' -ErrorAction SilentlyContinue
    if ($null -eq $p) { return $null }
    return $p.Name
}

function Get-DeviceValue {
    $item = Get-ItemProperty -Path $WinKey -Name 'Device' -ErrorAction SilentlyContinue
    if ($null -eq $item) { return $null }
    $value = $item.Device
    if ([string]::IsNullOrWhiteSpace($value)) { return $null }
    return $value
}

function Get-ManagedDefaultValue {
    $item = Get-ItemProperty -Path $WinKey -Name 'LegacyDefaultPrinterMode' -ErrorAction SilentlyContinue
    if ($null -eq $item) { return $null }
    return $item.LegacyDefaultPrinterMode
}

function Restart-SpoolerInternal {
    Write-Host '   -> 重启打印后台处理程序 (Spooler) ...'
    Restart-Service -Name $SvcName -Force
    $svc = Get-Service -Name $SvcName
    Write-Host ("   -> Spooler 当前状态:{0}" -f $svc.Status)
}

# ---------------------------------------------------------------- Detect

function Invoke-Detect {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    Write-Head '[1/5] 系统信息'
    $os = Get-CimInstance -ClassName Win32_OperatingSystem
    Write-Host ("   系统:{0}  Build {1}" -f $os.Caption, $os.BuildNumber)
    Write-Host ("   计算机:{0}   域/组:{1}" -f $env:COMPUTERNAME, $env:USERDOMAIN)
    $svc = Get-Service -Name $SvcName
    Write-Host ("   Spooler:{0}  启动类型:{1}" -f $svc.Status, $svc.StartType)

    Write-Head '[2/5] 当前打印机清单'
    $printers = @()
    $readOk = $false
    try {
        $printers = @(Get-Printer -ErrorAction Stop)
        $readOk = $true
        if ($printers.Count -eq 0) {
            Write-Host '   本机没有任何打印机' -ForegroundColor Gray
        }
        foreach ($p in $printers) {
            $mark = if ($p.Name -eq (Get-DefaultPrinterName)) { ' [默认]' } else { '' }
            Write-Host ("   - {0}{1}" -f $p.Name, $mark) -ForegroundColor $(if ($mark) { 'Green' } else { 'Gray' })
            Write-Host ("     端口:{0}   驱动:{1}" -f $p.PortName, $p.DriverName) -ForegroundColor DarkGray
        }
    }
    catch {
        Write-Host '   读取打印机列表失败(这不等于没有打印机)' -ForegroundColor Red
        Write-Host ("   原因:{0}" -f $_.Exception.Message) -ForegroundColor DarkGray
    }

    Write-Head '[3/5] 注册表默认打印机记录 (Device)'
    $device = Get-DeviceValue
    if ($null -eq $device) {
        Write-Host '   Device:<未设置>' -ForegroundColor Gray
    }
    else {
        Write-Host ("   Device:{0}" -f $device)
        Write-Host '   格式说明:打印机名,winspool,端口名' -ForegroundColor DarkGray
    }

    Write-Head '[4/5] Windows 默认打印机管理'
    $managed = Get-ManagedDefaultValue
    if ($null -eq $managed) {
        Write-Host '   LegacyDefaultPrinterMode:<未设置>(由 Windows 自动管理默认打印机)' -ForegroundColor Gray
    }
    elseif ($managed -eq 1) {
        Write-Host '   LegacyDefaultPrinterMode:1(已关闭自动管理,由用户手动指定)' -ForegroundColor Green
    }
    else {
        Write-Host ("   LegacyDefaultPrinterMode:{0}(自动管理仍生效)" -f $managed)
    }

    Write-Head '[5/5] 诊断建议'
    if (-not $readOk) {
        Write-Host '   无法读取打印机清单,本次不做判断。' -ForegroundColor Red
        Write-Host '   请先确保:① 以管理员身份运行  ② Spooler 服务已启动,然后重新执行 Detect。' -ForegroundColor Red
        return
    }
    if ($printers.Count -eq 0) {
        Write-Host '   本机没有打印机,先添加打印机再谈默认值。' -ForegroundColor Red
        return
    }

    $stale = $false
    if ($null -ne $device) {
        $devName = ($device -split ',')[0]
        $exists = @($printers | Where-Object { $_.Name -eq $devName }).Count -gt 0
        if (-not $exists) {
            $stale = $true
            Write-Host ("   !! 残留记录:Device 指向的「{0}」已不存在" -f $devName) -ForegroundColor Red
            Write-Host '      这就是 0x00000709 最常见的原因 —— 设默认时写不进这条记录。' -ForegroundColor Red
        }
        else {
            Write-Host ("   Device 指向的「{0}」存在,记录正常。" -f $devName) -ForegroundColor Green
        }
    }

    if ((Get-DefaultPrinterName) -eq $null) {
        Write-Host '   !! 当前没有默认打印机' -ForegroundColor Red
    }

    if ($stale) {
        Write-Host ''
        Write-Host '   建议执行:-Action Repair  (先预览:-Action Repair -WhatIf)' -ForegroundColor Cyan
    }
    else {
        Write-Host ''
        Write-Host '   建议先用命令行直接设默认:-Action SetDefault -PrinterName "打印机名"' -ForegroundColor Cyan
        Write-Host '   若界面里点"设为默认"仍报 0x00000709,再执行 Repair。' -ForegroundColor Cyan
    }
}

# ---------------------------------------------------------------- SetDefault

function Invoke-SetDefault {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    if ([string]::IsNullOrWhiteSpace($PrinterName)) {
        throw '需要 -PrinterName 参数。先用 -Action Detect 查看准确的打印机名称。'
    }
    $target = Get-Printer -Name $PrinterName -ErrorAction SilentlyContinue
    if ($null -eq $target) {
        throw ("本机没有名为 '{0}' 的打印机。请用 -Action Detect 核对名称。" -f $PrinterName)
    }

    Write-Head ("设置默认打印机:{0}" -f $PrinterName)

    if ($PSCmdlet.ShouldProcess($PrinterName, '设为默认打印机')) {
        $ok = $false
        try {
            $net = New-Object -ComObject WScript.Network
            $net.SetDefaultPrinter($PrinterName)
            $ok = $true
        }
        catch {
            Write-Host ("   COM 方式失败:{0}" -f $_.Exception.Message) -ForegroundColor DarkGray
        }

        Start-Sleep -Milliseconds 300
        $now = Get-DefaultPrinterName
        if ($now -ne $PrinterName) {
            Write-Host '   COM 方式未生效,改用 printui.dll ...' -ForegroundColor Yellow
            $null = & rundll32.exe printui.dll,PrintUIEntry /y /n $PrinterName
            Start-Sleep -Milliseconds 500
            $now = Get-DefaultPrinterName
        }

        if ($now -eq $PrinterName) {
            Write-Host ("   -> 成功,当前默认打印机:{0}" -f $now) -ForegroundColor Green
        }
        else {
            Write-Host ("   -> 失败,当前默认打印机仍为:{0}" -f $now) -ForegroundColor Red
            Write-Host '      请尝试 -Action Repair 清理残留记录后重试。' -ForegroundColor Red
        }
    }
    else {
        Write-Host '   -> [WhatIf] 预览模式,未做任何修改。' -ForegroundColor Yellow
    }
}

# ---------------------------------------------------------------- Repair

function Invoke-Repair {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    Write-Head '清理残留 Device 记录 + 关闭自动管理默认打印机'

    $device = Get-DeviceValue
    $managed = Get-ManagedDefaultValue

    if ($null -ne $device -or $null -ne $managed) {
        if (-not (Test-Path -Path $BackupDir)) {
            if ($PSCmdlet.ShouldProcess($BackupDir, '创建备份目录')) {
                New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null
            }
        }
        $backup = "Device=$device`r`nLegacyDefaultPrinterMode=$managed`r`nSavedAt=$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
        if ($PSCmdlet.ShouldProcess($BackupFile, '写入改动前备份')) {
            $backup | Out-File -FilePath $BackupFile -Encoding utf8
            Write-Host ("   -> 已备份原值到 {0}" -f $BackupFile) -ForegroundColor Green
        }
    }

    if ($null -ne $device) {
        if ($PSCmdlet.ShouldProcess("$WinKey\Device", '删除残留值')) {
            Remove-ItemProperty -Path $WinKey -Name 'Device' -Force
            Write-Host '   -> 已删除 Device(残留记录)' -ForegroundColor Green
        }
        else {
            Write-Host '   -> [WhatIf] 将删除 Device 残留记录' -ForegroundColor Yellow
        }
    }
    else {
        Write-Host '   Device 本来就为空,跳过' -ForegroundColor Gray
    }

    if ($PSCmdlet.ShouldProcess("$WinKey\LegacyDefaultPrinterMode", '设置为 1(关闭自动管理)')) {
        New-ItemProperty -Path $WinKey -Name 'LegacyDefaultPrinterMode' -PropertyType DWord -Value 1 -Force | Out-Null
        Write-Host '   -> 已关闭「让 Windows 管理默认打印机」' -ForegroundColor Green
    }
    else {
        Write-Host '   -> [WhatIf] 将把 LegacyDefaultPrinterMode 设为 1' -ForegroundColor Yellow
    }

    if ($PSCmdlet.ShouldProcess($SvcName, '重启打印后台处理程序')) {
        Restart-SpoolerInternal
    }
    else {
        Write-Host '   -> [WhatIf] 将重启 Spooler' -ForegroundColor Yellow
    }

    Write-Host ''
    if ($WhatIfPreference) {
        Write-Host '   [WhatIf] 预览结束,未做任何修改。去掉 -WhatIf 即真实执行。' -ForegroundColor Yellow
    }
    else {
        Write-Host '   完成。请重新设置默认打印机:-Action SetDefault -PrinterName "打印机名"' -ForegroundColor Cyan
        Write-Host '   如果没生效,注销并重新登录一次(HKCU 改动需要会话重载)。' -ForegroundColor Cyan
    }
}

# ---------------------------------------------------------------- Rollback

function Invoke-Rollback {
    [CmdletBinding(SupportsShouldProcess = $true)]
    param()

    Write-Head '还原 Repair 的改动'
    if (-not (Test-Path -Path $BackupFile)) {
        Write-Host ("   没找到备份文件:{0}" -f $BackupFile) -ForegroundColor Red
        Write-Host '   未做过 Repair,或备份已被清理,无需回滚。' -ForegroundColor Gray
        return
    }

    $raw = Get-Content -Path $BackupFile -Raw
    Write-Host '   备份内容:'
    Write-Host ('   ' + ($raw -replace "`r`n", "`r`n   ")) -ForegroundColor DarkGray

    if ($PSCmdlet.ShouldProcess($WinKey, '移除 LegacyDefaultPrinterMode 并重启 Spooler')) {
        Remove-ItemProperty -Path $WinKey -Name 'LegacyDefaultPrinterMode' -ErrorAction SilentlyContinue
        Write-Host '   -> 已移除 LegacyDefaultPrinterMode,恢复自动管理' -ForegroundColor Green
        Restart-SpoolerInternal
        Write-Host '   注意:Device 值不自动写回 —— 写回一条旧记录反而会重新制造问题。' -ForegroundColor Yellow
        Write-Host '   如需恢复默认打印机,请用 -Action SetDefault 重新指定。' -ForegroundColor Yellow
    }
    else {
        Write-Host '   -> [WhatIf] 预览模式,未做任何修改。' -ForegroundColor Yellow
    }
}

# ---------------------------------------------------------------- 入口

Write-Host ''
Write-Host '0x00000709 默认打印机排障工具  |  只读检测请用 -Action Detect' -ForegroundColor Cyan
Write-Host ("当前动作:{0}" -f $Action) -ForegroundColor Cyan

switch ($Action) {
    'Detect'     { Invoke-Detect -WhatIf:$WhatIfPreference }
    'SetDefault' { Invoke-SetDefault -WhatIf:$WhatIfPreference }
    'Repair'     { Invoke-Repair -WhatIf:$WhatIfPreference }
    'Rollback'   { Invoke-Rollback -WhatIf:$WhatIfPreference }
}

Write-Host ''
Write-Host '完成。' -ForegroundColor Cyan

八、怎么确认真的修好了

  1. 看默认项:Get-CimInstance Win32_Printer -Filter 'Default = TRUE' | Select-Object Name 应该返回你要的那台
  2. 看界面:控制面板 → 设备和打印机,目标打印机上应该有绿色对勾
  3. 注销重登再看一次。HKCU 的改动不重登,经常是"当场好了,下次登录又回去"
  4. 重启一次再打一张。确认不是服务还没重启完造成的假象

九、踩过的坑

  1. 手改 Device 值。格式是 打印机名,winspool,端口名,端口名写错一位就整条失效,而且不报错。直接删掉更安全,删了系统会自己重建。
  2. 删完第一次打印提示"没有默认打印机"。这是正常的,重新设一次就好,不是又坏了。
  3. 打印机名含中文或空格。命令行里要用英文引号完整包住,中文引号会直接失败。
  4. 域环境被组策略覆盖。GPO 里的「打印机首选项」会在每次登录时重新下发默认打印机,你改完下次登录又是旧的。这种情况要先看 gpresult /h,不是改本机。
  5. 把 0x00000709 当成 0x0000011b 修。后者是 SMB 连接建立不起来,两者常一起出现但解法完全不同。先修连接,再谈默认。
  6. 第一招就删驱动重装。八成不是驱动问题,白折腾半小时还容易把能用的打印机弄坏。

十、不是这个问题的情况

  • 0x0000011b —— 共享打印机连不上,RPC 认证级别不匹配,解法是改用 IP 直连
  • 0x80070035 —— 访问共享时「找不到网络路径」,是名称解析 / 445 端口 / 来宾登录这一类问题
  • 0x00000bbb —— 驱动或端口配置问题,跟默认打印机无关
  • 打印机脱机 / 打印队列卡住 —— 后台处理程序或端口问题,不在本文范围

关于本文示例:文中的打印机名、主机名均为示例(3F-HP-M403、corp.example.com),请替换成你自己的环境。

改注册表前请先导出备份,脚本的所有写入动作都支持 -WhatIf 预览和 Rollback 回滚。

共享 打印机 WIN 报错