如何在 Windows 中使用 rundll32.exe 删除文件?

Posted

技术标签:

【中文标题】如何在 Windows 中使用 rundll32.exe 删除文件?【英文标题】:How to delete a file in Windows using rundll32.exe for it? 【发布时间】:2021-12-20 14:29:17 【问题描述】:

我想应该是这样的:

rundll32 kernel32.dll,DeleteFileA,test.txt

但这只是行不通。 我试过了:

rundll32 kernel32.dll,DeleteFileA test.txt
rundll32 "kernel32.dll,DeleteFileA test.txt"

文件保留。 当我从 PowerShell 中尝试它时,它会在我拼错 DeleteFileA 时显示一条错误消息,因此它会在 kernel32.dll 中找到正确的条目。它只是不起作用可能是由于没有获取文件名参数。

我为什么需要它?我需要能够以管理员身份在常规用户上下文中运行的程序中删除文件。我严格不希望整个应用程序以管理员身份运行。只有确切的一次删除才会显示 UAC 确认。

以下是在我的 C# 应用程序中有效的内容:

private static void DeleteAsAdmin(string target) 
    Process.Start(new ProcessStartInfo  FileName = "cmd", Arguments = $"/C \"del /F /Q \"\"\"target\"\"\"\"", Verb = "RunAs", CreateNoWindow = true );

但是,它无论如何都会显示一个窗口。有一段时间,但它是可见的。这是因为我必须显式执行cmd 才能使用del 命令。

这就是我想改用rundll32 的原因。默认情况下,这将不创建任何窗口。它还暴露了FileDeleteA 方法。

我知道,我可以添加一个帮助程序可执行文件,以管理员身份为我的应用删除文件,但这是一个非常丑陋的解决方案,甚至比调用 cmd 还要丑陋。

为什么我首先需要删除文件?为了安全。该文件包含一个敏感的程序配置,该配置被加密(使用 DPAPI)并移动到用户可访问的目录。为了额外的安全,需要删除位于“C:\Program Files”中的原始文件。如果用户取消 UAC 提示,那将失败,但用户的错是他们的敏感配置是纯文本的。

是的,我知道我可以通过 MSI 将文件放在用户目录中,但这对我也不利,因为它需要我想避免的额外配置步骤。在使用完全默认的 MSI 安装程序安装后,该程序必须自己完成所有工作。我可以这样,但似乎rundll32 hack 只是在嘲笑我,而我只是一个特殊的角色;)

【问题讨论】:

What’s the guidance on when to use rundll32? Easy: Don’t use it. 用你的 cmdline DeleteFileA 真的会被调用,但是有 4 个参数 - DeleteFileA(hwnd, hInstance, L"test.txt", SW_SHOWDEFAULT) - 你怎么想 - “test.txt”会被删除?当你有self exe时你需要什么rundll?!用命令行运行self exe @RbMm docs.microsoft.com/en-us/windows/win32/api/fileapi/… - 这是 MSDN 文档中的错误吗?不过OK,self-exe好像还可以。我正在寻找其他东西,因为我正在开发一个 nuget 包。它不应该需要任何用户的代码修改。你打电话给Protect 这样就完成了。 使用IFileOperation - 它是专门为这个任务设计的 【参考方案1】:

rundll32 需要一个非常具体的函数签名,it is not a generic "call any function" helper application。

要隐藏 cmd 窗口,您可以尝试添加 WindowStyle = ProcessWindowStyle.Hidden,但如果您已经有 C# 应用程序,为什么还要麻烦呢?只是打电话给自己做任务。这至少将正确的 .exe 放入 UAC 对话框中。

即使你让这一切正常工作,它仍然是错误的!如果您要安装到 %ProgramFiles% 中,那么您正在为机器上的所有用户安装,并且一旦第二个用户运行您的应用程序,您的方案就会中断。写入用户配置文件的任何操作都必须在用户第一次运行您的程序时完成,而不是在安装阶段。您可以将模板文件从安装目录复制到用户配置文件,但不能删除模板。

【讨论】:

所以...可能将整个安装的应用程序放在用户的目录中,例如谷歌浏览器会解决问题。我喜欢它,现在我只想看看如何让微星做到这一点...... 你说得对,我测试了将安装程序指向用户的应用程序数据文件夹,问题自行解决。正确的做法是让所有用户共享程序文件,并将敏感配置直接安装到用户目录。 ALLUSERS=2 MSIINSTALLPERUSER=1 docs.microsoft.com/en-us/windows/win32/msi/installation-context 谢谢,我就是这样做的,它似乎很有魅力。程序文件中的exe,应用程序数据中的配置。用户可读写配置。【参考方案2】:

如果您需要删除文件,您可以使用IFileOperation。示例代码:

#include <shobjidl_core.h>

// assume
// CoInitializeEx(0, COINIT_DISABLE_OLE1DDE|COINIT_APARTMENTTHREADED);
// already called

HRESULT DeleteFileElevated(PCWSTR lpFilename)

    IShellItem* psi;

    HRESULT hr = SHCreateItemFromParsingName(lpFilename, 0, IID_PPV_ARGS(&psi));
    if (0 <= hr)
    
        IFileOperation *pFileOp;

        BIND_OPTS2 bo =  sizeof(bo) ;
        bo.dwClassContext = CLSCTX_LOCAL_SERVER;

        if (0 <= (hr = CoGetObject(L"Elevation:Administrator!new:3ad05575-8857-4850-9277-11b85bdb8e09", &bo, IID_PPV_ARGS(&pFileOp))))
        
            0 <= (hr = pFileOp->SetOperationFlags(FOF_NOCONFIRMATION| 
                FOF_NOERRORUI| 
                FOF_FILESONLY| 
                FOFX_EARLYFAILURE|
                FOFX_SHOWELEVATIONPROMPT)) &&
            0 <= (hr = pFileOp->DeleteItem(psi, 0))
                && 
                0 <= (hr = pFileOp->PerformOperations());

            pFileOp->Release();

        
        psi->Release();
    
    return hr;

【讨论】:

以上是关于如何在 Windows 中使用 rundll32.exe 删除文件?的主要内容,如果未能解决你的问题,请参考以下文章

命令行下的“蒙面歌王”rundll32.exe

rundll32.exe

rundll32.exe 等效于 64 位 DLL

Windows xp 在更换主题时出现rundll32.exe应用程序错误是怎么回事 急急急!!

如何使用 Rundll32 交换鼠标按钮?

rundll32 url.dll,FileProtocolHandler