从 ASP 脚本使用 wscript.shell 时无法引用 UNC 路径?
我在使用 wscript.shell 对象通过 ASP 脚本从命令行执行命令时遇到问题。
这是我的代码:
inPath = server.mappath("/connect/dev_f_fusion3/video/6EA63679C27E48538D79F7C7295201CF/6EA63679C27E48538D79F7C7295201CF.mov")
outPath = server.mappath("/connect/dev_f_fusion3/video/6EA63679C27E48538D79F7C7295201CF\6EA63679C27E48538D79F7C7295201CF.flv"
outPath = "\\webdev2\SVC\streams\dev_f_fusion3\6EA63679C27E48538D79F7C7295201CF.flv"
dim cmd
dim wshell
dim wffm
cmd = """C:\Program Files\ffmpeg\ffmpeg.exe"" -i """ & inPath & """ -ar ""22050"" -ab ""32"" -f ""flv"" -s ""320x240"" """ & outPath & """"
set wshell = server.createobject("wscript.shell")
set wffm = wshell.exec(cmd)
set wffm = nothing
set wshell = nothing
如您所见,我已经定义了变量 outPath 两次作为示例,以便您帮助我。对于第一个 outPath 分配,wscript.shell 对象执行得很好,但是,对于第二个 outPath 分配,它失败了,这让我相信它与我指定为 outPath 的 UNC 路径有关。
是否不允许 wscript.shell 对象访问 UNC 路径?如果是这样,我可以在哪里更改它以便允许他们?
感谢您的帮助!
I'm having a problem executing a command from a command line through an ASP script using the wscript.shell object.
Here is my code:
inPath = server.mappath("/connect/dev_f_fusion3/video/6EA63679C27E48538D79F7C7295201CF/6EA63679C27E48538D79F7C7295201CF.mov")
outPath = server.mappath("/connect/dev_f_fusion3/video/6EA63679C27E48538D79F7C7295201CF\6EA63679C27E48538D79F7C7295201CF.flv"
outPath = "\\webdev2\SVC\streams\dev_f_fusion3\6EA63679C27E48538D79F7C7295201CF.flv"
dim cmd
dim wshell
dim wffm
cmd = """C:\Program Files\ffmpeg\ffmpeg.exe"" -i """ & inPath & """ -ar ""22050"" -ab ""32"" -f ""flv"" -s ""320x240"" """ & outPath & """"
set wshell = server.createobject("wscript.shell")
set wffm = wshell.exec(cmd)
set wffm = nothing
set wshell = nothing
As you can see I've defined the variable outPath twice as an example for you to help me. With the first outPath assignment the wscript.shell object executes just fine, however, with the second outPath assignment it fails, leading me to believe it has something to do with the UNC path I've specified as the outPath.
Is the wscript.shell object not allowed to access UNC paths? If so where I can change it so that it will allow them?
Thanks for the help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
听起来问题有两个潜在根源:
1. 与启动新进程并让该进程访问 UNC 共享相关的问题
2. 与权限相关的问题是否使用新进程来访问 UNC 共享
我将从测试 #2 开始,检查您的站点是否可以从远程共享读取文件,而无需启动新进程来执行此操作所以。例如:
如果失败,那么您的问题可能相对容易解决:您的网站无法访问远程共享。要解决此问题,最简单的方法是使用匿名身份验证并选择有权访问共享的匿名用户。这是一个教程,解释了如何执行此操作。确保按照教程的建议禁用集成 Windows 身份验证!
还要确保您非常小心地处理和转义转换为 EXE 路径的用户输入,因为您确实不希望恶意访问者能够在您的网络上运行任意代码!理想情况下,您永远不会直接根据用户输入创建执行路径或命令行参数的任何部分,而只能间接创建(例如,使用用户输入在数据库中查找已知安全的文件名,然后使用该数据库结果在你的道路上)。
还有其他方法(域用户下的匿名身份验证除外)可以启用远程访问,包括委派、通过 HTTPS 使用基本身份验证等。如果您无法使用匿名身份验证,请告诉我更多详细信息,我可以帮助您解决找出正确的选择。
但是,如果上面的文件访问测试成功,则您的问题会更复杂 - 这意味着 IIS 进程内运行的代码具有正确的访问权限,但生成的进程不会继承访问远程资源的能力。
更新:根据下面的评论,您已经诊断出问题是生成的进程是在错误的用户帐户下启动的。这可以通过直接调用一些 Win32 API 来解决,并且也有 .NET 解决方案,但除非您习惯于 VBScript 之外的环境,否则这可能超出您现在想要的范围。
您可以将文件从远程计算机复制到本地计算机上的临时文件中,然后运行 FFMPEG.EXE,然后(如果需要)将更改保存回远程服务器,最后删除临时文件吗?
如果你能做到这一点,它将避免此线程中描述的问题,将更容易捕获 ASP 代码中的其他问题(例如网络故障),而不是隐藏在 FFMPEG.EXE 中,并且它甚至可以提高性能,具体取决于如何FFMPEG.EXE 有效地处理远程文件访问。
下面是一些用于将远程文件复制到临时本地位置的代码。警告,下面可能有一些拼写错误,因为我将一些示例粘合在一起来创建它,并且没有时间亲自测试它。
我相信这种本地复制方法将为您提供最佳的可靠性和可能的最佳性能,因为通过网络连接复制整个文件通常比一次读取一个块更快。此外,如果最有可能失败的操作(网络文件访问)发生在您的代码而不是其他人的代码中,您的错误处理和调试也会更容易。
但是,如果您确信需要使用 UNC 访问权限调用 EXE,那么最好的选择是使用 C++、C# 或 VB 构建 COM 组件,以取代 Wsh.Shell 作为进程启动器。我建议使用 .NET 语言而不是本机 C++ 来构建组件,因为调用会更容易。如果您在 .NET 中执行此操作,则需要使用
System.Diagnostics.Process
类,使用ProcessStartInfo
类来指定要使用的用户名/密码。您还可以尝试使用
WNetAddConnection2< 创建连接/code>
,然后使用
CreateProcess
或类似的 Win32 API(或其 .NET 等效项)启动进程,但您可能需要尝试一下才能找到要使用的正确参数。换句话说,构建这个包装器是一个非常困难的问题。您最好的选择可能是您当前的解决方法。
Sounds like there are two potential sources of the problem here:
1. issues related to launching a new process and having that process access a UNC share
2. issues related to permissions whether or not a new process is used to acces the UNC share
I'd start by testing #2, by checking to see if your site can read a file from the remote share without launching a new process to do so. For example:
If this fails, then your problem is probably relatively straightforward to solve: your website doesn't have access to the remote share. To fix, the easiest way would be to use anonymous authentication and pick an anonymous user with access to the share. Here's a tutorial explaing how to do this. Make sure to disable integrated windows auth, as the tutorial recommends!
Also make sure you are very careful with how you are processing and escaping user input that gets transformed into your EXE path, since you really don't want to enable a malicious visitor to be able to run arbitrary code on your network! Ideally, you'd never create any part of an executed path or command-line args directly based on user input, but only indirectly (e.g. use user input to look up a known-safe filename in a DB, and then use that DB result in your path).
There are other ways (other than anonymous auth under a domain user) to enable remote access, including delegation, using basic auth over HTTPS, etc. Let me know with more details if you can't use anonymous auth and I can help you figure out the right alternative.
However, if the file-access test above succeeds, your problem is more complex-- it means that code running inside the IIS process has the correct access, but a spawned process doesn't inherit the ability to access remote resources.
UPDATE: per your comment below, you've diagnosed that the problem is that the spawned process is launched under the wrong user account. This is fixable by calling some Win32 APIs directly, and there are .NET solutions too, but unless you're comfortable outside VBScript that may be more than you'll want to take on right now.
Can you copy the file from the remote machine into a temporary file on the local machine, then run FFMPEG.EXE, then (if you need to) save back changes to the remote server, and finally delete the temporary file?
If you can do this, it will avoid the problem described in this thread, will make it easier to catch other problems (e.g. network failure) inside your ASP code rather than hidden inside FFMPEG.EXE, and it may even boost performance depending on how efficiently FFMPEG.EXE handles remote file access.
Here's some code for copying a remote file into a temporary local location. Warning, there may be some typos below as I glued together a few samples to create it and haven't had time to test it myself.
I believe that this local-copying approach will give you the best reliability and probably best performance since copying entire files over a network connection is usually faster than reading one chunk at a time. Also your error handling and debugging will be easier if the operations most likley to fail (the networked file access) happen inside your code rather than someone else's.
But if you are convinced that calling your EXE with a UNC access is required, your best bet is building a COM component using C++, C#, or VB which replaces Wsh.Shell as your process launcher. I'd recomend building the component using a .NET language instead of native C++ because the calls will be much easier. If you do it in .NET, you'll want to use the
System.Diagnostics.Process
class to launch your process, using theProcessStartInfo
class to specify the username/password to use.You can also try creating a connection using
WNetAddConnection2
and then launch your process usingCreateProcess
or a similar Win32 API (or its .NET equivalent), but you may need to to play around to find the right parameters to use.In other words, it's a non-trivially hard problem to build this wrapper. Your best bet is probably your current workaround.
假设您使用 IIS 6,请查看这些链接
Assuming you use IIS 6, have a look at these links
如果您发布了所遇到的具体错误,将会很有帮助。此请求使用什么类型的身份验证?如果您使用匿名,则需要使用域匿名用户,或使用在目标服务器上具有相同用户名和密码的本地帐户。
It would be helpful if you posted the specific error that you are getting. What type of authentication is being used for this request? If you are using anonymous then you need to use a domain anon user, or use a local account that has the same username and password on the target server.