You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi中无需交互提取OLE容器内链接文件路径的方法

提取OLE容器中链接文件路径的无交互方法

可以通过OLE标准接口直接获取链接路径,无需依赖DoVerb交互或解析原始二进制明文,以下是两种可行方案:

方案一:通过IOleLink接口直接读取

利用TOleContainer加载容器后,不调用DoVerb,直接查询IOleLink接口获取链接源的显示名称(即文件路径),全程无交互:

uses
  ComObj, OleCtrls, ActiveX;

function GetOLELinkedFilePath(const ContainerPath: string): string;
var
  OleContainer: TOleContainer;
  OleLink: IOleLink;
  DisplayName: PWideChar;
begin
  Result := '';
  OleContainer := TOleContainer.Create(nil);
  try
    OleContainer.Parent := nil; // 无需可视化父控件
    OleContainer.LoadFromFile(ContainerPath);
    // 查询IOleLink接口
    if OleContainer.OleObject.QueryInterface(IOleLink, OleLink) = S_OK then
    begin
      // 获取链接源的显示名称(文件路径)
      if OleLink.GetSourceDisplayName(nil, DisplayName) = S_OK then
      begin
        Result := DisplayName;
        CoTaskMemFree(DisplayName); // 释放系统分配的内存
      end;
    end;
  finally
    OleContainer.Free;
  end;
end;

方案二:底层OLE存储解析(无TOleContainer依赖)

如果不想依赖TOleContainer,可以直接通过OLE存储API打开容器文件,遍历对象属性获取路径:

uses
  ActiveX, ComObj;

function GetLinkedPathFromOLEStorage(const ContainerPath: string): string;
var
  Storage: IStorage;
  Stream: IStream;
  OleLink: IOleLink;
  DisplayName: PWideChar;
begin
  Result := '';
  // 打开OLE存储文件
  if StgOpenStorage(PWideChar(ContainerPath), nil, STGM_READ or STGM_SHARE_DENY_WRITE, nil, 0, Storage) = S_OK then
  begin
    try
      // 打开OLE对象的属性流(通常名称为'CONTENTS',部分容器需调整)
      if Storage.OpenStream('CONTENTS', nil, STGM_READ or STGM_SHARE_DENY_WRITE, 0, Stream) = S_OK then
      begin
        try
          // 从流中加载OLE对象并查询IOleLink接口
          if OleLoadFromStream(Stream, IOleLink, OleLink) = S_OK then
          begin
            if OleLink.GetSourceDisplayName(nil, DisplayName) = S_OK then
            begin
              Result := DisplayName;
              CoTaskMemFree(DisplayName);
            end;
          end;
        finally
          Stream := nil;
        end;
      end;
    finally
      Storage := nil;
    end;
  end;
end;

注意:部分OLE容器的流名称可能不是CONTENTS,需根据实际容器类型调整;服务启动时需调用CoInitialize(nil)初始化COM环境,结束时调用CoUninitialize()释放资源。

内容的提问来源于stack exchange,提问作者D D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 15:42:17