繁体   English   中英

在安全模式下从 Windows 批处理脚本启动 Excel 文件,使用默认文件关联

[英]Start Excel file from Windows batch script in safemode, use default file association

问题摘要:我可以在安全模式下从Windows批处理脚本启动Excel文件Installer.xlsm,而不提供EXCEL.EXE安装路径吗?

细节

我有一个 Windows 批处理脚本,它从远程服务器下载最新版本的 Excel 插件系列,将它们放在一个目录 (C:\appname\AddIns) 中并调用 Excel 文件 Installer.xlsm。

加载后,Installer.xlsm 会执行一个 VBA 宏,该宏会卸载旧版本的加载项并安装它们的新版本。

目前我使用以下命令启动 Installer.xlsm:

start "Launching installer file" /wait "<Path to file>\Installer.xlsm"

它的好处是它使用Windows的文件关联来打开Excel,并且我不必提供EXCEL.EXE的安装路径(多个用户使用不同的机器映像和MS Office版本)。

现在我想在安全模式下加载 Installer.xlsm,以确保在 Installer.xlsm 尝试使用加载项时没有加载加载项并且没有运行其他代码。

我知道我可以使用"<PathToExcel>excel" /safemode "<PathToXls>Installer.xlsm" ,如本答案中所述,但此方法不使用 Windows 的文件关联,并且需要我提供路径。

我们的用户拥有各种机器映像,使用不同版本的 MS Office,因此我不想对所有可能的 Excel 安装位置进行硬编码。

我可以做以下形式的事情:

start "Launching installer file" /wait "<Path to file>\Installer.xlsm /safemode"

我尝试了不同的可能组合但没有成功。 你会怎么做?

首先,我建议阅读 Microsoft 文档页面Application Registration 它解释了应用程序或应用程序套件(如 Microsoft Office)的安装程序应如何注册已安装的应用程序,以便其他应用程序可以找到应用程序的可执行文件。

推荐在注册表项下创建

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths

具有可执行文件名称的子键,例如excel.exe ,默认字符串值是具有完整路径的可执行文件的名称,并且可以选择添加一个名称为Path的字符串值,其中仅包含可执行文件的路径。 Path字符串可以但大多数不存在,它可以但不能以反斜杠结尾。

命令START也使用此键来查找应用程序,如“START”在哪里搜索可执行文件?

Microsoft Office 各个版本的安装程序也在此键下注册了excel.exe键。

因此,在 Windows Vista 和更高版本的 Windows 上获取 Microsoft Excel 安装位置的最简单方法是:

@echo off
for /F "skip=1 tokens=2*" %%A in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\excel.exe" /ve 2^>nul') do set "ExcelApp=%%~B"
echo ExcelApp=%ExcelApp%
pause

但是在 Windows XP 上, reg.exe的输出是不同的,因此需要这个批处理代码:

@echo off
for /F "skip=3 tokens=3*" %%A in ('%SystemRoot%\System32\reg.exe QUERY "HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\excel.exe" /ve 2^>nul') do set "ExcelApp=%%~B"
echo ExcelApp=%ExcelApp%
pause

不同的输出在阅读由空格和字符串值分隔的单词的答案中进行了解释,该字符串值还包含批处理脚本中的空格,批处理代码编写以获取包含空格的注册表项的默认字符串的字符串值。

添加额外的代码来处理像注册表项这样的错误情况是一种很好的编码实践,因为根本没有安装 Microsoft Excel。

但是,是否可以使用批处理代码分别执行 Windows shell 函数ShellExecuteEx在命令提示符窗口中使用命令行时执行的命令START

start "Launching installer file" "C:\Path to file\Installer.xlsm"

是的,正如下面注释的批处理代码所示,这是可能的。

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem First query default string value of HKEY_CLASSES_ROOT\.xlsm from registry.
call :GetDefaultRegValue "HKCR\.xlsm"

rem Is there no key HKEY_CLASSES_ROOT\.xlsm or was the default string empty?
if not defined RegValue goto GetFromAppPaths

SET RegValue
rem Get the shell command line used for opening a *.xlsm file.
call :GetDefaultRegValue "HKCR\%RegValue%\shell\open\command"

rem Could the command line not read successfully from Windows registry?
if not defined RegValue goto GetFromAppPaths

SET RegValue
rem The command line contains as first string usually enclosed in double
rem quotes EXCEL.EXE with full path enclosed in double quotes. And there
rem can be even more arguments on the command line which are not needed
rem here. The command line below is used to get just first string of
rem the command line which should be EXCEL.EXE with full path.
for %%I in (%RegValue%) do set "RegValue=%%~I" & goto CheckExcelExistence

rem It is not good when both registry queries above fail. This means
rem either Microsoft Excel is not installed at all or a version of
rem Excel is installed which does not support *.xlsm files like Excel
rem of MS Office 2003, MS Office 2000 or MS Office 97.

rem However, perhaps just *.xlsm is not correct registered and therefore
rem get full path to excel.exe from application registration key.

:GetFromAppPaths
call :GetDefaultRegValue "HKLM\Software\Microsoft\Windows\CurrentVersion\App Paths\excel.exe"
if defined RegValue goto CheckExcelExistence

echo Failed to determine installation location of Microsoft Excel.
echo/
endlocal
pause
goto :EOF

:CheckExcelExistence
SET RegValue
rem Remove surrounding double quotes if the Excel executable file name
rem read from Windows registry is still enclosed in double quotes.
set "RegValue=%RegValue:"=%"
if exist "%RegValue%" goto :RunInstall

echo Registered "%RegValue%" does not exist.
echo/
endlocal
pause
goto :EOF

:RunInstall
SET RegValue
ECHO start "Launching installer file" /wait "%RegValue%" "%~dp0Installer.xlsm" /safemode
endlocal
goto :EOF


rem This subroutine queries from Windows registry the default string value of
rem the key passed to the subroutine as first and only parameter and assigns
rem this value to environment variable RegValue. Environment variable RegValue
rem is deleted and therefore is not defined after subroutine exits on failure
rem to get the registry value or when the default value is an empty string.
rem This subroutine works for Windows XP and all later versions of Windows.

:GetDefaultRegValue
set "TypeToken=2"

:Reg3Run
for /F "skip=1 tokens=%TypeToken%*" %%A in ('%SystemRoot%\System32\reg.exe QUERY "%~1" /ve 2^>nul') do (
    if "%%A" == "REG_SZ" (
        if not "%%~B" == "" (
            set "RegValue=%%B"
            goto :EOF
        )
    ) else if "%%A" == "NAME>" (
        set "TypeToken=3"
        goto Reg3Run
    )
)
set "RegValue="
goto :EOF

这个批处理代码只是一个演示。 真正找到时它不会启动 Excel。 相反,它只是输出将启动 Excel 的命令行,因为ECHO left of start ... 在标签RunInstall下方的块中。

此外,此批处理代码包含 4 行,只有SET RegValue 这 4 行仅输出从 Windows 注册表成功查询并存储在环境变量RegValue中的字符串值。 这 4 个命令有助于了解执行批处理文件时会发生什么。 最后应该从批处理文件中删除这四个命令行,以及用大写字母编写的单个ECHO

注意:如果预期的注册表项不存在或其默认值为空字符串,则很容易测试会发生什么。 只需在以call :GetDefaultRegValue开头的行上的最后一个双引号之前插入像#这样的单个字符,就不会再找到修改后的注册表项。

要了解使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • call /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • reg /?
  • reg query /?
  • rem /?
  • setlocal /?
  • start /?

另请阅读有关使用命令重定向运算符的 Microsoft 文章,了解2>nul的说明。 重定向运算符>必须在FOR命令行上使用脱字符^进行转义,以便在 Windows 命令解释器在执行命令FOR之前处理此命令行时解释为文字字符,该命令使用在中启动的单独命令进程执行嵌入式reg.exe命令行背景。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM