2010-11-11 5 views
0

J'écris un script Powershell qui va extraire un ensemble de fichiers de données à partir d'un fichier ZIP et les attacher ensuite à un serveur. J'ai écrit une fonction qui prend en charge la Décompressez et que je dois saisir tous les fichiers pour que je sache ce que j'attacher mon retour que de la fonction:Problèmes de conversion de type de données dans Powershell

function Unzip-Files 
{ 
    param([string]$zip_path, [string]$zip_filename, [string]$target_path, [string]$filename_pattern) 

    # Append a \ if the path doesn't already end with one 
    if (!$zip_path.EndsWith("\")) {$zip_path = $zip_path + "\"} 
    if (!$target_path.EndsWith("\")) {$target_path = $target_path + "\"} 

    # We'll need a string collection to return the files that were extracted 
    $extracted_file_names = New-Object System.Collections.Specialized.StringCollection 

    # We'll need a Shell Application for some file movement 
    $shell_application = New-Object -com shell.Application 

    # Get a handle for the target folder 
    $target_folder = $shell_application.NameSpace($target_path) 

    $zip_full_path = $zip_path + $zip_filename 

    if (Test-Path($zip_full_path)) 
    { 
     $target_folder = $shell_application.NameSpace($target_path) 
     $zip_folder = $shell_application.NameSpace($zip_full_path) 

     foreach ($zipped_file in $zip_folder.Items() | Where {$_.Name -like $filename_pattern}) 
     { 
      $extracted_file_names.Add($zipped_file.Name) | Out-Null 
      $target_folder.CopyHere($zipped_file, 16) 
     } 
    } 

    $extracted_file_names 
} 

J'appelle alors une autre fonction pour attacher réellement la base de données (je l'ai supprimé un code qui vérifie l'existence de la base de données, mais cela ne devrait pas affecter les choses ici):

function Attach-Database 
{ 
    param([object]$server, [string]$database_name, [object]$datafile_names) 

    $database = $server.Databases[$database_name] 

    $server.AttachDatabase($database_name, $datafile_names) 

    $database = $server.Databases[$database_name] 

    Return $database 
} 

Je continue à obtenir une erreur si, « Impossible de convertir argument » 1 ", avec la valeur:" System.Object [] ", pour" AttachDatabase "pour taper" System.Collections.Specialized.StringCollection "".

J'ai essayé de déclarer explicitement les types de données en divers points, mais cela ne fait que changer l'emplacement où j'obtiens l'erreur (ou une erreur similaire). J'ai également changé la déclaration de paramètre pour utiliser la collection de chaînes au lieu de l'objet sans chance.

Je commence par une collection de chaînes et souhaite finalement consommer une collection de chaînes. Je ne semble pas pouvoir empêcher Powershell d'essayer de le convertir en un objet générique à un moment donné.

Des suggestions?

Merci!

Répondre

1

Il semble que vous devriez retourner les noms en utilisant l'opérateur virgule:

... 
    , $extracted_file_names 
} 

pour éviter « dérouler » la collection à ses articles et de préserver l'objet de collection originale.

Il y avait plusieurs questions comme celle-ci, voici juste un couple:

Strange behavior in PowerShell function returning DataSet/DataTable

Loading a serialized DataTable in PowerShell - Gives back array of DataRows not a DataTable

MISE À JOUR:

Ce code similaire fonctionne:

Add-Type @' 
using System; 
using System.Collections.Specialized; 

public static class TestClass 
{ 
    public static string TestMethod(StringCollection data) 
    { 
     string result = ""; 
     foreach (string s in data) 
     result += s; 
     return result; 
    } 
} 
'@ 

function Unzip-Files 
{ 
    $extracted_file_names = New-Object System.Collections.Specialized.StringCollection 

    foreach ($zipped_file in 'xxx', 'yyy', 'zzz') 
    { 
     $extracted_file_names.Add($zipped_file) | Out-Null 
    } 

    , $extracted_file_names 
} 

function Attach-Database 
{ 
    param([object]$datafile_names) 

    # write the result 
    Write-Host ([TestClass]::TestMethod($datafile_names)) 
} 

# get the collection 
$names = Unzip-Files 

# write its type 
Write-Host $names.GetType() 

# pass it in the function 
Attach-Database $names 

Comme attendu, son sortie est:

System.Collections.Specialized.StringCollection 
xxxyyyzzz 

Si je supprime la virgule suggéré, puis nous obtenons:

System.Object[] 
Cannot convert argument "0", with value: "System.Object[]", 
for "TestMethod" to type "System.Collections.Specialized.StringCollection"... 

Les symptômes ressemblent, de sorte que la solution devrait vraisemblablement travailler, aussi, s'il n'y a pas d'autres conversions indésirables/déroulement dans le code omis entre les appels Unzip-Files et Attach-Database.

+0

Je l'ai déjà suggéré (ma réponse est supprimée ci-dessous) et cela n'a pas fonctionné. – Joey

+0

Eh bien, je ne peux pas voir les réponses supprimées :). Pourquoi ça n'a pas marché? –

+0

Désolé, il semble que cela ait effectivement résolu le problème. Joey, si tu récupères ta réponse, je peux l'accepter. +1 Roman. Merci à vous deux! –

Questions connexes