原文链接:
List Linked Files and TransmissionData
我们在讨论 Revit 2012 API 新特性时提到过:现在程序可以通过类 TransmissionData 访问 Revit 文档的外部链接文件了。实际上可以在界面中不打开 Revit 文档的前提下读取外部链接文件。
不过下面这个问题让我更深入地研究了这个新特性。
提问:
使用 Revit API 可以可以获取所有链接文件的路径吗?
回答:
答案是肯定的,实际上实现也很简单。
让我们先来看看类 TransmissionData 的说明吧:
该类包含一个文档中所有外部文件的引用。
类 TransmissionData 存储的信息包括外部文件引用、目前的状态和被要求的下一个状态。换句话说,它既保存了最近一次宿主文档被打开时外部文件的状态和路径,也包含了宿主文档在下一次被打开时所要求的外部文件的状态和路径。
因此,类 TransmissionData 允许代码在不打开宿主文档的前提下对外部文件引用进行操作。该类的两个方法 ReadTransmissionData / WriteTransmissionData 分别提供了读写接口。例如:将一个 TransmissionData 对象的所有外部文件引用都设置为 LinkedFileStatus.Unloaded,然后将其作为参数调用 WriteTransmissionData 方法。则下一次文档打开时所有外部文件都不会被加载。
下面是应用 TransmissionData 实现你的需求的代码:
我们在讨论 Revit 2012 API 新特性时提到过:现在程序可以通过类 TransmissionData 访问 Revit 文档的外部链接文件了。实际上可以在界面中不打开 Revit 文档的前提下读取外部链接文件。
不过下面这个问题让我更深入地研究了这个新特性。
提问:
使用 Revit API 可以可以获取所有链接文件的路径吗?
回答:
答案是肯定的,实际上实现也很简单。
让我们先来看看类 TransmissionData 的说明吧:
该类包含一个文档中所有外部文件的引用。
类 TransmissionData 存储的信息包括外部文件引用、目前的状态和被要求的下一个状态。换句话说,它既保存了最近一次宿主文档被打开时外部文件的状态和路径,也包含了宿主文档在下一次被打开时所要求的外部文件的状态和路径。
因此,类 TransmissionData 允许代码在不打开宿主文档的前提下对外部文件引用进行操作。该类的两个方法 ReadTransmissionData / WriteTransmissionData 分别提供了读写接口。例如:将一个 TransmissionData 对象的所有外部文件引用都设置为 LinkedFileStatus.Unloaded,然后将其作为参数调用 WriteTransmissionData 方法。则下一次文档打开时所有外部文件都不会被加载。
下面是应用 TransmissionData 实现你的需求的代码:
/// <summary>
/// 列出指定文档包含的所有DWG、RVT和其它类型的文件链接。/// </summary>
void ListLinks( ModelPath location )
{
string path = ModelPathUtils.ConvertModelPathToUserVisiblePath( location );
string content = string.Format( "The document at '{0}' ", path );
List<string> links = null;
// access transmission data in the given Revit file
TransmissionData transData = TransmissionData.ReadTransmissionData( location );
if( transData == null )
{
content += "does not have any transmission data";
}
else
{
// collect all (immediate) external references in the model
ICollection<ElementId> externalReferences = transData.GetAllExternalFileReferenceIds();
int n = externalReferences.Count;
content += string.Format( "has {0} external reference{1}{2}", n, PluralSuffix( n ), DotOrColon( n ) );
links = new List<string>( n );
// find every reference that is a link
foreach( ElementId refId in externalReferences )
{
ExternalFileReference extRef = transData.GetLastSavedReferenceData( refId );
links.Add( string.Format( "{0} {1}", extRef.ExternalFileReferenceType, ModelPathUtils.ConvertModelPathToUserVisiblePath( extRef.GetPath() ) ) );
}
}
Debug.Print( content );
TaskDialog dlg = new TaskDialog( "List Links" );
dlg.MainInstruction = content;
if( null != links && 0 < links.Count )
{
string s = string.Join( " \r\n", links.ToArray() );
Debug.Print( s );
dlg.MainContent = s;
}
dlg.Show();
}
其中 ModelPath 对象可以通过 ModelPathUtils 静态方法从文件路径中获取。简单地以处理当前活动文档为例,外部命令的实现就很简单了:
public Result Execute(
ExternalCommandData commandData,
ref string message,
ElementSet elements )
{
View view = commandData.View;
if( null == view )
{
message = "Please run this command in an active document.";
return Result.Failed;
}
else
{
Document doc = view.Document;
ModelPath modelPath = ModelPathUtils.ConvertUserVisiblePathToModelPath( doc.PathName );
ListLinks( modelPath );
return Result.Succeeded;
}
}
完整的实现代码可以在这里下载:
ListLinks.zip。
当然,这个实现由很多地方可以改进。比方说从处理当前活动文档改为处理指定的多个文档。