写保护 USB 驱动器上出现 ShellExecuteEx 错误?
我正在尝试在写保护的 USB 驱动器上测试应用程序,我想使用 ShellExecuteEx API(我需要使用此 API 调用,因为我需要 lpVerb := "runas")调用来执行第二个程序,但我通过 ShellExecuteEx 调用不断收到“写保护错误”。我似乎无法弄清楚正在尝试写入驱动器的内容,我没有写入驱动器的代码,我什至使用了最新的 Microsoft 标准用户分析器 和 应用程序验证程序尝试验证尝试写入驱动器的内容,但没有成功。这是我不断收到的错误:
[ Write Protect Error ]
Nothing in the以下代码正在尝试写入此驱动器,ShellExecuteEx API 调用是否是执行我尝试执行的操作的错误方法?如果没有,我怎样才能避免弹出这个错误。任何帮助将不胜感激。
[ WP-ON.reg ]
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies]
"WriteProtect"=dword:00000001
[ WP-OFF.reg ]
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies]
"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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这个问题来自于
ShellExecuteEx
是一个相当复杂的过程,启动一个新的后台线程,然后调用大量 COM 内容。出于安全原因,应该在某处启用写入。您可以尝试禁用UAC。但并不是一个好的解决方案。
当您查看以编程方式提升进程权限的相应解决方案时(有线清单是另一种静态提升方式),您只能找到两个 在此答案中引用:
runas
参数;值得阅读整篇“Vista UAC:权威指南”文章了解 ShellExecuteEx 的工作原理。
所以这是我的答案:由于您需要运行具有提升权限的进程,并且没有现有的“CreateProcessElevated”API,只有良好的大ShellExecute,所以最简单的方法是使用清单文件第二个可执行文件。
如果您希望 project1.exe 文件以“AsInvoker”权限运行,但有意仅以管理员权限运行,则有两种可能性:
.manifest
文件,并且不要将该文件嵌入到exe 作为一种资源 - 然后用带有“AsInvoker”或“requireAdministrator”参数的一个版本替换.manifest
内容 - 但在只读媒体上很困难,不是吗:;Elevate.exe
),其中包含具有“requireAdministrator”级别的清单,它将启动第二个可执行文件。您可以提供 exe 和命令行作为此Elevate.exe
程序的参数。The issue comes from the fact
ShellExecuteEx
is quite a complex process, starting a new background thread, then calling a lot of COM stuff. Write should be enabled somewhere, for security reasons.You may try to disable the UAC. But not a good solution.
When you look at the corresponding solutions to elevate a process rights programatically (wired manifest is another static way of elevation), you can only find the two quoted in this SO answer:
runas
parameter;It's worth reading the whole "Vista UAC: The Definitive Guide" article to understand how ShellExecuteEx works.
So here is my answer: since you need to run a process with elevated rights, and there is no existing "CreateProcessElevated" API but only the good big ShellExecute, the most easy is to use a manifest file for the 2nd executable.
If you want your project1.exe file to run with "AsInvoker" rights, but only with administrator rights on purpose, you have two possibilities:
.manifest
file, and do not embed the file to the exe as a resource - then replace the.manifest
content with one version with either "AsInvoker" or "requireAdministrator" parameter - but difficult on a read-only media, isn't it :;Elevate.exe
), containing a manifest with the "requireAdministrator" level, which will launch the 2nd executable. You could provide the exe and command line as a parameter to thisElevate.exe
program.