簡體   English   中英

使用NSIS檢測目標卷是否為NTFS

[英]Detecting if the target volume is NTFS using NSIS

我正在使用NSIS為需要在NTFS卷上運行的程序創建安裝程序。 如何檢測路徑安裝是否在NTFS卷上並采取相應措施(顯示幫助/警告消息)?

使用外部工具並非總是一個好主意(並非Windows的Home版本中存在每個命令行工具)總是最好使用系統插件直接調用正確的API。

!include LogicLib.nsh

StrCpy $0 "c:\"
System::Call 'Kernel32::GetVolumeInformation(t "$0",t,i ${NSIS_MAX_STRLEN},*i,*i,*i,t.r1,i ${NSIS_MAX_STRLEN})i.r0'
${If} $0 <> 0
    MessageBox mb_ok "fs=$1"
${EndIf}

但是在這種情況下,您不應檢查文件系統類型,而應查找所需的實際功能(壓縮,加密,連接,稀疏文件等)。

!define FILE_SUPPORTS_ENCRYPTION 0x00020000
!define FILE_READ_ONLY_VOLUME 0x00080000
!define FILE_VOLUME_QUOTAS 0x00000020

!macro MakeBitFlagYesNo flags bit outvar
IntOp ${outvar} ${flags} & ${bit}
${IfThen} ${outvar} <> 0 ${|} StrCpy ${outvar} "Yes" ${|}
${IfThen} ${outvar} == 0 ${|} StrCpy ${outvar} "No" ${|}
!macroend

StrCpy $0 "c:\"
System::Call 'Kernel32::GetVolumeInformation(t "$0",t,i ${NSIS_MAX_STRLEN},*i,*i,*i.r1,t,i ${NSIS_MAX_STRLEN})i.r0'
${If} $0 <> 0
    !insertmacro MakeBitFlagYesNo $1 ${FILE_SUPPORTS_ENCRYPTION} $2
    !insertmacro MakeBitFlagYesNo $1 ${FILE_READ_ONLY_VOLUME} $3
    !insertmacro MakeBitFlagYesNo $1 ${FILE_VOLUME_QUOTAS} $4
    MessageBox mb_ok "flags=$1 $\nFILE_SUPPORTS_ENCRYPTION=$2$\nFILE_READ_ONLY_VOLUME=$3$\nFILE_VOLUME_QUOTAS=$4"
${EndIf}

我不熟悉NSIS,但是您可能會發現這個小的“ DOS”技巧很有幫助。

我確實注意到可以使用NSIS打開文件,所以這可能會有所幫助-

chkntfs c: | find "file system" > yourfile.abc

CHKNTFS是用於管理CHKDSK操作的實用程序,但是如果您在沒有命令行開關的情況下運行該命令,它將僅報告結果。

“ C:”是您感興趣的驅動器-

當然,您可以從命令提示符處運行此命令以查看結果,而沒有“> yourfile.abc”部分,這是將輸出定向到該文件的原因。

在任何人對此投反對票之前,我只是以發人深省的建議為由,也許是引發真正的解決方案,並記住一個座右銘-親切...大聲笑...

編輯:此代碼片段可能會有所幫助-我沒有辦法真正測試一下-這是編譯時間的用法-您很可能需要運行時...但是,它可能會給您一個想法...

我“假定”沒有一個已經命名為NTFS的定義-如果是這樣,請相應地更改它。 第一個調用創建包含文件,第二個調用附加到該文件(雙>)... FIND的/ C選項僅對包含搜索項的數字行進行計數。 因此,結果為0或1。

!system 'echo "!define NTFS=" > newinclude.nsh'
!system 'chkntfs c: | find /c "NTFS" >> newinclude.nsh'
!include newinclude.nsh
!ifdef NTFS
  !echo "NTFS is defined and value should reflect accordingly; 0=NO, 1=Yes it is NTFS"
!endif

編輯:(再次,大聲笑)

這是一個片段,它將設置一個環境變量,據我所知,它在運行時應該很容易閱讀-您可以構造一個變量來執行,從而相應地替換驅動器號。

ExecWait 'chkntfs c: | find /c "NTFS"  > tempfile.abc'
ExecWait 'set /p NTFS= < tempfile.abc'
Exec     'del tempfile.abc'

現在,如果不是NTFS,則稱為NTFS的環境變量應保留0,如果要檢查的卷為NTFS,則應保留1。

或直接

ExecWait 'chkntfs c: | find /c "NTFS"' $0

$ 0保留返回碼; 結果有點倒退,因為這是錯誤返回碼。 如果為0,則表示已擁有NTFS,而> 0表示沒有NTFS。

您的測試將需要在運行時進行,因此Borzio的答案本身不會起作用。

看起來ExecWait命令似乎不允許重定向,因此以這種方式執行然后檢查文件內容將不起作用。

在我看來,您最好的選擇是選擇以下一項:

  • 制作一個將運行chkntfs的批處理文件,然后根據結果設置錯誤級別
  • 編寫C / C ++ / VB / etc。 應用會運行chkntfs,然后根據結果設置錯誤級別
  • 編寫C / C ++ / VB / etc。 使用Win32 API確定文件系統的應用程序
  • 為NSIS編寫一個插件,該插件將使用Win32 API確定文件系統

編輯: Borzio在我完成我的工作之前更新了他的:)

您可能需要添加在Winamp論壇上找到的內容: 具有文件重定向的ExecWait

  ExpandEnvStrings $1 %COMSPEC%
  ExecWait '"$1" /C chkntfs c: | find /c "NTFS"' $0

沒有ExpandEnvStrings $1 %COMSPEC% ,它在我的系統上無法生成重定向文件。

我已經測試了上面的內容,並且確實可以使用,對於NTFS為0,對於非NTFS為1。

該方法的唯一可能的缺點是在執行代碼期間會短暫彈出命令窗口。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM