Проблемы преобразования типов данных в Powershell - PullRequest
0 голосов
/ 11 ноября 2010

Я пишу сценарий Powershell, который извлечет набор файлов данных из ZIP-файла и затем присоединит их к серверу.Я написал функцию, которая заботится о распаковке, и, так как мне нужно захватить все файлы, чтобы я знал, что я прикрепляю, я возвращаю это из функции:

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
}

Затем я вызываюдругая функция для фактического присоединения базы данных (я удалил некоторый код, который проверяет существование базы данных, но это не должно влиять здесь):

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
}

Я продолжаю получать сообщение об ошибке: «Не могупреобразовать аргумент "1", со значением: "System.Object []", для "AttachDatabase", чтобы ввести "System.Collections.Specialized.StringCollection" ".

Я попытался объявить типы данных явно вразличные точки, но это просто меняет место, где я получаю ошибку (или одну похожую на нее).Я также изменил объявление параметра, чтобы использовать коллекцию строк вместо объекта без удачи.

Я начинаю с коллекции строк и в конечном итоге хочу использовать коллекцию строк.Кажется, я просто не могу заставить Powershell перестать пытаться преобразовать его в общий объект в какой-то момент.

Есть предложения?

Спасибо!

1 Ответ

1 голос
/ 12 ноября 2010

Похоже, вы должны возвращать имена, используя оператор запятой:

  ...
  , $extracted_file_names
}

, чтобы избежать "разворачивания" коллекции к ее элементам и сохранения исходного объекта коллекции.

Было несколько таких вопросов, вот только пара:

Странное поведение в функции PowerShell, возвращающей DataSet / DataTable

Загрузкасериализованный DataTable в PowerShell - возвращает массив DataRows, а не DataTable

ОБНОВЛЕНИЕ:

Этот похожий код работает:

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

Как ожидается, его выводis:

System.Collections.Specialized.StringCollection
xxxyyyzzz

Если я уберу предложенную запятую, то получим:

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

Симптомы выглядят одинаково, поэтому решение, по-видимому, должно работать, если нетдругие нежелательные преобразования / развёртывания в пропущенном коде между Unzip-Files и Attach-Database вызовами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...