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\6EA63679C27E48538D79F7C7开发者_运维百科295201CF.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!
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:
<%
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
%>
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.
<%
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
%>
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 the ProcessStartInfo
class to specify the username/password to use.
You can also try creating a connection using WNetAddConnection2
and then launch your process using CreateProcess
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.
Assuming you use IIS 6, have a look at these links
- Using UNC path as paths location in Mercurial IIS6 Server2003
- http://forums.iis.net/t/1149805.aspx
- http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/f72cfb8b-84e4-47e1-824a-db1bbb4aebff.mspx?mfr=true
- http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/cd02642c-8389-4563-9cd2-bae8a516c722.mspx?mfr=true
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.
精彩评论