开发者

Data type conversion issues in Powershell

I'm writing a Powershell script that will extract a set of data files from a ZIP file and will then attach them to a server. I've written a function that takes care of the unzip and since I need to grab all of the files so that I know what I'm attaching I return that from the function:

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
}

I then call another function to actually attach the database (I've removed some code that checks for existence of the database, but that shouldn't affect things here):

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
}

I keep getting an error though, "Cannot convert argument "1", with value: "System.Object[]", for "AttachDatabase" to type "System.Collections.Specialized.StringCollection"".

I've tried declaring the data types explicitly at various points, but that just changes the location where I get the error (or one similar to it). I've also changed the parameter declaration to use the string collection instead of object开发者_开发知识库 with no luck.

I'm starting with a string collection and ultimately want to consume a string collection. I just don't seem to be able to get Powershell to stop trying to convert it to a generic Object at some point.

Any suggestions?

Thanks!


It looks like you should return the names using the comma operator:

  ...
  , $extracted_file_names
}

to avoid "unrolling" the collection to its items and to preserve the original collection object.

There were several questions like this, here is just a couple:

Strange behavior in PowerShell function returning DataSet/DataTable

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

UPDATE:

This similar code works:

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

As expected, its output is:

System.Collections.Specialized.StringCollection
xxxyyyzzz

If I remove the suggested comma, then we get:

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

The symptoms look the same, so the solution presumably should work, too, if there are no other unwanted conversions/unrolling in the omitted code between Unzip-Files and Attach-Database calls.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜