log4net 日志文件在应用程序安装子文件夹的 Windows 资源管理器中不可见

log4net log file not visible in Windows explorer in application installation sub folder

我将 log4net 用于我用 c# 编写的桌面应用程序,并使用 Visual Studio 扩展 "Microsoft Visual Studio Installer Projects"(MSI 安装程序)进行部署。安装后我没有看到为 log4net 定义的日志子文件夹。

Microsoft Visual Studio 安装程序项目”中的 TARGETDIR 定义为 [ProgramFiles64Folder][Manufacturer]\[ProductName].

log4net 日志文件定义为

<appender name="rollingFile" type="log4net.Appender.RollingFileAppender,log4net">
   <param name="File" value=".\log\MyApp.log" />
   <!-- ... -->

通过 "Microsoft Visual Studio Installer Projects"-created setup.exe 和 msi-installer 安装应用程序后我没有看到 程序 Files\MyManufacturer\MyProductName 下 Windows 资源管理器中的日志文件夹 虽然显示隐藏的文件、文件夹...已设置。

出于测试目的,我将以下代码添加到我的应用程序中:

// does log file exist and grow ?
string currdir = Directory.GetCurrentDirectory();
MessageBox.Show(currdir, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
string[] sa = File.ReadAllLines(currdir + "\log\MyApp.log");
MessageBox.Show(sa.Length.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
// show lines created this year (2019)
string s = "";
for (int i = 0; i < sa.Length; i++)
{
    if(sa[i].Contains("2019")) 
        s = s + sa[i] + "\n";
}
MessageBox.Show(s, "Error", MessageBoxButton.OK, MessageBoxImage.Error);

所以,Program Files\MyManufacturer\MyProductName\log\MyApp.log下的日志文件 可以通过应用程序访问,我看到它在增长!

所以问题是:日志子目录在哪里?如何让它在 Wndows 资源管理器中可见? 这是权限问题吗?

Short Version: Please see if you have any virtualized folders under: %LocalAppData%\VirtualStore.

If you see a redirected file written here, then you are seeing the result of redirected file writes due to lack of permissions to write to the original location. It is a policy controlled feature with a number of snags to be aware of. Details below.


Bitness?:你确定你在寻找正确的文件夹吗?您是否已签入 Program Files (x86) 以确认?


虚拟化/数据重定向:我想知道您是否启用了自动神奇地将安全文件夹中的失败写入重定向到另一个的策略可写位置? User Account Control: Virtualize file and registry write failures to per-user locations.

数据重定向/虚拟化策略条目:

Note: The local security policy applet is available only in professional, enterprise and corporate editions of Windows. It will be lacking in "home editions".

要查找和更改此政策,请执行以下操作(或其他等效方式):

  1. Windows Key + 点击 R.
  2. 复制和粘贴:%windir%\system32\secpol.msc /s.
  3. 单击 OK 或单击 Enter.
  4. 导航至:Local Policies\Security Options。查找条目:User Account Control: Virtualize file and registry write failures to per-user locations.
  5. 这个设置是否设置为“Activated”?

Prerequisite Conditions: Even if this setting is set to activated, redirection only works under very specific circumstances. For a program to be eligible for virtualization it must comply as follow:

  1. Bitness: Program must be 32bit.
  2. Access Rights: Must not run with administrator rights.
  3. Manifest: Must not have been compiled with a manifest file (indicating it is for Vista or later). Or you comment out the security section.

(see below for technical details on how to create a test application). All of this from this source. And here is another SO answer.

Task Manager & Virtualization:可以看到virtualization status的通过将 Virtualization column 添加到任务管理器中的进程页面的程序(在 Windows 10 中使用详细信息视图 - 它应该在那里显示类似 UAC-Virtualization 的内容) :

Where Does It Write?:如果此数据重定向/虚拟化设置处于活动状态,日志将自动重定向到可写位置同时仍然在您的应用程序中显示原始路径。请检查:%LocalAppData%\VirtualStore。程序:

  1. Windows Key + 点击 R.
  2. 复制和粘贴:%LocalAppData%\VirtualStore.
  3. 单击 OK 或单击 Enter.
  4. 检查子文件夹(如果有)。

Solution: This problem can be dealt with in several ways.

  1. Write Location: Write to a writable location outright - by design. This is the only sane approach for the future in my opinion.

  2. ACL Permissions: You can open write permission to the location in question and allow users or everyone write access. I do not like this approach security-wise.

  3. Elevate: I suppose you can run the application with admin rights by using an elevation manifest. I really do not like this approach. Elevated applications are given "the keys to the city" and represent a major security risk.

There are some flavors of these "solutions", but I think I will suggest these three for now. Maybe check the below link(s).


技术说明:仅作记录。关于我用来调试的测试应用程序:

  1. 标准 Windows Forms C# 应用程序。
  2. 在按钮点击事件上或直接在主函数中:File.WriteAllText(@"C:\Program Files\My folder\TestFile.txt", "Test");(先创建路径并根据您的语言调整 "Program Files" 部分)
  3. Project => Add New Item... => Application Manifest File.
  4. 注释掉整个 "Security" 部分。
  5. 编译 32 位可执行文件。

现在尝试构建 运行。您应该会在 Task ManagerUAC-Virtualization 列 中看到为虚拟化激活的应用程序(上面的屏幕截图)。如果数据重定向/虚拟化策略处于活动状态,则单击该按钮应写入 %LocalAppData%\VirtualStore


一些链接: