【问题标题】:Save & Close Open Excel 2007 Files Automatically BEFORE Shutdown Due To Power Loss保存并关闭打开的 Excel 2007 文件在因断电而关闭之前自动打开
【发布时间】:2015-05-09 03:58:27
【问题描述】:

我花了几天的时间试图找到一种方法来保存用户打开的 Excel 2007 文件,然后再发出 shutdown.exe 或 psshutdown.exe。我正在使用启用了 UAC 的 Windows 7 Pro 64 位机器,包括远程限制。我不想绕过这些安全措施。

我开发了可以完成这项工作的 vbscript,但它只能在本地运行。代码如下:

Option Explicit
'--------------------------------------------------

'*** Dimension Local Variables ***
Dim objXL, msg, i, WshShell, strShutdownMessage, strMsg

'*** Enable Error Handling ***
On Error Resume Next

'*** Display Server Emergency and Computer Shutdown Message ***
Set WshShell = WScript.CreateObject("WScript.Shell") 'Creates an instance of the Windows Scripting Host shell (WshShell)
'--- Popup Message - Automatically Closes After 15 Seconds ---
'--- (the "4112" nType value is the sum of 16 - Critical window type + 4096 - display on top!!)
WshShell.Popup "AN UNEXPECTED SERVER EMERGENCY HAS OCCURRED." & Chr(13) & Chr(13) &_
"THIS COMPUTER WILL AUTOMATICALLY SHUT DOWN 30 SECONDS FROM WHEN THIS MESSAGE DISAPPEARS.  " &_
"PLEASE SAVE YOUR DATA AND CLOSE ALL OPEN APPLICATIONS IMMEDIATELY!", 15, "SERVER EMERGENCY SHUTDOWN WARNING!",4112

'*** Debugging Exit ***
'WScript.quit

'*** Wait 30 Seconds Before Saving Data, Closing Applications, and Shutting Down Computer ***
WScript.Sleep 30000

'*** Set Excel Object Variable ***
Set objXL = GetObject( , "Excel.Application")

'*** Trap Error And Shutdown Computer If No Open Excel Workbooks ***
If Err.Number > 0 Then 'No open Excel workbooks
 'MsgBox ("ErrorLevel ... = " & Err.Number)
 'Wscript.quit
 WshShell.run("c:\windows\system32\shutdown.exe /f /s") 'Run shutdown command
End If

'*** Save Data And Close Each Open Excel Workbook ***
For Each i In objXL.Workbooks 'Close each open Excel workbook
 i.Save
 i.Close
Next

'*** Shutdown Computer ***
WshShell.run("c:\windows\system32\shutdown.exe /f /s")

我遇到的问题是代码执行以下语句时抛出429错误:

Set objXL = GetObject( , "Excel.Application")

我已经尝试过 psexec、runas、vmrum(远程机器是 VM),甚至是任务计划程序来解决这个问题。我什至想出了如何确定远程 VM 上登录用户的会话号,以便我可以将它传递给 psexec,以便它可以与远程 VM 用户交互运行。关闭警告消息正确显示在远程 VM 活动用户的桌面上。但我总是收到 429 错误 - 除非我使用远程 VM 的本地管理员帐户登录本地和远程计算机(这是一个工作组,而不是域,顺便说一句)。我最初认为这可能是一个 psexec 问题,但我现在认为它是 Office 2007 或 Windows 7 UAC 权限问题(感谢 Harry Johnston 对我原帖的回答):

GetObject() 429 使用 PSExec 在虚拟机上运行 WScript 文件时出错 机器

在发出关机指令之前,有什么方法可以在远程机器上保存打开的 Excel 文件吗?我不信任 Office 自动保存。我客户的数据太重要了,不会因为停电或无法正确使用自动保存而丢失。

【问题讨论】:

    标签: windows excel vbscript uac psexec


    【解决方案1】:

    如果你正常关机,Word等会弹出对话框。正常关机只是请求程序关闭,任何程序都可以取消它。强制程序终止时。

    因此,请在客户端中正常关闭 excel。他们会得到一个对话框。他们也可以取消它。 taskkill 命令行程序可以做到这一点。

    taskkill /s computername /im excel.exe
    

    如果他们拒绝关闭,您可以使用 /f 标志强制关闭。

    【讨论】:

    • 是的,我知道这一点。我试图解决的用例是当用户没有保存他们的工作并且在发生断电时(在会议中、午餐时等)他们离开了他们的计算机。尽管这在技术上是用户的问题,但为了留住新客户,我想防止这种情况发生。
    • 如果您保存它,请确保您不会覆盖原始文件 - 人们编辑文件是为了丢弃更改。
    • 是的,我知道这一点。这个问题没有完美的解决方案。我打算使用“期望管理”来处理这个问题,这意味着如果用户在离开机器之前没有保存他们的“测试更改”,那是他们的责任。
    【解决方案2】:

    这个问题的简短回答是,我在远程机器上运行的 vbscript 没有在远程机器的登录用户的安全上下文中运行因此,Office 2007 不会'不允许在以下代码行中从 Excel.Application ActiveX 组件创建 objXL 对象(因此出现 429 错误消息“ActiveX 组件无法创建对象”):

    Set objXL = GetObject( , "Excel.Application")
    

    因此,挑战在于能够弄清楚如何在远程机器的登录用户的安全上下文中运行我的 vbscript(或任何应用程序)。我最终选择了 PSEXEC 作为我用来在远程机器上运行我的 vbscript 的实用程序。 PSEXEC 有三个问题,我必须处理这些问题才能让我的 vbscript 成功执行而不会出现 429 错误(如果您使用 PSEXEC 以外的其他东西,您的问题列表可能会有所不同)。 这些问题仅存在于远程机器上:

    1. 远程过程调用 (RPC) 引擎未激活
    2. UAC 远程访问限制已启用
    3. 应用程序必须在登录用户的 Windows 7 会话中运行

    解决第一个问题需要在远程计算机上启用 RPC 引擎。为此,您必须配置并启动四 (4) 个 Windows 服务并配置注册表项以启用 remote RPC。配置注册表项以启用远程 RPC,如下所示:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TerminalServer

    • AllowRemoteRPC ... dword = 1
    • fDenyTSConnections ... dword=0

    四个Windows服务应该配置如下:

    • 远程桌面配置服务...手动启动...必须启动
    • 远程桌面服务服务...手动启动...必须启动
    • 远程桌面服务用户模式端口重定向服务...手动启动..必须启动
    • 远程过程调用服务...自动启动...必须启动

    第二个问题,UAC 远程访问限制,阻止任何在 Windows 7 计算机上拥有帐户的用户使用 remote PRC(这是 PSEXEC 用来在其上运行应用程序的机制)远程访问计算机远程机器)使用机器的内置管理员帐户时除外。 Windows 7 内置管理员帐户不受 UAC 远程限制的影响(这解释了为什么我在使用管理员帐户时执行的 vbscript 没有 429 错误)。但是,所有其他用户帐户都会受到影响。

    经过几天的测试,我了解到只有在远程机器登录用户的安全上下文中运行应用程序才能在远程机器上成功执行。这意味着 PSEXEC 必须使用远程机器当前登录用户的登录凭据,以便应用程序访问远程机器登录用户的安全上下文并且不引发 429 错误。 这是帮助我配置此解决方案以解决 429 错误问题的关键学习部分。

    但是我怎么能使用远程机器的登录用户的登录凭据(假设我有一些方法来获取凭据;稍后会详细介绍)在登录用户的安全上下文中执行我的 vbscript,如果远程机器的 UAC 远程访问限制首先拒绝我访问远程机器?我可以让它工作的唯一方法是关闭远程机器的 UAC 远程访问限制。这不是一个简单的决定,因为关闭 UAC 远程访问限制会使远程机器面临“环回攻击”。但是,如果我要让 PSEXEC 在远程机器的登录用户的安全上下文中在远程机器上运行我的 vbscript,我别无选择。要关闭 UAC 远程访问限制,请在远程计算机上修改以下注册表项:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System

    值“0”(零)启用 UAC 远程限制; “1”值禁用 UAC 远程限制。将此值更改为“1”以禁用 UAC 远程访问限制。这将允许 PSEXEC 访问远程计算机以使用远程计算机的登录用户的登录凭据来运行其应用程序负载。

    最后一个也是最具挑战性的问题是如何确定哪个用户在远程计算机上登录,然后使用他们的用户名和密码在登录用户的安全上下文中运行 PSEXEC。解决这个问题的方法是使用 QWINSTA 查询远程机器上的会话数据。这涉及创建一个 Windows 7 命令 (.cmd) 文件,该文件使用 QWINSTA 询问远程计算机,并确定与远程计算机的活动会话相关联的 USERNAME 以及活动会话的 ID。

    使用 Windows 7 .cmd 文件中存在的一系列 DOS 比较 ("==") 语句,将 QWINSTA USERNAME 值与远程计算机用户列表及其密码进行比较,以确定远程计算机的登录用户密码。然后将用户名、密码和会话 ID 作为扩展的 DOS 变量传递给 PSEXEC 语句。然后,PSEXEC 应用程序有效负载可以在正确的用户会话中在远程计算机上运行(这也是一个难以解决的问题),并使用登录用户的凭据。正确的用户会话和登录用户登录凭据的组合将 PSEXEC 应用程序“连接”到登录用户的安全上下文并允许其运行而不会生成 429 错误。

    【讨论】:

      猜你喜欢
      • 2021-11-24
      • 1970-01-01
      • 2016-06-10
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多