假设一些Windows服务使用的代码需要映射网络驱动器,而不需要UNC路径。当服务启动时,如何使驱动器映射可用于服务的会话?作为服务用户登录并创建持久映射将不会在实际服务的上下文中建立映射。


当前回答

而不是依赖于一个持久驱动器,你可以设置脚本映射/取消映射驱动器每次你使用它:

net use Q: \\share.domain.com\share 
forfiles /p Q:\myfolder /s /m *.txt /d -0 /c "cmd /c del @path"
net use Q: /delete

这对我很有用。

其他回答

您要么需要修改服务,要么将其包装到辅助进程中:除了会话/驱动器访问问题外,持久驱动器映射仅在交互式登录时恢复,而服务通常不会执行。

helper进程方法可以非常简单:只需创建一个映射驱动器的新服务并启动“真正的”服务。唯一不是完全无关紧要的事情是:

The helper service will need to pass on all appropriate SCM commands (start/stop, etc.) to the real service. If the real service accepts custom SCM commands, remember to pass those on as well (I don't expect a service that considers UNC paths exotic to use such commands, though...) Things may get a bit tricky credential-wise. If the real service runs under a normal user account, you can run the helper service under that account as well, and all should be OK as long as the account has appropriate access to the network share. If the real service will only work when run as LOCALSYSTEM or somesuch, things get more interesting, as it either won't be able to 'see' the network drive at all, or require some credential juggling to get things to work.

而不是依赖于一个持久驱动器,你可以设置脚本映射/取消映射驱动器每次你使用它:

net use Q: \\share.domain.com\share 
forfiles /p Q:\myfolder /s /m *.txt /d -0 /c "cmd /c del @path"
net use Q: /delete

这对我很有用。

The reason why you are able to access the drive in when you normally run the executable from command prompt is that when u are executing it as normal exe you are running that application in the User account from which you have logged on . And that user has the privileges to access the network. But , when you install the executable as a service , by default if you see in the task manage it runs under 'SYSTEM' account . And you might be knowing that the 'SYSTEM' doesn't have rights to access network resources.

这个问题有两种解决方案。

To map the drive as persistent as already pointed above. There is one more approach that can be followed. If you open the service manager by typing in the 'services.msc'you can go to your service and in the properties of your service there is a logOn tab where you can specify the account as any other account than 'System' you can either start service from your own logged on user account or through 'Network Service'. When you do this .. the service can access any network component and drive even if they are not persistent also. To achieve this programmatically you can look into 'CreateService' function at http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx and can set the parameter 'lpServiceStartName ' to 'NT AUTHORITY\NetworkService'. This will start your service under 'Network Service' account and then you are done. You can also try by making the service as interactive by specifying SERVICE_INTERACTIVE_PROCESS in the servicetype parameter flag of your CreateService() function but this will be limited only till XP as Vista and 7 donot support this feature.

希望这些解决方案对你有帮助。如果这对你有用,请告诉我。

你可以使用'net use'命令:

var p = System.Diagnostics.Process.Start("net.exe", "use K: \\\\Server\\path");
var isCompleted = p.WaitForExit(5000);

如果这在服务中不起作用,请尝试Winapi和PInvoke WNetAddConnection2

编辑:显然我误解你了——你不能改变服务的源代码,对吗?在这种情况下,我会遵循mdb的建议,但稍微改变一下:创建自己的服务(让我们称之为映射服务)来映射驱动器,并将这个映射服务添加到第一个(实际工作的)服务的依赖项中。这样,在映射服务启动(并映射驱动器)之前,工作服务将不会启动。

您既不想从“System”更改服务运行的用户,也不想找到一种狡猾的方式将映射运行为System。

有趣的是,这可以通过使用“at”命令,简单地将您的驱动器映射安排到未来一分钟,它将在系统帐户下运行,使驱动器对您的服务可见。