2010-11-19 76 views
6

我们最近从Delphi 2006升级到Delphi 2007,项目文件从.bdsproj更改为.dproj如何将bdsproj批量转换为dproj?

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

我想出了这个过程使用打开所有的命令行项目:

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

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

是否有有效的方法将多个.bdsproj转换为.dproj

注意:上述命令行中的'find'是一个类似于UNIX的查找(例如MKS或GNU),用于搜索文件,而不是搜索文件内的文本的Windows查找。

+2

伤心Embarcadero没有可用于执行转换的命令行工具。 – 2010-11-19 14:25:40

+0

bdsproj文件与其相应的dproj文件之间的文本区别是什么?可能不多,我期望。它们是否足够相似以至于一个简单的程序可以将一个程序转换成另一个程序而不必加载Delphi?他们是XML,对吧?我在想一个简单的XSLT可以一次完成所有的事情。 – 2010-11-19 17:40:20

+0

@Rob,我认为他们也会相似,在某些方面他们也是。但是有些差异使得它不仅仅是从一个XML到另一个XML的翻译。每个文件都包含不在其他信息中的信息。例如。 dproj包含来自dpr以及来自bdsproj的信息,并且UsePackages设置在bdsproj中不是dproj。这些只是我很快注意到的差异,可能还有其他的。一旦我看到它不是一个直接的转换,我停止了寻找。 – WileCau 2010-11-20 00:05:06

回答

3

以下是使用PowerShell的find解决方案的发烧友版本。它在指定的目录下搜索bdsproj文件,并生成包含所有项目的bdsgroup

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

提示:

  • -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

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

  • 选择40个项目
  • 将它们拖动到IDE
  • 单击是40倍
  • 保存所有
  • 关闭所有
  • 重复直到完成。
+1

似乎对于一次性任务来说足够有效。 – 2010-11-19 07:29:56

+0

只有限制:不允许在项目组中重复项目名称 - 我后悔在项目组中使用像'Unittests'这样的项目名称,IDE不停地向我倾诉;) – mjn 2010-11-19 07:58:07

2

也许你可以使用类似的find(也许有点德尔福PROGRAMM)命令行创建的所有项目* .bdsgroup文件并打开,在D2007。