Hallo an alle,
ich habe mich wohl oder übel dazu durchringen müssen, dateioperationen in meinem program via eines
COM-Objektes durchzuführen, um der benutzerkontensteuerung von Windows 7 gerecht zu werden. da ich vorher noch nie in kontakt mit
COM war, habe ich diverse tutorials durchgearbeitet. Als ergebnis habe ich nun eine typbibliothek, in der ich eine schnittstelle für ein comobject definiere (IEFS_TLB.pas). Ferner zwei
DLL's, welche das objekt exportieren und für jeweils 32Bit/64Bit systeme ein Manifest besitzen um Admin rechte anzufordern (ob das überhaupt nötig sit weiß ich gar nicht so genau). in einem testprojekt (IEFS_Test.exe) wird nun zunächst das
com-objekt registriert, wobei ich mich zum setzen der registry-einträge hier
http://chrison.net/UACElevationInMan...Elevation.aspx durchgewühlte, und folgende methode lieferte:
Delphi-Quellcode:
procedure RegisterIEFSServer(
const clsid: TCLSID);
function GetRegSvr32Location:
string;
const
CSIDL_WINDOWS = $24;
begin
result := Format('
%sSystem32\RegSvr32.exe',
[IncludeTrailingPathDelimiter(GetSpecialPath(CSIDL_WINDOWS))]);
end;
var
R: TRegistry;
clsName:
string;
begin
// register server dll
ShellExecute(0,
'
runas',
'
regsvr32.exe',
PChar(GetIsaacServerLocation),
nil,
SW_SHOWNORMAL);
// register elevated rights
R := TRegistry.Create;
try
R.RootKey := HKEY_CLASSES_ROOT;
if R.OpenKey(Format('
CLSID\%s', [GUIDToString(
clsid)]), true)
then
begin
clsName := R.ReadString('
');
R.WriteString('
LocalizedString', Format('
@%s,-%d', [GetIsaacServerLocation, ResId_ClassWinElevatedFileStream]));
R.WriteString('
AppID', GUIDToString(ComServerAppId));
if R.OpenKey('
Elevation', true)
then
R.WriteInteger('
Enabled', 1);
R.CloseKey;
end;
if R.OpenKey(Format('
AppID\%s', [GUIDToString(ComServerAppId)]), true)
then
begin
R.WriteString('
', ChangeFileExt(ExtractFileName(GetIsaacServerLocation), '
'));
R.WriteString('
DLLSurrogate', '
');
R.CloseKey;
end;
if R.OpenKey(Format('
AppID\%s', [ExtractFileName(GetIsaacServerLocation)]), true)
then
R.WriteString('
AppID', GUIDToString(ComServerAppId));
finally
R.Free;
end;
end;
Wenn diese Methode mit Admin-Rechten ausgeführt wird, bekomme ich eine Bestätigung, dass die Bibliothek korrekt registriert wurde.
Als nächstes fordere ich das
COM-Objekt mit Admin-Rechten mittels einem Aufruf von:
Delphi-Quellcode:
function CoCreateInstanceAsAdmin(hwnd: HWND; rclsid: TCLSID; riid: TIID; out ppv): HRESULT;
const
mBufSize = 300;
var
bo3: BIND_OPTS3;
bo : BIND_OPTS;
wszMonikerName: LPCWSTR;
begin
Result := S_FALSE;
GetMem(wszMonikerName, mBufSize);
if Assigned(wszMonikerName) then
try
if WinVersion.GetWinVersionType in [wvWinVista, wvWin7, wvWin8] then
begin
StringToWideChar(Format('Elevation:Administrator!new:%s', [GUIDToString(rclsid)]), wszMonikerName, mBufSize);
FillChar(bo3, SizeOf(bo3), 0);
bo3.cbStruct := SizeOf(bo);
bo3.hwnd := hwnd;
bo3.dwClassContext := CLSCTX_LOCAL_SERVER;
Result := NewCoGetObject(wszMonikerName, @bo3, riid, ppv);
end
else
begin
StringToWideChar(Format('new:%s', [GUIDToString(rclsid)]), wszMonikerName, mBufSize);
FillChar(bo, SizeOf(bo), #0);
bo.cbStruct := SizeOf(bo);
Result := CoGetObject(PWidestring(wszMonikerName), @bo, riid, @ppv);
end;
finally
FreeMem(wszMonikerName, mBufSize);
end;
end;
an. Hier bekomme ich nun als FehlerCode auf meinem Windows 7 Testsystem die Fehlermeldung:
"The class is not configured to support Elevated activation."
mit fehlercode
CO_E_ELEVATION_DISABLED
0x80080017
Kann mir eventuell jemand sagen, wo verdammt nochmal mein Fehler liegt? Das beschäftigit mich jetzt bereits seit Montag
Viele Grüße