我有一个应用程序需要在用户的 %APPDATA% 目录中创建其设置目录。为此,它使用类似于以下的代码:
std::string appDataBase = getenv("APPDATA");
std::string appDir = appDataBase + "\\MyDir";
std::cerr << "About to invoke _mkdir(" << appDir << ")" << std::endl;
int rv = _mkdir(appDir.c_str());
std::cerr << "_mkdir returned " << rv << ", errno = " << errno << std::endl;
但是,当这段代码运行时,_mkdir
调用失败并且 errno
被设置为 EACCES
:
About to invoke _mkdir(C:\Users\mdm\AppData\Roaming\MyDir)
_mkdir returned -1, errno = 13
我会假设这是一个简单的权限问题,除了以下事实:(1) 我可以在资源管理器中手动创建目录而没有任何权限问题,以及 (2) 如果我将完全相同的代码复制到一个单独的项目。
我已广泛搜索有关此问题的信息,但只能找到有关一般权限问题的讨论,例如用户无法使用资源管理器访问/写入此文件夹。如果我以管理员身份运行我的应用程序中的代码,那么它的权限显然会发生一些奇怪的事情,但我不知道还有什么要检查的。我已使用 Process Explorer 检查并确认该应用程序正在使用我的用户帐户运行,该帐户对 %APPDATA% 目录具有完全写入权限,并且我已确保 %APPDATA% 树未设置为隐藏或只读。
是否可以在 Windows 应用程序上设置某种“有效用户 ID”或“有效权限”,这可能取决于构建配置或进程初始化中的某些内容?是否有任何其他因素会阻止一个特定应用程序写入 %APPDATA% 而其他用户进程可以?
更新
进一步调查表明,行为差异与代码内容无关,而是文件系统中可执行文件的位置。我的应用程序是从我的用户目录中 Development
文件夹内的源代码树构建的,并且 _mkdir
调用对该目录中的可执行文件失败;但是,将 .exe 文件复制到新目录 C:\Development
中可以使其正常工作(尽管移动现有的 Development
目录不会)。简单的测试程序在 Documents\Visual Studio\Projects
中,这似乎也是一个令人满意的位置。
最佳答案
Windows 有一组不同的(而且很大)函数用于更改安全上下文。参见 here对于一些。
也许包含该代码的项目正在改变安全上下文?如果该程序作为公共(public)访问服务器运行,我希望它调用 ImpersonateAnonymousToken()
,例如。
关于windows - 应用程序无法写入 %APPDATA%(但用户可以),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10267437/