本文介绍了uac 提升,同时使用 ifileoperation copyitem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码在 Windows 7 中进行文件复制操作,但它不起作用并且在运行或调试时没有任何错误,当应用程序去调用 CoGetObject 时它会崩溃并且不能返回任何 Hresult 错误,我只知道错误发生在这一行 ->result := CoGetObject(pWideString(MonikerName), @BindOpts,ShlObj.IFileOperation, @iFileOperation);任何人都可以在此代码中找到任何问题?`类型PBindOpts3 = ^TBindOpts3;{$EXTERNALSYM tagBIND_OPTS3}tagBIND_OPTS3 = 记录cbStruct:双字;grfFlags:双字;grfMode:双字;dwTickCountDeadline: DWORD;dwTrackFlags:双字;dwClassContext: DWORD;语言环境: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;psiFrom: IShellItem;psiTo: IShellItem;我的文件:文本文件;BindOpts:TBindOpts3;MonikerName:WideString;回复:HResult;

开始试试

开始

结果:= 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);结果 := CoGetObject(pWideString(MonikerName), @BindOpts,ShlObj.IFileOperation, @lFileOperation);如果成功(结果)然后结果 := CoCreateInstance(CLSID_FileOp, nil,CLSCTX_LOCAL_SERVER + CLSCTX_INPROC_SERVER + CLSCTX_INPROC_HANDLER,IFileOperation, lFileOperation);如果成功(结果)然后开始结果:= lFileOperation.SetOperationFlags(FOFX_SHOWELEVATIONPROMPT + FOFX_NOCOPYHOOKS +FOFX_REQUIREELEVATION);如果成功(结果)然后开始结果 := SHCreateItemFromParsingName(pchar(aSrcItem), nil, IShellItem, psiFrom);如果成功(结果)然后开始如果 aDest <>'' 然后开始结果 := SHCreateItemFromParsingName(pchar(aDest), nil, IShellItem, psiTo);结尾;如果成功(结果)然后开始结果:= lFileOperation.CopyItem(psiFrom, psiTo, pchar(aNewName), nil);psiTo := nil;结尾;psiFrom := nil;结尾;如果成功(结果)然后开始结果:= lFileOperation.PerformOperations;结尾;结尾;lFileOperation := nil;结尾;CoUninitialize;结尾;结尾;

除了在 d: 例外做开始

 showmessage(d.tostring());结尾;

结束;

结束;

`

解决方案

CoGetObject() 实际返回什么 HRESULT 值?

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

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

试试这个:

function CopyItem(const aSrcItem, aDest, aNewName: string): HResult;常量CLSID_FileOp: TGUID = '{3ad05575-8857-4850-9277-11b85bdb8e09}';无功lFileOperation:ShlObj.IFileOperation;psiFrom: IShellItem;psiTo: IShellItem;BindOpts:TBindOpts3;MonikerName:WideString;开始尝试结果 := CoInitialize(nil);OleCheck(结果);尝试ZeroMemory(@BindOpts, Sizeof(TBindOpts3));BindOpts.cbStruct := Sizeof(TBindOpts3);BindOpts.hwnd := 0;BindOpts.dwClassContext := CLSCTX_LOCAL_SERVER;MonikerName := 'Elevation:Administrator!new:' + GUIDToString(CLSID_FileOp);结果 := CoGetObject(MonikerName, @BindOpts, ShlObj.IFileOperation, lFileOperation);OleCheck(结果);结果 := lFileOperation.SetOperationFlags(FOFX_SHOWELEVATIONPROMPT or FOFX_NOCOPYHOOKS or FOFX_REQUIREELEVATION);OleCheck(结果);结果:= SHCreateItemFromParsingName(PChar(aSrcItem), nil, IShellItem, psiFrom);OleCheck(结果);如果 aDest <>'' 然后开始结果 := SHCreateItemFromParsingName(PChar(aDest), nil, IShellItem, psiTo);OleCheck(结果);结尾;结果:= lFileOperation.CopyItem(psiFrom, psiTo, PChar(aNewName), nil);OleCheck(结果);结果:= lFileOperation.PerformOperations;OleCheck(结果);最后CoUninitialize;结尾;除了在 E: 异常做 ShowMessage(d.ToString());结尾;结尾;

I'm using below code to file copy operataion in windows seven,but it doesn't work and there is no any error while running or debugging,When the application goes to calling the CoGetObject it'll crash and can't returning any Hresult error,I just know the error occur in this line ->result := CoGetObject(pWideString(MonikerName), @BindOpts, ShlObj.IFileOperation, @iFileOperation);anyone can find any problem in this code? `

type
  PBindOpts3 = ^TBindOpts3;
{$EXTERNALSYM tagBIND_OPTS3}
  tagBIND_OPTS3 = record
    cbStruct: DWORD;
    grfFlags: DWORD;
    grfMode: DWORD;
    dwTickCountDeadline: DWORD;
    dwTrackFlags: DWORD;
    dwClassContext: DWORD;
    locale: LCID;
    pServerInfo: Pointer;
    hwnd: hwnd;
  end;
  TBindOpts3 = tagBIND_OPTS3;
{$EXTERNALSYM BIND_OPTS3}
  BIND_OPTS3 = TBindOpts3;

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; myFile: TextFile; BindOpts: TBindOpts3; MonikerName: WideString; Res: HResult;

begin try

begin

result := CoInitialize(nil); if Succeeded(result) then begin

    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;

except on d: exception do begin

 showmessage(d.tostring());
end;

end;

end;

`

解决方案

What HRESULT value is CoGetObject() actually returning?

Do not cast a WideString to a pWideString when calling a COM function. Pass it in as-is and let Delphi handle the marshalling details for you.

And there is no need to call CoCreateInstance() after calling CoGetObject(). CoGetObject() already returns the required COM object to you. Use it as-is.

Try this:

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;

这篇关于uac 提升,同时使用 ifileoperation copyitem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-06 01:44