【问题标题】:uac elevate while using ifileoperation copyitemuac 在使用 ifile 操作 copyitem 时提升
【发布时间】:2011-03-17 08:07:27
【问题描述】:

我在 Windows 7 中使用下面的代码进行文件复制操作,但它不起作用,并且在运行或调试时没有任何错误,当应用程序调用 CoGetObject 时它会崩溃并且不能返回任何 Hresult 错误,我只知道错误发生在这一行 ->result := CoGetObject(pWideString(MonikerName), @BindOpts, ShlObj.IFileOperation, @iFileOperation); 任何人都可以在这段代码中找到任何问题? `

类型 PBindOpts3 = ^TBindOpts3; {$EXTERNALSYM tagBIND_OPTS3} tagBIND_OPTS3 = 记录 cbStruct:双字; grfFlags:双字; grfMode:双字; dwTickCountDeadline:双字; dwTrackFlags:双字; dwClassContext:双字; 语言环境:LCID; pServerInfo:指针; hwnd: hwnd; 结尾; TBindOpts3 = tagBIND_OPTS3; {$EXTERNALSYM BIND_OPTS3} BIND_OPTS3 = TBindOpts3;

function CopyItem(const aSrcItem, aDest, aNewName: string): HResult; 常量 CLSID_FileOp: TGUID = '{3ad05575-8857-4850-9277-11b85bdb8e09}';

变量 lFileOperation:ShlObj.IFileOperation; psi来自:IShellItem; psiTo:IShellItem; 我的文件:文本文件; 绑定选项:TBindOpts3; 绰号:宽字符串; 回复:HResult;

开始 试试

begin

结果 := CoInitialize(nil); 如果成功(结果)那么 开始

    ZeroMemory(@BindOpts, Sizeof(TBindOpts3));
    BindOpts.cbStruct := Sizeof(TBindOpts3);
    BindOpts.hwnd := 0;
    BindOpts.dwClassContext := CLSCTX_LOCAL_SERVER;

    MonikerName := 'Elevation:Administrator!new:' + GUIDToString
      (CLSID_FileOp);
    result := CoGetObject(pWideString(MonikerName), @BindOpts,
      ShlObj.IFileOperation, @lFileOperation);

    if Succeeded(result) then

      result := CoCreateInstance(CLSID_FileOp, nil,
        CLSCTX_LOCAL_SERVER + CLSCTX_INPROC_SERVER + CLSCTX_INPROC_HANDLER,
        IFileOperation, lFileOperation);
    if Succeeded(result) then
    begin
      result := lFileOperation.SetOperationFlags
        (FOFX_SHOWELEVATIONPROMPT + FOFX_NOCOPYHOOKS +
          FOFX_REQUIREELEVATION); 
      if Succeeded(result) then
      begin
        result := SHCreateItemFromParsingName
          (pchar(aSrcItem), nil, IShellItem, psiFrom);
        if Succeeded(result) then
        begin
          if aDest <> '' then
          begin

            result := SHCreateItemFromParsingName
              (pchar(aDest), nil, IShellItem, psiTo);
          end;

          if Succeeded(result) then
          begin

            result := lFileOperation.CopyItem
              (psiFrom, psiTo, pchar(aNewName), nil);

            psiTo := nil;
          end;

          psiFrom := nil;
        end;

        if Succeeded(result) then
        begin

          result := lFileOperation.PerformOperations;
        end;
      end;

      lFileOperation := nil;
    end;

    CoUninitialize;
  end;
end;

除了 在 d: 例外做 开始

 showmessage(d.tostring());
end;

结束;

结束;

`

【问题讨论】:

  • 为什么删除了大部分问题?
  • roza 如果您还有其他问题,请提出其他问题。不要只编辑这个。

标签: delphi api


【解决方案1】:

CoGetObject() 实际返回的HRESULT 值是多少?

在调用 COM 函数时不要将 WideString 转换为 pWideString。按原样传递,让 Delphi 为您处理编组细节。

并且在调用 CoGetObject() 之后无需调用 CoCreateInstance()。 CoGetObject() 已经将所需的 COM 对象返回给您。按原样使用。

试试这个:

function CopyItem(const aSrcItem, aDest, aNewName: string): HResult;
const
  CLSID_FileOp: TGUID = '{3ad05575-8857-4850-9277-11b85bdb8e09}';
var
  lFileOperation: ShlObj.IFileOperation;
  psiFrom: IShellItem;
  psiTo: IShellItem;
  BindOpts: TBindOpts3;
  MonikerName: WideString;
begin
  try
    Result := CoInitialize(nil);
    OleCheck(Result);
    try
      ZeroMemory(@BindOpts, Sizeof(TBindOpts3)); 
      BindOpts.cbStruct := Sizeof(TBindOpts3); 
      BindOpts.hwnd := 0; 
      BindOpts.dwClassContext := CLSCTX_LOCAL_SERVER; 

      MonikerName := 'Elevation:Administrator!new:' + GUIDToString(CLSID_FileOp); 
      Result := CoGetObject(MonikerName, @BindOpts, ShlObj.IFileOperation, lFileOperation); 
      OleCheck(Result);

      Result := lFileOperation.SetOperationFlags(FOFX_SHOWELEVATIONPROMPT or FOFX_NOCOPYHOOKS or FOFX_REQUIREELEVATION);  
      OleCheck(Result);

      Result := SHCreateItemFromParsingName(PChar(aSrcItem), nil, IShellItem, psiFrom); 
      OleCheck(Result);

      if aDest <> '' then 
      begin 
        Result := SHCreateItemFromParsingName(PChar(aDest), nil, IShellItem, psiTo); 
        OleCheck(Result);
      end; 

      Result := lFileOperation.CopyItem(psiFrom, psiTo, PChar(aNewName), nil); 
      OleCheck(Result);

      Result := lFileOperation.PerformOperations;
      OleCheck(Result);
    finally 
      CoUninitialize; 
    end; 
  except
    on E: Exception do ShowMessage(d.ToString());
  end;
end;

【讨论】:

    猜你喜欢
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2010-10-29
    • 2020-08-05
    • 1970-01-01
    • 2011-02-11
    相关资源
    最近更新 更多