Search code examples
windows-installerlog4netvisual-studio-extensionswindows-explorervdproj

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


I use log4net for my desktop application written in c# and deployed using Visual Studio Extension "Microsoft Visual Studio Installer Projects" (MSI-Installer). After installation I do not see the log subfolder defined for log4net.

The TARGETDIR in "Microsoft Visual Studio Installer Projects" is defined as [ProgramFiles64Folder][Manufacturer]\[ProductName].

The log4net log file is defined as

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

After installing the application via the "Microsoft Visual Studio Installer Projects"-created setup.exe and msi-installer I do not see the log-folder in the Windows explorer under Program Files\MyManufacturer\MyProductName although Show hidden files, folders, ... is set.

For testing purposes I added the following code to my application:

// 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);

So, the log file under Program Files\MyManufacturer\MyProductName\log\MyApp.log can be accessed via the application and I see that it grows!

So the question is: Where is the log subdirectory ? How can I make it visible in the Wndows explorer ? Is this a permission issue ?


Solution

  • 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?: Are you sure you are looking in the right folder? Did you check in Program Files (x86) to be sure?


    Virtualization / Data Redirection: I am wondering if you have policies enabled that auto-magically redirect failed writes in secured folders to another writable location? User Account Control: Virtualize file and registry write failures to per-user locations.

    Data Redirect / Virtualization Policy Entry:

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

    To find and change this policy, please do as follows (or equivalent by other means):

    1. Windows Key + tap R.
    2. Copy & Paste: %windir%\system32\secpol.msc /s.
    3. Click OK or hit Enter.
    4. Navigate to: Local Policies\Security Options. Look for entry: User Account Control: Virtualize file and registry write failures to per-user locations.
    5. Is this setting set to "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: You can see the virtualization status of a program by adding the Virtualization column to the Processes page in Task Manager (in Windows 10 use the Details view - it should say something like UAC-Virtualization there):

    Task Manager UAC-Virtualization

    Where Does It Write?: If this data redirection / virtualization setting is active, the log is redirected to a writable location automatically whilst still showing the original path in your application. Please check under: %LocalAppData%\VirtualStore. Procedure:

    1. Windows Key + tap R.
    2. Copy & Paste: %LocalAppData%\VirtualStore.
    3. Click OK or hit Enter.
    4. Check sub folders (if any).

    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).


    Technical Notes: Just for the record. With regards to the test application I used to debug:

    1. Standard Windows Forms C# application.
    2. On a button click event or directly in the main function: File.WriteAllText(@"C:\Program Files\My folder\TestFile.txt", "Test"); (create path first and adjust "Program Files" part to your language)
    3. Project => Add New Item... => Application Manifest File.
    4. Comment out the whole "Security" section.
    5. Compile a 32-bit executable.

    Now try to build and run. You should see the application activated for virtualization in the UAC-Virtualization column of Task Manager (screenshot above). Clicking the button should write to %LocalAppData%\VirtualStore if the data redirect / virtualization policy is active.


    Some Links: