听起来这里有两个潜在的问题来源:
1. 与启动新进程和让该进程访问 UNC 共享相关的问题
2. 是否使用新进程访问UNC共享的权限相关问题
我将从测试 #2 开始,检查您的站点是否可以在不启动新进程的情况下从远程共享读取文件。例如:
<%
dim filesys, filetxt
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set filesys = CreateObject("Scripting.FileSystemObject")
Set filetxt = filesys.OpenTextFile("\\webdev2\SVC\streams\dev_f_fusion3\testfile.txt", ForReading, True)
Response.Write (filetxt.ReadAll())
filetxt.Close
%>
如果失败,那么您的问题可能比较容易解决:您的网站无权访问远程共享。要解决此问题,最简单的方法是使用匿名身份验证并选择有权访问共享的匿名用户。这是tutorial 解释如何执行此操作。确保按照教程的建议禁用集成 Windows 身份验证!
还要确保您在处理和转义转换为 EXE 路径的用户输入时非常小心,因为您真的不希望恶意访问者能够在您的网络上运行任意代码!理想情况下,您永远不会直接基于用户输入创建执行路径或命令行参数的任何部分,而只是间接创建(例如,使用用户输入在数据库中查找已知安全的文件名,然后使用该数据库结果在你的道路上)。
还有其他方法(域用户下的匿名身份验证除外)启用远程访问,包括委托、通过 HTTPS 使用基本身份验证等。如果您不能使用匿名身份验证,请告诉我更多详细信息,我可以帮助您找出正确的替代方案。
但是,如果上面的文件访问测试成功,您的问题就更复杂了——这意味着在 IIS 进程内运行的代码具有正确的访问权限,但衍生的进程不会继承访问远程资源的能力。
更新:根据您在下面的评论,您已诊断出问题在于生成的进程是在错误的用户帐户下启动的。这可以通过直接调用一些 Win32 API 来解决,并且也有 .NET 解决方案,但除非您在 VBScript 之外感到很自在,否则您现在可能不想承担更多。
您能否将远程计算机上的文件复制到本地计算机上的临时文件中,然后运行 FFMPEG.EXE,然后(如果需要)将更改保存回远程服务器,最后删除临时文件?
如果你能做到这一点,它将避免这个线程中描述的问题,将更容易在你的 ASP 代码中发现其他问题(例如网络故障)而不是隐藏在 FFMPEG.EXE 中,它甚至可以提高性能取决于 FFMPEG.EXE 处理远程文件访问的效率。
这里有一些用于将远程文件复制到临时本地位置的代码。警告,下面可能有一些拼写错误,因为我将一些示例粘在一起来创建它,并且没有时间自己测试它。
<%
dim filesys, filetxt
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set filesys = CreateObject("Scripting.FileSystemObject")
Const TemporaryFolder = 2
Dim tfolder, tname, tfile
Set tfolder = fso.GetSpecialFolder(TemporaryFolder)
tname = tFolder & "/" & fso.GetTempName
Dim remoteFilename
remoteFilename = "\\webdev2\SVC\streams\dev_f_fusion3\testfile.txt"
Const OverwriteExisting = True
filesys.CopyFile remoteFilename, tName, OverwriteExisting
%>
我相信这种本地复制方法将为您提供最佳的可靠性和可能的最佳性能,因为通过网络连接复制整个文件通常比一次读取一个块更快。如果最有可能失败的操作(网络文件访问)发生在您的代码中而不是其他人的代码中,那么您的错误处理和调试也会更容易。
但是,如果您确信需要使用 UNC 访问权限调用您的 EXE,那么最好的办法是使用 C++、C# 或 VB 构建一个 COM 组件,以取代 Wsh.Shell 作为您的进程启动器。我建议使用 .NET 语言而不是本机 C++ 来构建组件,因为调用会容易得多。如果您在 .NET 中执行此操作,您将需要使用 System.Diagnostics.Process 类来启动您的进程,使用 ProcessStartInfo 类来指定要使用的用户名/密码。
您也可以尝试使用 WNetAddConnection2 创建连接,然后使用 CreateProcess 或类似的 Win32 API(或其 .NET 等效项)启动您的进程,但您可能需要尝试找到正确的参数以采用。
换句话说,构建这个包装器是一个非常困难的问题。您最好的选择可能是您当前的解决方法。