eye*_*ton 4 delphi delphi-7 shellexecuteex
我正在尝试在写保护的USB驱动器上测试应用程序,我想使用ShellExecuteEx API(我需要使用此API调用,因为我需要lpVerb:="runas")调用来执行第二个程序,但是我使用ShellExecuteEx调用继续获得"写保护错误".我似乎无法弄清楚是什么试图写入驱动器,我没有写入驱动器的代码,我甚至使用最新的Microsoft标准用户分析器和应用程序验证程序来尝试验证试图写入驱动器的内容开车没有成功.这是我一直得到的错误:
[写保护错误]

以下代码中没有任何内容试图写入此驱动器,ShellExecuteEx API调用错误的方法来执行我正在尝试的操作吗?如果没有,我怎么能弹出这个错误.任何帮助将不胜感激.
[WP-ON.reg]
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies]
"WriteProtect"=dword:00000001
Run Code Online (Sandbox Code Playgroud)
[WP-OFF.reg]
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies]
"WriteProtect"=dword:00000000
Run Code Online (Sandbox Code Playgroud)
注:每次更新注册表时,必须弹出并重新插入设备.
[project1.dpr]
program project1;
{.$APPTYPE CONSOLE}
uses
  Windows, SysUtils;
begin
  Windows.MessageBox(Windows.GetActiveWindow(),
    PChar('Hello World!'), PChar('project1'), MB_OK);
end.
Run Code Online (Sandbox Code Playgroud)
[launch.manifest]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity processorArchitecture="x86" version="2.0.1.0" name="eyeClaxton.asInvoker.Launch" type="win32" />
<description>asInvoker Launch</description>
<dependency>
    <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="x86" />
    </dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
        <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="false" />
        </requestedPrivileges>
    </security>
</trustInfo>
</assembly>
Run Code Online (Sandbox Code Playgroud)
[launch.dpr]
program launch;
uses
  Windows, ShellAPI;
{$R 'MANIFEST.RES'}
procedure ShellEx(const theFilename, theParams: string);
  function RunAsAdmin(): Boolean;
  var
    OSVerInfo: TOSVersionInfo;
  begin
    OSVerInfo.dwOSVersionInfoSize := System.SizeOf(OSVerInfo);
    Result := (Windows.GetVersionEx(OSVerInfo)) and (OSVerInfo.dwMajorVersion > 5);
  end;
var
  ShellExInfo: TShellExecuteInfo;
  Directory: array[0..MAX_PATH] of Char;
begin
  Windows.ZeroMemory(@ShellExInfo, System.SizeOf(ShellExInfo));
  ShellExInfo.cbSize := System.SizeOf(TShellExecuteInfo);
  ShellExInfo.Wnd := Windows.GetActiveWindow();
  ShellExInfo.nShow := SW_SHOWNORMAL;
  ShellExInfo.fMask := SEE_MASK_FLAG_NO_UI;
  if (RunAsAdmin()) then  // If OS is greater than Windows XP
    ShellExInfo.lpVerb := PChar('runas');
  Windows.ZeroMemory(@Directory, System.SizeOf(Directory));
  Windows.GetCurrentDirectory(SizeOf(Directory), Directory);
  ShellExInfo.lpDirectory := PChar(string(Directory));
  ShellExInfo.lpFile := PChar('"' + string(Directory) + '\' + theFilename + '"');
  ShellExInfo.lpParameters := PChar('"' + theParams + '"');
  //
  // ShellExecuteEx causes a "Write Protect" error to popup.
  //
  if (not ShellAPI.ShellExecuteEx(@ShellExInfo)) then
    Windows.MessageBox(Windows.GetActiveWindow(),
      PChar('File ' + ShellExInfo.lpFile + ' not found!'),
      PChar('asInvoker Launch'), MB_OK or MB_ICONERROR);
end;
begin
  ShellEx('project1.exe', System.ParamStr(1));
end.
Run Code Online (Sandbox Code Playgroud)
    问题来自于一个ShellExecuteEx非常复杂的过程,启动一个新的后台线程,然后调用很多COM东西.出于安全原因,应该在某处启用写入.
您可以尝试禁用UAC.但不是一个好的解决方案.
当您查看相应的解决方案以编程方式提升流程权限时(有线清单是另一种静态的提升方式),您只能找到此SO答案中引用的两个:
runas参数的ShellExecuteEx ;值得阅读整篇"Vista UAC:The Definitive Guide"文章,了解ShellExecuteEx的工作原理.
所以这是我的答案:因为您需要运行具有提升权限的进程,并且没有现有的"CreateProcessElevated"API,但只有好的大型ShellExecute,最简单的方法是使用清单文件作为第二个可执行文件.
如果您希望project1.exe文件以"AsInvoker"权限运行,但只有管理员权限,则有两种可能:
.manifest文件,不要将文件作为资源嵌入到exe中 - 然后将.manifest内容替换为带有"AsInvoker"或"requireAdministrator"参数的一个版本 - 但在只读媒体上很难,不是: ;Elevate.exe),包含一个带有"requireAdministrator"级别的清单,它将启动第二个可执行文件.您可以提供exe和命令行作为此Elevate.exe程序的参数.