231

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

4

13 回答 13

234

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

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

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

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

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

就这么容易!

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

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

于 2011-01-21T20:11:54.390 回答
74

我找到了一个与 psexec 类似的解决方案,但无需其他工具即可工作并且在重新启动后仍然有效。

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

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

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

于 2011-10-23T15:28:21.537 回答
48

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

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

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

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

于 2008-10-08T13:48:29.540 回答
46

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

于 2011-10-26T15:16:17.870 回答
29

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

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

mklink /D C:\myLink \\127.0.0.1\c$
于 2016-06-03T02:38:22.953 回答
9

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

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

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

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

于 2008-10-08T13:38:23.370 回答
5

力推,

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

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

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

于 2014-01-22T15:14:37.630 回答
4

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

以带有 NFS Disk 的 Windows Server 2012 为例:

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

编写一个批处理文件,例如: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

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

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

  1. 在“系统启动”中以“SYSTEM”身份运行。
  2. 创建操作:运行“C:\mount_nfs.bat”。

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

于 2016-01-20T09:13:42.037 回答
3

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

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

  1. 将驱动器映射为如上所述的持久性。

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

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

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

于 2010-09-29T11:51:53.947 回答
1

您可以将脚本设置为每次使用驱动器时映射/取消映射驱动器,而不是依赖持久驱动器:

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

这对我有用。

于 2018-01-26T20:57:47.490 回答
0

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

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

于 2008-10-08T13:37:56.350 回答
0

我还不能发表评论(致力于声誉),但创建了一个帐户只是为了回答@Tech Jerk @spankmaster79(好名字哈哈)和@NMC 问题,他们在回复“我找到了一个与psexec,但无需其他工具即可工作,并且可以在重新启动后继续存在。” @Larry 发布的帖子。

解决方案是从登录帐户中浏览到该文件夹​​,即:

    \\servername\share  

并让它提示登录,并在 psexec 中输入您用于 UNC 的相同凭据。之后它开始工作。就我而言,我认为这是因为具有该服务的服务器与我映射到的服务器不是同一域的成员。我在想如果 UNC 和计划任务都引用 IP 而不是主机名

    \\123.456.789.012\share 

它可以完全避免这个问题。

如果我在这里获得足够的代表点数,我会将其添加为回复。

于 2016-06-06T19:16:00.610 回答
0

我找到了一个非常简单的方法:使用powershell的命令“New-SmbGlobalMapping”,它将全局挂载驱动器:

$User = "usernmae"
$PWord = ConvertTo-SecureString -String "password" -AsPlainText -Force
$creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
New-SmbGlobalMapping -RemotePath \\192.168.88.11\shares -Credential $creds -LocalPath S:
于 2021-11-26T06:22:05.143 回答