Добавление информации о версии в свойства файла Excel с помощью VBA, чтение с помощью PowerShell - PullRequest
0 голосов
/ 05 февраля 2020

Моя цель - добавить номер версии к свойствам файла 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, либо мне нужно установить ProductVersion и FileVersion из VBA. Я бы согласился с любой комбинацией вещей, которая приводит к установке версии файла в Excel, которая видна за пределами Excel, в идеале я хотел бы иметь возможность использовать все эти свойства.

Вы можете увидеть Revision Number Я пытаюсь получить от PowerShell, а также Version Number, который я не могу установить из VBA здесь:

enter image description here

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Если вы щелкнете правой кнопкой мыши по файлу и нажмете свойства на вкладке Подробности, вы увидите все, что доступно.

Если вы не хотите использовать COM в EOM (объектная модель Excel), вам нужно сначала назначить их в EOM, а затем нажать на них через PowerShell, так как Windows Explorer показывает их или enum metadata.

Итак, что-то вроде ...

### 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, не содержат Revision

... попробуйте это так.

Получено из здесь:

Эй, сценарист! Как я могу перечислить все свойства документа Microsoft Word?

и здесь:

# 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
#>

Примечание: я имел в виду добавить источники:

Что касается параметров настройки, см. этот пример Word с MS PowerShellgallery.com, который, конечно, можно настроить для других документов Office.

Задать спецификацию c свойства документа Word с помощью PowerShell

В прилагаемом скрипте используется модель автоматизации Word для установки конкретного свойства документа BuiltIn Word. Это приведено в качестве примера того, как это сделать. Вам нужно будет изменить шаблон, используемый для поиска файлов, а также встроенное свойство Word и значение, которое вы будете назначать sh.

Как указано выше, получение - это то же самое ...

Получить свойства встроенного документа Word

Этот скрипт позволит вам указать определенные c свойства встроенного документа Word. Он возвращает объект, содержащий указанные свойства документа word, а также путь к этим документам. Поскольку объект PowerShell возвращается, вы можете фильтровать и искать различную информацию fr

0 голосов
/ 12 февраля 2020

Спасибо @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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...