[英]Add Version Info to Excel file properties with VBA, read with PowerShell
我的目標是將版本號添加到 Excel 文件的文件屬性中,然后可以使用 PowerShell 從外部讀取。
如果我運行(Get-Item "example.xls").VersionInfo
我會得到空白的 ProductVersion 和 FileVersion。
ProductVersion FileVersion FileName
-------------- ----------- --------
example.xls
我找不到從 VBA 設置這些屬性的方法。 我確實找到了獲取\\設置修訂號的方法:
Public Function FileVersion() As String
With ThisWorkbook.BuiltinDocumentProperties
FileVersion = .Item("Revision Number").Value
End With
End Function
Public Sub UpdateFileVersion()
With ThisWorkbook.BuiltinDocumentProperties
.Item("Revision Number").Value = .Item("Revision Number").Value + 1
End With
End Sub
但是,我找不到從 PowerShell 讀取修訂號的方法。 我要么需要從 PowerShell 讀取修訂號,要么需要從 VBA 設置 ProductVersion 和 FileVersion。 我會接受導致在 Excel 中設置在 Excel 之外可見的文件版本的任何組合,理想情況下我希望能夠使用所有這些屬性。
您可以在此處查看我嘗試從 PowerShell 獲取的Revision Number
以及無法從 VBA 設置的Version Number
:
如果您右鍵單擊一個文件並在“詳細信息”選項卡中點擊屬性,您將看到所有可用內容。
如果您不想將 COM 放入 EOM(Excel 對象模型),那么您需要先在 EOM 中分配這些,然后通過 PowerShell 擊中它們,就像 Windows 資源管理器顯示它們或枚舉元數據一樣。
所以,像...
### Get file properties
##
Get-ItemProperty -Path 'D:\Temp' -filter '*.xl*' |
Format-list -Property * -Force
或者
### Enumerate file properties in PowerShell
# get the first file
(
$Path = ($FileName = (Get-ChildItem -Path 'D:\Temp' -Filter '*.xl*').FullName ) |
Select-Object -First 1
)
$shell = New-Object -COMObject Shell.Application
$folder = Split-Path $path
$file = Split-Path $path -Leaf
$shellfolder = $shell.Namespace($folder)
($shellfile = $shellfolder.ParseName($file))
<#
You'll need to know what the ID of the extended attribute is.
This will show you all of the ID's:
#>
0..287 |
Foreach-Object { '{0} = {1}' -f $_, $shellfolder.GetDetailsOf($null, $_) }
# Once you find the one you want you can access it like this:
$shellfolder.GetDetailsOf($shellfile, 216)
至於這...
謝謝,但你的清單,以及我在 Excel 文件上運行它得到的清單,不包含修訂版
……這樣試試。
從這里開始:
# Getting specific properties fomr MS Word
$Path = "D:\Temp"
$ObjectProperties = "Author","Keywords","Revision number"
$Application = New-Object -ComObject Word.Application
$Application.Visible = $false
$Binding = "System.Reflection.BindingFlags" -as [type]
$Select = "Name","Created"
$Select += $ObjectProperties
ForEach ($File in (Get-ChildItem $Path -Include '*.docx' -Recurse))
{ $Document = $Application.Documents.Open($File.Fullname)
$Properties = $Document.BuiltInDocumentProperties
$Hash = @{}
$Hash.Add("Name",$File.FullName)
$Hash.Add("Created",$File.CreationTime)
ForEach ($Property in $ObjectProperties)
{ $DocProperties = [System.__ComObject].InvokeMember("item",$Binding::GetProperty,$null,$Properties,$Property)
Try {$Value = [System.__ComObject].InvokeMember("value",$binding::GetProperty,$null,$DocProperties,$null)}
Catch {$Value = $null}
$Hash.Add($Property,$Value)
}
$Document.Close()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($Properties) |
Out-Null
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($Document) |
Out-Null
New-Object PSObject -Property $Hash |
Select $Select
}
$Application.Quit()
# Results
<#
Name : D:\Temp\Test.docx
Created : 06-Feb-20 14:23:55
Author : ...
Keywords :
Revision number : 5
#>
# Getting specific properties fomr MS Excel
$Path = "D:\Temp"
$ObjectProperties = "Author","Keywords","Revision number"
$Application = New-Object -ComObject excel.Application
$Application.Visible = $false
$Binding = "System.Reflection.BindingFlags" -as [type]
$Select = "Name","Created"
$Select += $ObjectProperties
ForEach ($File in (Get-ChildItem $Path -Include '*.xlsx' -Recurse))
{ $Document = $Application.Workbooks.Open($File.Fullname)
$Properties = $Document.BuiltInDocumentProperties
$Hash = @{}
$Hash.Add("Name",$File.FullName)
$Hash.Add("Created",$File.CreationTime)
ForEach ($Property in $ObjectProperties)
{ $DocProperties = [System.__ComObject].InvokeMember("item",$Binding::GetProperty,$null,$Properties,$Property)
Try {$Value = [System.__ComObject].InvokeMember("value",$binding::GetProperty,$null,$DocProperties,$null)}
Catch {$Value = $null}
$Hash.Add($Property,$Value)
}
$Document.Close()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($Properties) |
Out-Null
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($Document) |
Out-Null
New-Object PSObject -Property $Hash |
Select $Select
}
$Application.Quit()
# Results
<#
Name : D:\Temp\Test.xlsx
Created : 25-Nov-19 20:47:15
Author : ...
Keywords :
Revision number : 2
#>
注意點:我的意思是添加來源:
關於設置屬性,請參閱 MS PowerShellgallery.com 中的此 Word 示例,當然可以針對其他 Office 文檔對其進行調整。
附加的腳本使用 Word 自動化模型來設置特定的內置 Word 文檔屬性。 它是作為如何執行此操作的示例提供的。 您將需要修改用於查找文件的模式,以及您希望分配的內置 Word 屬性和值。
如上所述,獲取是同一件事......
此腳本將允許您指定特定的 Word 內置文檔屬性。 它返回一個對象,其中包含指定的 Word 文檔屬性以及這些文檔的路徑。 由於 PowerShell 對象返回,因此您可以過濾和搜索不同的信息 fr
感謝@postanote 為我指明了正確的方向。 提供的代碼都沒有對我來說是開箱即用的。
這是我最終從 Excel 文檔中提取修訂號的操作:
<# Get-Excel-Property.ps1 v1.0.0 by Adam Kauffman 2020-02-03
Returns the property value from an Excel File
#>
param(
[Parameter(Mandatory=$true, Position=0)][string]$FilePath,
[Parameter(Mandatory=$true, Position=1)][string]$ObjectProperties
)
Function Get-Property-Value {
[CmdletBinding()]Param (
[Parameter(Mandatory = $true)]$ComObject,
[Parameter(Mandatory = $true)][String]$Property
)
$Binding = "System.Reflection.BindingFlags" -as [type]
Try {
$ObjectType = $ComObject.GetType()
$Item = $ObjectType.InvokeMember("Item",$Binding::GetProperty,$null,$ComObject,$Property)
return $ObjectType.InvokeMember("Value",$Binding::GetProperty,$null,$Item,$null)
}
Catch {
return $null
}
}
# Main
$Application = New-Object -ComObject Excel.Application
$Application.Visible = $false
$Document = $Application.Workbooks.Open($FilePath)
$Properties = $Document.BuiltInDocumentProperties
$Hash = @{}
$Hash.Add("Name",$FilePath)
ForEach ($Property in $ObjectProperties)
{
$Value = Get-Property-Value -ComObject $Properties -Property $Property
$Hash.Add($Property,$Value)
}
# COM Object Cleanup
if ($null -ne $Document) {
$Document.Close($false)
Remove-Variable -Name Document
}
if ($null -ne $Properties) {
Remove-Variable -Name Properties
}
if ($null -ne $Application) {
$Application.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($Application) | Out-Null
Remove-Variable -Name Application
}
[gc]::collect()
[gc]::WaitForPendingFinalizers()
# Show collected information
New-Object PSObject -Property $Hash
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.