【问题标题】:Data type conversion issues in PowershellPowershell 中的数据类型转换问题
【发布时间】:2010-11-11 20:20:09
【问题描述】:

我正在编写一个 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 在某些时候停止尝试将其转换为通用对象。

有什么建议吗?

谢谢!

【问题讨论】:

    标签: sql-server-2008 powershell types


    【解决方案1】:

    看起来您应该使用逗号运算符返回名称:

      ...
      , $extracted_file_names
    }
    

    避免将集合“展开”到其项目并保留原始集合对象。

    有几个这样的问题,这里只是几个:

    Strange behavior in PowerShell function returning DataSet/DataTable

    Loading a serialized DataTable in PowerShell - Gives back array of DataRows not a 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
    

    正如预期的那样,它的输出是:

    System.Collections.Specialized.StringCollection
    xxxyyyzzz
    

    如果我删除建议的逗号,那么我们得到:

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

    症状看起来相同,因此如果在 Unzip-FilesAttach-Database 调用之间的省略代码中没有其他不需要的转换/展开,则该解决方案可能也应该起作用。

    【讨论】:

    • 我已经建议了(我的答案已在下面删除),但没有奏效。
    • 抱歉,看来这确实解决了问题。乔伊,如果你取消删除你的答案,那么我可以接受。 +1罗马。谢谢你们!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多