vbscript / Classic ASP-プログラムで独自のファイル名を取得する方法はありますか?
-
19-08-2019 - |
質問
古いコードを確認したところ、次のようなものが見つかりました(foo.asp内):
Const ASP_FILENAME = "foo.asp" ' TODO: Update this to the name of this file (if changed)
この変数は、エラーの記録にのみ使用されます。 (つまり、<!> quot; foo.aspのエラー-xxxxxオブジェクトを作成できませんでした。<!> quot;)これを回避する方法はありますか?
ありがとう!
解決
現在廃止されているAspfaq.comから( Archive.org ):
現在のURL /ページの名前を取得するにはどうすればよいですか
これは非常に簡単ですが、2つの部分があります。
現在のファイルの名前を取得するには、次のいずれかを使用できます。
<%
Response.Write Request.ServerVariables("SCRIPT_NAME") & "<br>"
Response.Write Request.ServerVariables("PATH_INFO") & "<br>"
Response.Write Request.ServerVariables("URL") & "<br>"
%>
そのパスをローカルにする(たとえば、FileSystemObjectで使用する)には、結果にserver.mappath()メソッドを適用するだけです。
http://またはhttps://プレフィックスを含むURL全体を取得するには、次のようにします。
<%
prot = "http"
https = lcase(request.ServerVariables("HTTPS"))
if https <> "off" then prot = "https"
domainname = Request.ServerVariables("SERVER_NAME")
filename = Request.ServerVariables("SCRIPT_NAME")
querystring = Request.ServerVariables("QUERY_STRING")
response.write prot & "://" & domainname & filename & "?" & querystring
%>
ページ名のみを取得するには、次のようなものを使用します:
<%
scr = Request.ServerVariables("SCRIPT_NAME") & "<br>"
if instr(scr,"/")>0 then
scr = right(scr, len(scr) - instrRev(scr,"/"))
end if
response.write scr
%>
または、IFロジックなし:
<%
scr = Request.ServerVariables("SCRIPT_NAME") & "<br>"
loc = instrRev(scr,"/")
scr = mid(scr, loc+1, len(scr) - loc)
response.write scr
%>
今。ファイルが別のファイル内の#INCLUDEである場合、上記のスクリプトはCALLINGファイルの名前を生成します(含まれているファイルが最初に呼び出しスクリプトに統合され、その中のASPがすべて「親」のコンテキストで実行されるため'ファイル)。これを回避する1つの方法は、各インクルードファイルをロードする前にcurrent_filename変数を再設定することです。例:
<%
current_filename = "filetoinclude.asp"
%>
<!--#include file='filetoinclude.asp'-->
(いいえ、#INCLUDEディレクティブに変数としてcurrent_filenameを渡さないでください。記事#2042を参照してください。)
次に、filetoinclude.aspで:
<%
Response.Write "Current file: " & current_filename
%>
もちろん、各インクルードファイル内のファイル名を同じくらい簡単にハードコーディングできます。しかし、その解決策は、少なくともある程度動的にその情報を取得する目的をやや損なうと思われます。
他のヒント
Request.ServerVariables("url")
を解析して、ファイル名の部分を取得できます。 Google検索でこのコードが見つかりました。クレジットを主張しないでください。これはSCRIPT_NAMEサーバー変数を使用しますが、これは実際にはより意味があるように思われます。
function getFileName(fpath, returnExtension)
tmp = fpath
if instrRev(tmp,"/") > 0 then
tmp = mid(tmp, instrRev(tmp,"/")+1)
end if
if returnExtension = false then
if instrRev(tmp,".") > 0 then
tmp = left(tmp, instrRev(tmp,".")-1)
end if
end if
getFileName = tmp
end function
filename = request.ServerVariables("SCRIPT_NAME")
Const ASP_FILENAME = getFileName(filename, true)
server.mappathが従来のaspに存在するかどうかはわかりませんが、存在する場合はページのファイル名を知るためにifを使用できます。
Not saying that anyone here [insert discrete throat clearing cough here] still uses Classic ASP for maintaining and supporting legacy applications, but I recently had the need to do something similar. Refusing to settle for the "it's impossible with Classic ASP" responses out there, I set out to find a way and came up with the following solution.
This approach basically leverages underlying OS commands to literally determine the current filename (whose result is equivalent to using the __FILE__
magic constant in PHP) regardless of whether it's a file include (*.inc
) or the script itself (*.asp
).
First, to support some sanitization (you can do this some other more "optimal" way if you wish):
'Regex helpers
Function NewRegex(ByVal pattern, ByVal ignore_case, ByVal global)
Set NewRegex = New RegExp
NewRegex.Pattern = pattern
NewRegex.IgnoreCase = ignore_case
NewRegex.Global = global
End Function
Function RegexMatch(ByVal pattern, ByVal subject)
RegexMatch = RegexMatches(subject, pattern, True, False)
End Function
Function RegexMatches(ByVal subject, ByVal pattern, ByVal ignore_case, ByVal global)
RegexMatches = NewRegex(pattern, ignore_case, global).Test(subject)
End Function
And now for a time of "reflection:"
Function GetCurrentFilename(ByVal uniqueId)
'1. Enforce uniqueId format
If Not RegexMatch("^[0-9a-f]+$", uniqueId) Then
Exit Function
End If
'2. Use findstr to scan "readable" files in current directory for uniqueId
Dim shell, cmd, process, fs, filename
Set shell = Server.CreateObject("WScript.Shell")
'See findstr /? for details on switches used below
'cmd = C:\Windows\system32\cmd.exe /c findstr /P /M /C:"uniqueId" "C:\Inetpub\wwwroot\includes\*"
cmd = shell.ExpandEnvironmentStrings("%COMSPEC%") & " /c findstr /P /M /C:""" & uniqueId & """ """ & Server.MapPath(".") & "\*"""
Set process = shell.Exec(cmd)
'3. Use Scripting.FileSystemObject to return the filename portion of the first result returned
Set fs = Server.CreateObject("Scripting.FileSystemObject")
GetCurrentFilename = fs.GetFileName(process.StdOut.ReadLine())
Set fs = Nothing
Set process = Nothing
Set shell = Nothing
End Function
Then, inside whatever file you want to "inspect" the current filename, simply drop the following line, passing in some unique identifier that should not exist in any other file in the current directory but this one:
'myfile.inc
Response.Write "This is in " & GetCurrentFilename("908ab098c")
The result:
This is in somefile.inc
Oh, and if you're interested in what I needed to use this for, here's what it looks like used in a simple breakpoint function:
Function Breakpoint(ByVal line_no, ByVal uniqueId, ByVal msg)
Dim fn
fn = GetCurrentFilename(uniqueId)
Response.Write "[!] Breakpoint hit at Line " & CLng(line_no) & " in " & fn & ": " & Server.HtmlEncode(msg) & vbNewLine
Response.End
End Function
Such that on Line 20 of my code, if I wanted to add my own breakpoint, it would look like this:
Breakpoint 20, "B0001", "Some debug output here"
Output:
[!] Breakpoint hit at Line 20 in somefile.inc: Some debug output here
Happy coding!