代码之家  ›  专栏  ›  技术社区  ›  Tom H

Powershell中的数据类型转换问题

  •  0
  • Tom H  · 技术社区  · 14 年前

    我正在编写一个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
    }
    

    但是,我一直收到一个错误,“Cannot convert argument”1,值为“System.Object[]”,用于“AttachDatabase”的类型为“System.Collections.Specialized.StringCollection”。

    我试着在不同的地方显式地声明数据类型,但是这只会改变我得到错误的位置(或者类似的位置)。我还将参数声明更改为使用字符串集合,而不是不走运的对象。

    我从一个字符串集合开始,最终想要使用一个字符串集合。我似乎无法让Powershell在某个时候停止尝试将其转换为泛型对象。

    谢谢!

    1 回复  |  直到 14 年前
        1
  •  1
  •   Community Egal    7 年前

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

      ...
      , $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-Files Attach-Database 电话。