使用ifileoperation复制项时uac提升 [英] uac elevate while using ifileoperation copyitem
问题描述
我正在使用下面的代码在Windows 7中进行文件复制操作,但是它不起作用,并且在运行或调试时没有任何错误,当应用程序调用CoGetObject时,它将崩溃并且无法执行返回任何Hresult错误,我只知道此行中发生错误-> result := CoGetObject(pWideString(MonikerName), @BindOpts,
ShlObj.IFileOperation, @iFileOperation);
任何人都可以在此代码中找到任何问题?
`
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}';
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;
var lFileOperation: ShlObj.IFileOperation; psiFrom: IShellItem; psiTo: IShellItem; myFile: TextFile; BindOpts: TBindOpts3; MonikerName: WideString; Res: HResult;
begin try
begin try
begin
结果:= CoInitialize(nil); 如果成功(结果),则 开始
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;
除外 d:例外 开始
except on d: exception do begin
showmessage(d.tostring());
end;
end;
end;
`
推荐答案
CoGetObject()实际返回什么HRESULT
值?
What HRESULT
value is CoGetObject() actually returning?
在调用COM函数时,请勿将WideString转换为pWideString.照原样传递它,让Delphi为您处理编组细节.
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.
并且在调用CoGetObject()之后无需调用CoCreateInstance(). CoGetObject()已将所需的COM对象返回给您.照原样使用.
And there is no need to call CoCreateInstance() after calling CoGetObject(). CoGetObject() already returns the required COM object to you. Use it as-is.
尝试一下:
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;
这篇关于使用ifileoperation复制项时uac提升的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!