我有一个C#程序可以做到这一点:
Directory.Exists(@"\\PcName\SomeDir");
并打印该路径是否可访问(存在)。
这就是问题:我在登录后自动登录(自动登录用户)后通过Task Scheduler
运行此应用程序,使用“登录时”触发器,然后返回false
,虽然该路径 IS 可以访问! (我设法在应用程序启动前几秒使用explorer.exe打开该路径)。标记为:
Run with highest privileges
如果我手动运行它运行正常,即使我右键单击任务并通过Task Scheduler
选择“运行”!
如果我 取消选择 “以最高权限运行”,则没有问题,但必须以最高权限运行(访问注册表和整批其他的东西)
如果我手动或由任务调度程序自动运行它,它在同一用户下运行 - 我确保使用Process Explorer
它发生在某些机器上(Win8x64,admin-privileges-user没有密码,自动登录,工作组机器,不是域),但不在其他机器上(相同:Win8x64,admin-privileges-user)没有密码,自动登录,工作组机器,而不是域名。
即使我在任务中插入Thread.Sleep(TimeSpan.FromMinutes(1));
或输入1分钟延迟(在任务计划程序中),它仍然表示此路径不存在
答案 0 :(得分:0)
问题解决了。我不得不“冒充”,虽然我不确定为什么:如果我在没有重新启动的情况下使用调度程序,它会访问远程共享 - 完全相同的设置,一对一。只有在重新启动后才能访问共享(稍后,再次 - 相同的设置,它可以访问)。
重新启动后立即运行它的唯一区别是app-process的父级像往常一样services.exe
而不是explorer.exe
。我的猜测是它必须在重新启动后立即登录,所以它必须使用services.exe
(explorer.exe
不应该存在于该阶段,如果我没有记错的话。)
以下是C#
中的解决方案,粗略地说,可能与之关注的是:
// 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...
}
}