2010-11-19 41 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。