windowsscheduled-tasksuser-accountswindows-networkingnetwork-shares

Network address inaccessible if ran by the Task Scheduler


I have a C# program that does this:

Directory.Exists(@"\\PcName\SomeDir");

and prints whether that path is accessible (exists) or not.

This is the problem: I run this app via the Task Scheduler right after log-in (auto-log-in user), using the "On Login" trigger, and it returns false, although that path IS accessible! (I manage to open that path using the explorer.exe few seconds before my app starts). It is marked to:

Run with highest privileges

If I run it manually it runs OK, even when I right click the task and select "Run" via the Task Scheduler!


Solution

  • Problem solved. I had to "impersonate", although I’m not really sure why: if I use the scheduler without restarting, it accesses the remote share – exactly the same settings, one to one. Only after restart it fails to access the share (and a moment later, again – same settings, it is able to access).

    The only difference in running it immediately after restart is that the app-process’s parent is services.exe and not explorer.exe as usual. My guess is that it has to log in immediately after the restart, so it must use services.exe (explorer.exe is not supposed to exist at that stage, if I'm not mistaken).

    Below is the solution in C#, roughly, to whom it may concern:

    // LogonUser is a "P/Invoked" API:
    // http://www.pinvoke.net/default.aspx/advapi32/LogonUser.html
    // this solution works only with the LOGON32_LOGON_NEW_CREDENTIALS as the 4th parameter:
    using (var h = LogonUser(username, domain, password, 
        LogonType.LOGON32_LOGON_NEW_CREDENTIALS, 
        LogonProvider.LOGON32_PROVIDER_DEFAULT))
    {
        using (var winImperson8Ctx = WindowsIdentity.Impersonate(h.DangerousGetHandle())) {
            return Directory.Exists(path); // now works fine...    
        }
    }