【问题标题】:How to batch convert bdsproj to dproj?如何将 bdsproj 批量转换为 dproj?
【发布时间】:2011-05-12 10:08:09
【问题描述】:

我们最近从 Delphi 2006 升级到 Delphi 2007,项目文件从 .bdsproj 更改为 .dproj

到目前为止,我的研究表明,要创建.dproj,需要在 D2007 IDE 中打开现有项目。我们有超过 400 个.bdsproj 文件,因此手动执行此操作并不实际。

我想出的过程是使用以下命令从命令行打开所有项目:

find . -name *.bdsproj -exec bds.exe -pDelphi -ns -m "{}" ";"

这并不理想,因为它很慢(等待 BDS 加载,等待编译发生,等待 BDS 关闭,...)。

有没有一种有效的方法可以将多个.bdsproj 转换为.dproj

注意:上述命令行中的“find”是一个类似 UNIX 的 find(例如 MKS 或 GNU),它搜索文件,而不是 Windows 的 find 搜索文件中的文本。

【问题讨论】:

  • 很遗憾 Embarcadero 没有可用于进行该转换的命令行工具。
  • bdsproj 文件与其对应的 dproj 文件在文本上有什么区别?可能不多,我想。它们是否足够相似,以至于一个简单的程序可以在无需加载 Delphi 的情况下将一个转换为另一个?它们是 XML,对吧?我在想一个简单的 XSLT 可以一次性改变这一切。
  • @Rob,我认为它们也会相似,并且在某些方面它们是相似的。但是有一些差异使它不仅仅是从一个 XML 到另一个 XML 的转换。每个文件都包含另一个文件中没有的信息。例如。 dproj 包含来自 dpr 和 bdsproj 的信息,并且 bdsproj 中的 UsePackages 设置不是 dproj。这些只是我很快注意到的差异,可能还有其他差异。一旦我看到这不是直接的转换,我就停止了寻找。

标签: delphi delphi-2007


【解决方案1】:

您可以一次打开多个项目。即使使用拖放。

  • 选择 40 个项目
  • 将它们拖到 IDE 中
  • 点击是 40 次
  • 全部保存
  • 全部关闭
  • 重复直到完成。

【讨论】:

  • 对于一次性任务来说似乎足够高效。
  • 唯一限制:不允许在项目组中重复项目名称 - 我很遗憾在这里和那里使用像“Unittests”这样的项目名称,IDE 一直在对我发出哔哔声;)
【解决方案2】:

这是使用 PowerShell 的 find 解决方案的更高级版本。它在指定目录下搜索bdsproj 文件并生成包含所有项目的bdsgroup

脚本运行后,用D2007打开bdsgroup,将项目转换为dproj。 D2007 还产生一个groupproj,它似乎是 D2007 的 bdsgroup 等价物。

提示:

  • 使用-help 运行脚本以查看说明。
  • 在打开bdsgroup之前启动D2007,似乎处理项目更快。
  • 您不需要保存项目,打开它们就足以创建dproj

感谢:

这是脚本。它对我有用:o)

Param(
    $path = ".",
    $exclude = "",
    [switch]$help
)

Set-PSDebug -Strict
$ErrorActionPreference = 'Stop'

# Ensure path is fully qualified and ends with a path delimiter
$path = Join-Path (Resolve-Path $path) ""

# Output file full name ($path\scriptname.bdsproj)
$outfile = Join-Path $path ([IO.Path]::ChangeExtension($MyInvocation.MyCommand.Name, "bdsgroup"))

# Bdsgroup template
$groupXml = [xml]@"
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
    <PersonalityInfo>
        <Option>
            <Option Name="Personality">Default.Personality</Option>
            <Option Name="ProjectType"></Option>
            <Option Name="Version">1.0</Option>
            <Option Name="GUID">{$([guid]::NewGuid().ToString())}</Option>
        </Option>
    </PersonalityInfo>
    <Default.Personality>
        <Projects>
            <Projects Name="Targets"></Projects>
        </Projects>
        <Dependencies/>
    </Default.Personality>
</BorlandProject>
"@

### Functions ###

function ShowUsage()
{
    $myName = Split-Path -Leaf $MyInvocation.ScriptName
    Write-Host "Usage:"
    Write-Host "`t$myName [-path <Path>] [-exclude <Exclude>] [-help]"
    Write-Host
    Write-Host "`t-path <Path>"
    Write-Host "`t`tSpecifies the directory to begin searching for *.bdsproj."
    Write-Host "`t`tPath:" $path
    Write-Host
    Write-Host "`t-exclude <Exclude>"
    Write-Host "`t`tSpecifies a directory to exclude from the search."
    Write-Host "`t`tExclude:" $exclude
    Write-Host
    Write-Host "`t-help"
    Write-Host "`t`tDisplays this message."
    Write-Host
    Write-Host "Output will be written to:"
    Write-Host "`t" $outfile
    Write-Host
    Write-Host "Limitations:"
    Write-Host "`tDoes not support multiple directories for Path or Exclude."
}

# Get the target name.
# e.g. "D:\dev\src\foo.bdsproj" returns "foo.exe"
function GetTarget($bdsproj)
{
    $mainSource = GetMainSource($bdsproj)
    $ext = GetTargetExt($mainSource)
    Split-Path -Leaf ([IO.Path]::ChangeExtension($mainSource, $ext))
}

# Get the relative project path.
# e.g. If path is "D:\dev" then "D:\dev\src\foo.bdsproj" returns "src\foo.bdsproj"
function GetProject($bdsproj)
{
    $prefixLen = $path.Length
    $suffixLen = $bdsproj.Length - $prefixLen
    $bdsproj.Substring($prefixLen, $suffixLen)
}

# Get the fully qualified MainSource (dpr/dpk) path.
# e.g. "D:\dev\src\foo.bdsproj" returns "D:\dev\src\foo.dpr"
function GetMainSource($bdsproj)
{
    $projXml = [xml](Get-Content $bdsproj)
    $mainSource = $projXml.BorlandProject."Delphi.Personality".Source.Source |
        Where-Object { $_.Name -eq "MainSource" }

    $result = Join-Path (Split-Path -Path $bdsproj) $mainSource.InnerText

    if (-not (Test-Path $result))
    {
        throw "No MainSource (dpr/dpk) found for $bdsproj"
    }

    $result
}

# Get the target extension depending on the source type.
function GetTargetExt($mainSource)
{
    $targets = @{"package"="pkg"; "library"="dll"; "program"="exe"}
    $targetType = GetTargetType($mainSource)
    $targets[$targetType]
}

# Read the target type out of the dpr.
function GetTargetType($mainSource)
{
    $name = [IO.Path]::GetFileNameWithoutExtension($mainSource)
    $pattern = "^\s*(package|library|program)\s+$name;$"
    $matches = (Select-String -Path $mainSource -Pattern $pattern)
    if ($matches -eq $null)
    {
        throw "Unknown target type (pkg/dll/exe) for $mainSource"
    }
    $matches.Matches[0].Groups[1].Value
}

# Add a project entry to groupXml.
# e.g. <Projects Name="foo.exe">src\foo.bdsproj</Projects>
function AddProject($target, $project)
{
    $node = $groupXml.CreateElement("Projects")
    $node.SetAttribute("Name", $target)
    $node.InnerText = $project
    $groupXml.BorlandProject."Default.Personality".Projects.AppendChild($node) | Out-Null

    $targets = $groupXml.BorlandProject."Default.Personality".Projects.Projects |
        Where-Object { $_.Name -eq "Targets" }
    $targets.InnerText = $targets.InnerText + " " + $target
}

### Main ###

if ($help)
{
    ShowUsage
}
else
{
    Get-ChildItem -Path $path -Include "*.bdsproj" -Recurse |
    Where-Object { $exclude -eq "" -or $_.FullName -notmatch $exclude } |
    ForEach-Object { AddProject (GetTarget $_.FullName) (GetProject $_.FullName) }

    $groupXml.OuterXml | Out-File -Encoding "UTF8" $outfile
}

【讨论】:

    【解决方案3】:

    也许您可以使用类似于您的find 的命令行(也许还有一个小的 Delphi 程序)来创建一个包含所有项目的 *.bdsgroup 文件并在 D2007 中打开它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      • 1970-01-01
      • 2018-05-16
      • 2011-06-25
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多