Ik wil graag een inventaris maken van mijn muziekcollectie met behulp van Powershell, m.a.w. bepaalde metadata-tags van die bestanden naar een .txt-bestand schrijven. Mijn collectie zit in een soort mapstructuur, in een (vergeefse) poging het overzichtelijk te houden. Ook staan er ook nog wat .mp3-tjes los in de hoofdmap zelf. De bedoeling is dus het oplijsten van alle niet-mapelementen uit de hoofdmap, dus inclusief die in de submappen. Bij het testen (het naar het scherm schrijven i.p.v. naar de txt) blijkt dat de .mp3-tjes in de hoofdmap worden opgelijst zoals de bedoeling is, maar de submappen van de hoofdmap niet worden doorzocht. De mappen zelf vindt hij wel. Hieronder vindt u mijn eerste poging:
#//////////////////////////////////////////////////////////////////////////////////
$map = "C:\Users\Ik\Music\muziek"
function lijstopties(){
foreach($submap in $map){
$objShell = New-Object -ComObject Shell.Application
$objMap = $objShell.namespace($subMap)
foreach ($bestand in $objMap.items()){
for ($a=0 ; $a -le 266; $a++){
$objMap.getDetailsOf($bestand, $a)
}
}
}
}
lijstopties
#/////////////////////////////////////////////////////////////////////////////////////
Zoals hierboven gezegd faalt dit jammerlijk: "foreach($submap in $map)" was een beetje wishful thinking, en geeft enkel $map terug, $map is immers een string. Dat is de reden waarom alleen de hoofdmap wordt doorzocht, namespace wordt alleen voor de hoofdmap veranderd.
Wat googlen leert dat
$items = Get-ChildItem -Recurse "C:\Users\Ik\Music\muziek"| where {$_.psiscontainer -ne $true}
wel doet wat ik wil, en veel simpeler is dan het gepruts met de lussen.
Probleem is nu, ik kan op vb. het 6de element uit $items niet meer "$objMap.getDetailsOf($items[5], $a)" toepassen om de metadata te bekomen. Powershell ziet dit blijkbaar als een variant op "$objMap.getDetailsOf($objMap.items(), $a)", wat de naam van het metadatadeel geeft.
vb: $objMap.getDetailsOf($items[5], 0)
zal "Name" geven, terwijl ik die "Name" ingevuld wil zien door de naam van het bestand.
Na nog wat gegoogle en geprobeer dacht ik te mogen besluiten dat getdetailsof() als eerste parameter een system.marshalbyrefobject wil, terwijl alle $items[i] system.io.fileinfo blijken te zijn, een subklasse van system.marshalbyrefobject. Ik had gehoopt via de methode MemberwiseClone(true) van system.io.fileinfo de bijhorende system.marshalbyrefobject te kunnen vinden.
Een of meerdere elementen in die redenering kloppen blijkbaar niet, want:
($items[1]).MemberWiseClone().gettype()
geeft:
Method invocation failed because [System.IO.FileInfo] doesn't contain a method named 'MemberWiseClone'.
At I:\rest\powershell\Untitled1.ps1:8 char:28
+ ($items[1]).MemberWiseClone <<<< ().gettype()
+ CategoryInfo : InvalidOperation: (MemberWiseClone:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Mijn vraag is dus: hoe kan ik system.io.fileinfo "casten" (is eigenlijk het goede woord niet) naar system.marshalbyrefobject? Of beter, hoe verkrijg ik het system.marshalbyrefobject waarvan $items[5] de
system.io.fileinfo is?
Oja, de reden waarom ik niet gewoon vb:
$items = Get-ChildItem -Recurse "C:\Users\Ik\Music\muziek"| where {$_.psiscontainer -ne $true}|select Name
gebruik, is omdat je volgens mij bij select "hard" moet coderen wat je wil dat geselecteerd wordt (na elkaar pipelinen gaat natuurlijk niet). Mijn uiteindelijke doel is een gebruiker te laten ingeven (door middel van getallen) welke metadata hij wil. Dan moet ik gewoon getdetailsof() voor die getallen oproepen, en is er niks hard te coderen.
Het enige waar ik dus aan vast zou willen houden is het gebruik van dat getdetailsof(), tenzij ook daarvoor een betere oplossing bestaat natuurlijk (bij gebruikersinput).
Dank u wel!
#//////////////////////////////////////////////////////////////////////////////////
$map = "C:\Users\Ik\Music\muziek"
function lijstopties(){
foreach($submap in $map){
$objShell = New-Object -ComObject Shell.Application
$objMap = $objShell.namespace($subMap)
foreach ($bestand in $objMap.items()){
for ($a=0 ; $a -le 266; $a++){
$objMap.getDetailsOf($bestand, $a)
}
}
}
}
lijstopties
#/////////////////////////////////////////////////////////////////////////////////////
Zoals hierboven gezegd faalt dit jammerlijk: "foreach($submap in $map)" was een beetje wishful thinking, en geeft enkel $map terug, $map is immers een string. Dat is de reden waarom alleen de hoofdmap wordt doorzocht, namespace wordt alleen voor de hoofdmap veranderd.
Wat googlen leert dat
$items = Get-ChildItem -Recurse "C:\Users\Ik\Music\muziek"| where {$_.psiscontainer -ne $true}
wel doet wat ik wil, en veel simpeler is dan het gepruts met de lussen.
Probleem is nu, ik kan op vb. het 6de element uit $items niet meer "$objMap.getDetailsOf($items[5], $a)" toepassen om de metadata te bekomen. Powershell ziet dit blijkbaar als een variant op "$objMap.getDetailsOf($objMap.items(), $a)", wat de naam van het metadatadeel geeft.
vb: $objMap.getDetailsOf($items[5], 0)
zal "Name" geven, terwijl ik die "Name" ingevuld wil zien door de naam van het bestand.
Na nog wat gegoogle en geprobeer dacht ik te mogen besluiten dat getdetailsof() als eerste parameter een system.marshalbyrefobject wil, terwijl alle $items[i] system.io.fileinfo blijken te zijn, een subklasse van system.marshalbyrefobject. Ik had gehoopt via de methode MemberwiseClone(true) van system.io.fileinfo de bijhorende system.marshalbyrefobject te kunnen vinden.
Een of meerdere elementen in die redenering kloppen blijkbaar niet, want:
($items[1]).MemberWiseClone().gettype()
geeft:
Method invocation failed because [System.IO.FileInfo] doesn't contain a method named 'MemberWiseClone'.
At I:\rest\powershell\Untitled1.ps1:8 char:28
+ ($items[1]).MemberWiseClone <<<< ().gettype()
+ CategoryInfo : InvalidOperation: (MemberWiseClone:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Mijn vraag is dus: hoe kan ik system.io.fileinfo "casten" (is eigenlijk het goede woord niet) naar system.marshalbyrefobject? Of beter, hoe verkrijg ik het system.marshalbyrefobject waarvan $items[5] de
system.io.fileinfo is?
Oja, de reden waarom ik niet gewoon vb:
$items = Get-ChildItem -Recurse "C:\Users\Ik\Music\muziek"| where {$_.psiscontainer -ne $true}|select Name
gebruik, is omdat je volgens mij bij select "hard" moet coderen wat je wil dat geselecteerd wordt (na elkaar pipelinen gaat natuurlijk niet). Mijn uiteindelijke doel is een gebruiker te laten ingeven (door middel van getallen) welke metadata hij wil. Dan moet ik gewoon getdetailsof() voor die getallen oproepen, en is er niks hard te coderen.
Het enige waar ik dus aan vast zou willen houden is het gebruik van dat getdetailsof(), tenzij ook daarvoor een betere oplossing bestaat natuurlijk (bij gebruikersinput).
Dank u wel!