delphi – 写保护的USB驱动器上的ShellExecuteEx错误?
我正在尝试在写保护的USB驱动器上测试应用程序,我想使用
ShellExecuteEx API(我需要使用此API调用,因为我需要lpVerb:=“runas”)调用来执行第二个程序,但是我使用ShellExecuteEx调用继续获得“写保护错误”.我似乎无法弄清楚是什么试图写入驱动器,我没有写入驱动器的代码,我甚至使用最新的
Microsoft Standard User Analyzer和
Application Verifier来尝试验证什么是试图写入驱动器但没有成功.这是我一直得到的错误:
[写保护错误] 以下代码中没有任何内容试图写入此驱动器,ShellExecuteEx API调用错误的方法来执行我正在尝试的操作吗?如果没有,我怎么能弹出这个错误.任何帮助将不胜感激. [WP-ON.reg] REGEDIT4 [HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlStorageDevicePolicies] "WriteProtect"=dword:00000001 [WP-OFF.reg] REGEDIT4 [HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlStorageDevicePolicies] "WriteProtect"=dword:00000000 注:每次更新注册表时,必须弹出并重新插入设备. [project1.dpr] program project1; {.$APPTYPE CONSOLE} uses Windows,SysUtils; begin Windows.MessageBox(Windows.GetActiveWindow(),PChar('Hello World!'),PChar('project1'),MB_OK); end. [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> [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. 解决方法
问题来自于ShellExecuteEx是一个非常复杂的过程,启动一个新的后台线程,然后调用很多COM东西.出于安全原因,应该在某处启用写入.
您可以尝试禁用UAC.但不是一个好的解决方案. 当您查看相应的解决方案以编程方式提升流程权限时(有线清单是另一种静态的提升方式),您只能找到两个quoted in this SO answer: >将ShellExecuteEx与runas参数一起使用; 值得阅读整篇“Vista UAC: The Definitive Guide”文章,了解ShellExecuteEx的工作原理. 所以这是我的答案:因为您需要运行具有提升权限的进程,并且没有现有的“CreateProcessElevated”API,但只有好的大型ShellExecute,最简单的方法是使用清单文件作为第二个可执行文件. 如果您希望project1.exe文件以“AsInvoker”权限运行,但只有管理员权限,则有两种可能: >使用外部.manifest文件,不要将文件作为资源嵌入到exe中 – 然后将.manifest内容替换为带有“AsInvoker”或“requireAdministrator”参数的一个版本 – 但在只读媒体上很难,不是吗;;>使用外部第3个可执行文件(我们将其称为Elevate.exe),其中包含具有“requireAdministrator”级别的清单,该清单将启动第二个可执行文件.您可以提供exe和命令行作为此Elevate.exe程序的参数. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |