验证'C:\ Program Files\'是否可写。

我有这样一种情况,用户可以配置一些文件(被下载和安装以供应用程序使用)的目标位置。有两个配置的位置,一个是系统位置,另一个是用户位置。该应用程序是一个基于 Lua 的命令行工具。

在安装之前,我通过编写临时文件并将其删除来检查位置是否可写。如果失败,我以提升的权限重新启动相同的命令,这允许管理员进行安装,但不允许普通用户。

问题:系统位置默认位于“C:\Program Files\”中,受保护(没有问题)并被重定向(这是问题)到“C:\Users<name>\AppData\VirtualStore\Program Files...”目录。由于这种重定向,测试成功,东西被安装而不需要提升权限。因此,它最终会出现在VirtualStore中,而不是出现用户没有所需权限的错误。

问题:那么,我如何测试实际的C:\Program Files\可写性,而不触发VirtualStore的重定向?

点赞
用户388389
用户388389
del /q /f "C:\Users\%username%\AppData\Local\VirtualStore\Program Files\redirectionTest" >nul 2>&1
echo test>"%ProgramFiles%\redirectionTest"
if exist "C:\Users\%username%\AppData\Local\VirtualStore\Program Files\redirectionTest" (
  echo redirected
) else (
  echo not redirected
)
删除 /q /f "C:\Users\%username%\AppData\Local\VirtualStore\Program Files\redirectionTest" >nul 2>&1
echo test>"%ProgramFiles%\redirectionTest"
如果存在 "C:\Users\%username%\AppData\Local\VirtualStore\Program Files\redirectionTest" (
  echo 重定向
) 否则 (
  echo 未重定向
)

或者只需要:

echo test>"%ProgramFiles%\redirectionTest"
如果存在 "%ProgramFiles%\redirectionTest" 直接输出 not redirected

IF EXIST 也会受到重定向的影响吗?

2013-11-28 15:56:15
用户2525533
用户2525533
@echo off
2>nul (
(call ) >>"C:\Program Files\file"
) && (
   rem we have access
   rem do stuff
   exit /b
)
rem we dont have access
rem do stuff

如果有问题,请解释一下哪里出了问题,否则我不清楚你的问题。

2013-11-28 16:01:45
用户746559
用户746559

我尝试了一些技巧来查看哪些命令被重定向了,哪些没有。起初我尝试使用操作系统的 copy 命令将临时文件复制到同一位置的第二个临时文件中,但在那种情况下同时读取源文件和写入目标文件均被重定向了。

以下 Lua 代码得出了最终判断结果:

function is_writable(file)
   assert(file)
   file = dir.normalize(file)
   local result
   local tmpname = 'tmptestwritable.deleteme'
   if fs.is_dir(file) then
      local file2 = dir.path(file, tmpname)
      local fh = io.open(file2, 'wb')
      result = fh ~= nil
      if fh then fh:close() end
      if result then
         -- 上面的测试可能会在写入 Vista 及更高版本的 c:\program files\ 时出现虚拟存储区重定向导致的误报。
         -- 因此获取目录列表并检查文件是否真正存在。
         local pipe = io.popen("dir "..fs.Q(file))
         local dir_list = pipe:read("*a")
         pipe:close()
         result = (nil ~= string.find(dir_list, tmpname, 1, true))
      end
      os.remove(file2)
   else
      local fh = io.open(file, 'r+b')
      result = fh ~= nil
      if fh then fh:close() end
   end
   return result
end

在普通的 '编写测试文件' 后,它会在目标文件夹上运行 dir 命令,该命令仅返回无重定向的内容,然后在这个内容中搜索所使用的临时名称。

感谢您的努力!

2013-11-28 16:33:32