2017-08-04 20 views
1

問題總結: 能否啓動Excel從Windows批處理腳本安全模式文件Installer.xlsm,但不提供EXCEL.EXE安裝路徑?啓動Excel文件中的安全模式,使用默認文件關聯

詳細

我有一個Windows批處理腳本下載一個家庭的Excel的最新版本加載項從遠程服務器,在一個目錄把它們(C:\應用程序名稱\加載項),並調用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",如this answer中所述,但此方法不使用Windows的文件關聯,並要求我提供路徑。

我們擁有使用不同版本的MS Office的各種機器圖像的用戶,因此我不想對所有可能的Excel安裝位置進行硬編碼。

我可以做以下形式的東西:

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

我嘗試不同的可能組合沒有成功。你會怎麼做?

+0

爲什麼直接使用excel可執行文件出現問題? – Compo

+0

嗨@Compo看到我的問題。它需要提供EXCEL.exe安裝位置的路徑,這對於不同的機器映像和MS Office版本的用戶將有所不同。我並不知道指向MS Office安裝文件夾的env變量,也不想對可能的位置進行硬編碼,只是偶爾發現有新的可能性需要添加到腳本中。你知道動態獲取EXCEL.exe路徑的另一種方法嗎? –

+0

https://superuser.com/questions/280176/how-to-run-ms-excel-2007-from-a-batch-file –

回答

2

首先,我建議閱讀有關Application Registration的Microsoft TechNet文章。它解釋了應用程序的安裝程序或Microsoft Office等應用程序套件如何註冊已安裝的應用程序,以便其他應用程序可以找到應用程序的可執行文件。

推薦的是下注冊表項創建

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

與像excel.exe可執行文件與完整路徑可執行文件的默認字符串值是名稱和可選將與名稱多了一個字符串值的名稱的子項僅包含可執行文件的路徑的PathPath字符串可以但大多數不存在,它可以但不能以反斜槓結尾。

命令START也使用此鍵來查找應用程序在回答這個註冊鍵下鍵excel.exe也解釋上Where is 「START」 searching for executables?

的Microsoft Office的各個版本的安裝程序。

所以在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 

不同的輸出在回答書面獲取包含空格的註冊表項的默認字符串的字符串值,批號解釋上Read words separated by space & string value also contains space in a batch script

由於完全沒有安裝Microsoft Excel,所以添加處理像註冊表項這樣的錯誤情況的額外代碼根本不存在是一種很好的編碼實踐。

但是批處理代碼可以做什麼命令START分別是Windows shell函數ShellExecuteEx在命令提示符窗口中使用命令行嗎?

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左邊的start ...在標籤RunInstall下方的塊中。

此批處理代碼包含4行,只有SET RegValue。這4行僅輸出從Windows註冊表中查詢成功的字符串值,並存儲在環境變量RegValue中。這4個命令有助於理解執行批處理文件時會發生什麼。這四條命令行最後應該從批處理文件中刪除,並且還應該用大寫字母寫入單個的命令行。

注意:如果預期註冊表項不存在或其默認值爲空字符串,測試會發生什麼很容易。只需在開頭的行上插入單個字符,如#,然後再找不到已修改的註冊表項。

爲了解所使用的命令及其工作方式,請打開命令提示符窗口,在其中執行以下命令,並仔細閱讀爲每個命令顯示的所有幫助頁面。

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

閱讀也是微軟的文章關於Using Command Redirection Operators2>nul解釋。重定向操作>必須插入符號^可以逃過命令行被解釋爲文字字符時,Windows命令解釋程序進程執行命令FOR執行該嵌入式reg.exe命令行中單獨的命令過程,此命令行啓動在背景中。

+0

哇!謝謝你的回答!這裏要處理很多東西。開始實驗... –

+0

該解決方案非常適合動態獲取EXCEL.EXE路徑的方法。 –