在 Revit API 中,我知道我可以获得当前正在运行的 Revit 实例的版本 ( ControlledApplication.VersionBuild
, ControlledApplication.VersionName
, ControlledApplication.VersionNumber
)。但是,我想在打开 Revit 文件之前获取它本身的版本。这样,当用户在较新版本的 Revit 中打开较旧的 Revit 文件时,我可以停止自动升级对话框。我正在使用 Revit 2013 并期待 2011、2012 和 2013 的文件。
2 回答
正如您所说,Revit 文件格式是结构化存储文档,您需要的信息存储在BasicFileInfo流中。
这是演示如何提取 BasicFileInfo 数据的完整控制台应用程序
不幸的是,我不知道 BasicFileInfoStream 的格式。但是,如果您将其作为字符串读取,则可以获得创建文件的版本。
读取唯一的 BasicFileInfo 比读取整个文件要好得多。想象一下,如果 Revit 项目超过 500 MB 或更多。你打电话时
string fileContents = streamReader.ReadToEnd();
您将整个文件写入内存。
此外,大文件上的正则表达式工作缓慢。
我认为你应该使用
var rawString = System.Text.Encoding.Unicode.GetString(rawData);
从我的示例中并在 rawString 中使用 Regex 而不是整个文件。
希望能帮助到你。
更新:
我完全忘记了。在 Revit 2013 中,您可以使用类SavedInCurrentVersion
的属性BasicFileInfo
来确定文件是否保存在当前 Revit 版本中。如果您想获取保存文件的版本(如您的问题标题中所示),您可以使用SavedInVersion
同一类的属性。您可以使用该BasicFileInfo.Extract
方法获取BasicFileInfo
.
我仔细查看了我的问题中发布的讨论组,发现版本信息在文件的其他乱码中实际上是人类可读的。“.rvt”文件以 OLE 格式存储,因此如果使用结构化存储查看器等工具,您可以查看内容。它将位于BasicFileInfo下。
如果您愿意,那么您可能可以使用.NET 的 OLE 库来读取数据,但我使用 aStreamReader
和 aRegex
代替。
这是正则表达式:
Revit\sArchitecture\s(?<Year>\d{4})\s(Build:\s(?<Build>\w*)\((?<Processor>\w{3})\)\)
这是代码:
private void ControlledApplication_DocumentOpening (object sender,
DocumentOpeningEventArgs e)
{
FileInfo revitFileToUpgrade = new FileInfo(e.PathName);
Regex buildInfoRegex = new Regex(
@"Revit\sArchitecture\s(?<Year>\d{4})\s\(Build:\s(?<Build>\w*)\((<Processor>\w{3})\)\)");
using(StreamReader streamReader =
new StreamReader(e.PathName, Encoding.Unicode))
{
string fileContents = streamReader.ReadToEnd();
Match buildInfo = buildInfoRegex.Match(fileContents);
string year = buildInfo.Groups["Year"].Value;
string build = buildInfo.Groups["Build"].Value;
string processor = buildInfo.Groups["Processor"].Value;
}
}
这将允许您获取年份、内部版本号和处理器类型。但是请注意,我的版本专门针对Architecture进行检查,因此您需要针对 MEP 或 Structural 进行修改。
更新:
- 如果您使用的是Revit 2013 或更高版本,请参阅我的其他答案。
- 如果您使用的是Revit 2012 或更早版本,请将上面的 Regex 与Victor 的答案结合起来,以便更好地阅读 BasicFileInfo(而不是全部内容)。