windows 映射服务使用的网络驱动器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/182750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:30:06  来源:igfitidea点击:

Map a network drive to be used by a service

windowswindows-servicesuncsystem-administrationmapped-drive

提问by VoidPointer

Suppose some Windows service uses code that wants mapped network drives and no UNC paths. How can I make the drive mapping available to the service's session when the service is started? Logging in as the service user and creating a persistent mapping will not establish the mapping in the context of the actual service.

假设某些 Windows 服务使用需要映射网络驱动器且没有 UNC 路径的代码。如何在服务启动时使驱动器映射可用于服务会话?以服务用户身份登录并创建持久映射不会在实际服务的上下文中建立映射。

采纳答案by mdb

You'll either need to modify the service, or wrap it inside a helper process: apart from session/drive access issues, persistent drive mappings are only restored on an interactive logon, which services typically don't perform.

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

The helper process approach can be pretty simple: just create a new service that maps the drive and starts the 'real' service. The only things that are not entirely trivial about this are:

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

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

  • 辅助服务需要将所有适当的 SCM 命令(启动/停止等)传递给实际服务。如果真正的服务接受自定义 SCM 命令,请记住也传递这些命令(尽管我不希望考虑 UNC 路径的服务使用此类命令...)

  • 在凭据方面,事情可能会变得有点棘手。如果真实服务在普通用户帐户下运行,您也可以在该帐户下运行帮助服务,只要该帐户对网络共享具有适当的访问权限,一切都应该没问题。如果真正的服务只能在以 LOCALSYSTEM 或类似方式运行时才能工作,那么事情会变得更有趣,因为它要么根本无法“看到”网络驱动器,要么需要一些凭据处理才能使事情发挥作用。

回答by ForcePush

Use this at your own risk. (I have tested it on XP and Server 2008 x64 R2)

使用它需要您自担风险。(我已经在 XP 和 Server 2008 x64 R2 上测试过了)

For this hack you will need SysinternalsSuite by Mark Russinovich:

对于这个 hack,你需要Mark Russinovich 的 SysinternalsSuite

Step one:Open an elevated cmd.exe prompt (Run as administrator)

第一步:打开提升的 cmd.exe 提示(以管理员身份运行)

Step two:Elevate again to root using PSExec.exe: Navigate to the folder containing SysinternalsSuite and execute the following command psexec -i -s cmd.exeyou are now inside of a prompt that is nt authority\systemand you can prove this by typing whoami. The -iis needed because drive mappings need to interact with the user

第二步:使用 PSExec.exe 再次提升为 root:导航到包含 SysinternalsSuite 的文件夹并执行以下命令, psexec -i -s cmd.exe您现在处于提示中nt authority\system,您可以通过键入来证明这一点whoami。该-i是必要的,因为驱动器映射需要互动与用户

Step Three:Create the persistent mapped drive as the SYSTEM account with the following command net use z: \\servername\sharedfolder /persistent:yes

第三步:使用以下命令创建持久映射驱动器作为 SYSTEM 帐户 net use z: \\servername\sharedfolder /persistent:yes

It's that easy!

就这么简单!

WARNING: You can only remove this mapping the same way you created it, from the SYSTEM account. If you need to remove it, follow steps 1 and 2 but change the command on step 3 to net use z: /delete.

警告:您只能以与创建它相同的方式从 SYSTEM 帐户中删除此映射。如果您需要删除它,请按照步骤 1 和 2 操作,但将步骤 3 中的命令更改为net use z: /delete

NOTE: The newly created mapped drive will now appear for ALL users of this system but they will see it displayed as "Disconnected Network Drive (Z:)". Do not let the name fool you. It may claim to be disconnected but it will work for everyone. That's how you can tell this hack is not supported by M$.

注意:新创建的映射驱动器现在将显示给该系统的所有用户,但他们会看到它显示为“断开的网络驱动器 (Z:)”。不要让这个名字欺骗了你。它可能声称已断开连接,但它对每个人都有效。这就是您如何判断 M$ 不支持此 hack 的方式。

回答by larry

I found a solution that is similar to the one with psexec but works without additional tools and survives a reboot.

我找到了一个与 psexec 类似的解决方案,但无需其他工具即可工作,并且可以在重新启动后幸免于难

Just add a sheduled task, insert "system" in the "run as" field and point the task to a batch file with the simple command

只需添加一个调度任务,在“运行方式”字段中插入“系统”,然后使用简单命令将任务指向批处理文件

net use z: \servername\sharedfolder /persistent:yes

Then select "run at system startup" (or similar, I do not have an English version) and you are done.

然后选择“在系统启动时运行”(或类似的,我没有英文版本)就大功告成了。

回答by Hal

A better way would be to use a symbolic link using mklink.exe. You can just create a link in the file system that any app can use. See http://en.wikipedia.org/wiki/NTFS_symbolic_link.

更好的方法是使用 mklink.exe 使用符号链接。您可以在文件系统中创建任何应用程序都可以使用的链接。请参阅http://en.wikipedia.org/wiki/NTFS_symbolic_link

回答by philu

There is a good answer here: https://superuser.com/a/651015/299678

这里有一个很好的答案:https: //superuser.com/a/651015/299678

I.e. You can use a symbolic link, e.g.

即您可以使用符号链接,例如

mklink /D C:\myLink \127.0.0.1\c$

回答by Treb

You could us the 'net use' command:

您可以使用“net use”命令:

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

If that does not work in a service, try the Winapi and PInvoke WNetAddConnection2

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

Edit:Obviously I misunderstood you - you can not change the sourcecode of the service, right? In that case I would follow the suggestion by mdb, but with a little twist: Create your own service (lets call it mapping service) that maps the drive and add this mapping service to the dependencies for the first (the actual working) service. That way the working service will not start before the mapping service has started (and mapped the drive).

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

回答by lk7777

ForcePush,

力推,

NOTE: The newly created mapped drive will now appear for ALL users of this system but they will see it displayed as "Disconnected Network Drive (Z:)". Do not let the name fool you. It may claim to be disconnected but it will work for everyone. That's how you can tell this hack is not supported by M$...

注意:新创建的映射驱动器现在将显示给该系统的所有用户,但他们会看到它显示为“断开的网络驱动器 (Z:)”。不要让这个名字欺骗了你。它可能声称已断开连接,但它对每个人都有效。这就是您如何判断 M$ 不支持此 hack 的方式...

It all depends on the share permissions.If you have Everyone in the share permissions, this mapped drive will be accessible by other users. But if you have only some particular user whose credentials you used in your batch script and this batch script was added to the Startup scripts, only System account will have access to that share not even Administrator. So if you use, for example, a scheduled ntbackuo job, System account must be used in 'Run as'. If your service's 'Log on as: Local System account' it should work.

这完全取决于共享权限。如果您拥有“所有人”的共享权限,则其他用户可以访问此映射驱动器。但是,如果您只有某些特定用户的凭据,并且您在批处理脚本中使用了该用户的凭据,并且此批处理脚本已添加到启动脚本中,则只有系统帐户才能访问该共享,甚至管理员都不能访问。因此,例如,如果您使用预定的 ntbackuo 作业,则必须在“运行方式”中使用系统帐户。如果您的服务的“登录身份:本地系统帐户”应该可以工作。

What I did, I didn't map any drive letter in my startup script, just used net use \\\server\share ...and used UNC path in my scheduled jobs. Added a logon script (or just add a batch file to the startup folder) with the mapping to the same share with some drive letter: net use Z: \\\...with the same credentials. Now the logged user can see and access that mapped drive. There are 2 connections to the same share. In this case the user doesn't see that annoying "Disconnected network drive ...". But if you really need access to that share by the drive letter not just UNC, map that share with the different drive letters, e.g. Y for System and Z for users.

我所做的,我没有在我的启动脚本中映射任何驱动器号,只是net use \\\server\share ...在我的计划作业中使用和使用了 UNC 路径。添加了一个登录脚本(或者只是将一个批处理文件添加到启动文件夹),并映射到具有某些驱动器号的相同共享:net use Z: \\\...具有相同的凭据。现在登录的用户可以查看和访问该映射驱动器。有 2 个连接到同一共享。在这种情况下,用户不会看到烦人的“网络驱动器断开连接...”。但是,如果您真的需要通过驱动器号而不只是 UNC 访问该共享,请使用不同的驱动器号映射该共享,例如 Y 代表系统,Z 代表用户。

回答by Val

Found a way to grant Windows Service access to Network Drive.

找到一种方法来授予 Windows 服务访问网络驱动器的权限。

Take Windows Server 2012 with NFS Disk for example:

以带有 NFS 磁盘的 Windows Server 2012 为例:

Step 1: Write a Batch File to Mount.

第 1 步:写入要挂载的批处理文件。

Write a batch file, ex: C:\mount_nfs.bat

编写一个批处理文件,例如:C:\mount_nfs.bat

echo %time% >> c:\mount_nfs_log.txt
net use Z: \{your ip}\{netdisk folder}\ >> C:\mount_nfs_log.txt 2>&1

Step 2: Mount Disk as NT AUTHORITY/SYSTEM.

第 2 步:将磁盘挂载为 NT AUTHORITY/SYSTEM。

Open "Task Scheduler", create a new task:

打开“任务计划程序”,新建一个任务:

  1. Run as "SYSTEM", at "System Startup".
  2. Create action: Run "C:\mount_nfs.bat".
  1. 在“系统启动”时以“SYSTEM”身份运行。
  2. 创建操作:运行“C:\mount_nfs.bat”。

After these two simple steps, my Windows ActiveMQ Service run under "Local System" priviledge, perform perfectly without login.

经过这两个简单的步骤,我的Windows ActiveMQ服务在“本地系统”权限下运行,无需登录即可完美运行。

回答by Kushagra

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.

当您通常从命令提示符运行可执行文件时,您能够访问驱动器的原因是,当您将它作为普通 exe 执行时,您是在您登录的用户帐户中运行该应用程序。并且该用户具有访问网络的权限。但是,当您将可执行文件安装为服务时,默认情况下,如果您在任务管理中看到它在“SYSTEM”帐户下运行。您可能知道“SYSTEM”无权访问网络资源。

There can be two solutions to this problem.

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

  1. To map the drive as persistent as already pointed above.

  2. 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).aspxand can set the parameter 'lpServiceStartName ' to 'NT AUTHORITY\NetworkService'. This will start your service under 'Network Service' account and then you are done.

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

  1. 将驱动器映射为上面已经指出的持久性。

  2. 还有一种方法可以遵循。如果您通过键入“services.msc”打开服务管理器,您可以转到您的服务,在您的服务属性中有一个登录选项卡,您可以在其中将帐户指定为“系统”以外的任何其他帐户,您可以从您自己登录的用户帐户或通过“网络服务”启动服务。当您这样做时.. 该服务可以访问任何网络组件和驱动器,即使它们也不是持久的。要以编程方式实现此目的,您可以查看http://msdn.microsoft.com/en-us/library/ms682450(v=vs.85).aspx 上的“CreateService”功能, 并可以将参数“lpServiceStartName”设置为“NT”权威\网络服务'。这将在“网络服务”下启动您的服务

  3. 您也可以尝试通过在 CreateService() 函数的 servicetype 参数标志中指定 SERVICE_INTERACTIVE_PROCESS 来使服务具有交互性,但这将仅限于 XP,因为 Vista 和 7 不支持此功能。

Hope the solutions help you.. Let me know if this worked for you .

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

回答by Torbj?rn Gyllebring

You wan't to either change the user that the Service runs under from "System" or find a sneaky way to run your mapping as System.

您既不想从“系统”更改服务在其下运行的用户,也不想找到一种偷偷摸摸的方式将您的映射作为系统运行。

The funny thing is that this is possible by using the "at"command, simply schedule your drive mapping one minute into the future and it will be run under the System account making the drive visible to your service.

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