.NET - 此脚本的每个单独部分都可以工作,但是作为一个整体运行它会导致它替换我的SVG文件中的所有文本

问题描述 投票:1回答:1

我创建了一个脚本来自动化电子邮件签名图像创建。

我想要实现的步骤是:

  1. 使用用户信息替换SVG文件中的标记文本。
  2. 使用Inkscape CLI生成该SVG文件的PNG版本。
  3. 用下一个用户的信息替换SVG文件中的先前用户信息,然后重复步骤2。
  4. 重复步骤2和3,直到所有用户都有PNG电子邮件签名文件。
  5. 用原始标记替换SVG文件中的最后一个用户信息。

剧本的目标:

  1. 允许新标记动态添加到SVG,而无需更改脚本。
  2. 接受要使用的联系人和SVG模板的输入。
  3. 项目清单

这是我的脚本:

param(
  [string]$targetDirectory=$(Convert-Path .),
  [string]$width = 980,
  [string]$height = 242,
  [string]$PNGname = "$Name - Signature.png"
  )
Write-Host ""

$scriptPath = Split-Path $MyInvocation.MyCommand.Path
$CSVPrompt = 'Input the name of the CSV file you wish to use. Remember the file extension. It must be .txt or .csv and the file must be located in the same directory as this script.'
$SVGPrompt = 'Input the name of the SVG file you wish to use. Remember the file extension. It must be located in the same directory as this script.'
$targetCSV = Read-Host -Prompt $CSVPrompt
$targetSVG = Read-Host -Prompt $SVGPrompt
$contactList = import-csv $scriptPath\$targetCSV
$tags = $contactList[0] | Get-Member -Membertype 'NoteProperty' | Select-Object -ExpandProperty 'Name'

Foreach ($tag in $tags) {New-Variable -Name "$tag" -Value "[$tag]";
  New-Variable -Name "prior$tag" -Value "[$tag]";}

function ReplaceInformation
  { # Gets the contents of the target SVG file; replaces the tag with the value; Sets the content of the file.
    (Get-Content $scriptPath\signature-template.svg).replace
      (
        (Get-Variable -Name "prior$tag" -ValueOnly),
        (Get-Variable -Name $tag -ValueOnly)
      ) | Set-Content $scriptPath\signature-template.svg;
  }

function ProducePNG
  { # Simple command to use Inkscape to convert SVG to PNG of a specified size.
    & "C:\Program Files\Inkscape\inkscape.exe" $targetSVG -z -e $PNGname -w $width -h $height;
  }

function ResetInformation
  { # This takes the last user's information and resets the tags back to their generic [<tag>].
    (Get-Content $scriptPath\signature-template.svg).replace((Get-Variable -Name "prior$tag" -ValueOnly), "[$tag]") | Set-Content $scriptPath\signature-template.svg;
  }

Foreach ($contact in $contactList)
  {
    Foreach ($tag in $tags)
      { # This produces variables set to the tag value in the contact. i.e. the $Name variable with the value of $contact.Name
        Set-Variable -Name "$tag" -Value $contact.$tag;
        ReplaceInformation
        Set-Variable -Name "prior$tag" -Value $contact.$tag;
      } # The "prior" variables are for chaining replace after the initial replacement. i.e. going from [Name] to Bob to Julie without having to reset back to [Name] until the last user is done.
    ProducePNG
  }
ResetInformation

当我在Powershell中手动运行它以实现其预期目的时,每个单独的功能都能正常工作。当我运行整个脚本时,我看到很多这样的但是研究并没有告诉我它意味着什么:

OverloadDefinitions
-------------------
string Replace(char oldChar, char newChar)
string Replace(string oldValue, string newValue)

string Replace(char oldChar, char newChar)
string Replace(string oldValue, string newValue)

string Replace(char oldChar, char newChar)
string Replace(string oldValue, string newValue)

... etc etc for 100's of lines before the script completes.

我得到的是,当我在输入CSV和4个标记字段中只有2个联系人时,所以我希望看到这些行重复,对于那么多用户来说最多重复12-14次。 100次对我没有意义,除非它是每个角色一个。

我拥有的SVG文件大小为250KB,但是当我运行脚本时,我最终只得到列表中的最后一个标记以及该标记的最后一个用户值。所以250KB SVG变成了这个:

Receptionist
[Title]

以下是SVG文件中的标记示例列表,但存储在Powershell中的$tags变量中。它按字母顺序排列,但我不认为这是我的问题。这最终成为每个联系人替换的顺序:

[Email]
[Name]
[Number]
[Title]

一个与我在测试中使用的CSV相当的示例:

Name,Email,Title,Number
Bob Saggett,[email protected],Janitor,9878
Julie Grey,[email protected],Receptionist,9001

我觉得我的问题的核心在于我如何使用.NET替换方法,但从文档中,我认为我正在使用它。

https://msdn.microsoft.com/en-us/library/fk49wtc1(v=vs.110).aspx

.NET版本为4.5.1,PowerShell版本为4.0。

.net svg replace tags powershell-v4.0
1个回答
2
投票

在Powershell脚本中,您不应将调用参数传递给新行,如下所示:

(Get-Content $scriptPath\signature-template.svg).replace
  (
    (Get-Variable -Name "prior$tag" -ValueOnly),
    (Get-Variable -Name $tag -ValueOnly)
  ) | Set-Content $scriptPath\signature-template.svg;

上面的代码导致replace实际上没有参数执行。结果,Powershell只为replace打印可能的过载定义。如果在Powershell窗口中键入"".replace,则可以重复此行为:

PS C:> "".replace

OverloadDefinitions
-------------------
string Replace(char oldChar, char newChar)
string Replace(string oldValue, string newValue)

因此,要解决此问题,请更改replace调用,以便传递的参数位于同一行:

(Get-Content $scriptPath\signature-template.svg).replace((Get-Variable -Name "prior$tag" -ValueOnly), (Get-Variable -Name $tag -ValueOnly)) | Set-Content $scriptPath\signature-template.svg;

关于这个:

我得到的是,当我在输入CSV和4个标记字段中只有2个联系人时,所以我希望看到这些行重复,对于那么多用户来说最多重复12-14次。 100次对我没有意义,除非它是每个角色一个。

有一个简单的解释,为什么你观察到replace这么多错误的调用。 Get-Content不是将文件内容作为单个字符串返回,而是作为文件行的集合返回。这就是为什么replace被称为signature-template.svg文件中包含多少行的原因。

© www.soinside.com 2019 - 2024. All rights reserved.