vbscript / Classic ASP - есть ли способ получить собственное имя файла программно? - PullRequest
0 голосов
/ 16 января 2009

Я просто просматривал старый код и обнаружил следующее (внутри foo.asp):

Const ASP_FILENAME = "foo.asp"  ' TODO: Update this to the name of this file (if changed)

Переменная используется только для регистрации ошибок. (т.е. "Ошибка в foo.asp - Не удалось создать объект xxxxx.") Есть ли способ избежать этого?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 16 января 2009

Вы можете проанализировать Request.ServerVariables("url"), чтобы получить часть имени файла. Поиск Google нашел этот код , на который я не претендую на кредит, который использует серверную переменную SCRIPT_NAME, которая, кажется, действительно имеет больше смысла, также принимая любую перезапись URL в учетную запись, которая может быть на месте:

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)
2 голосов
/ 16 января 2009

Из ныне несуществующего Aspfaq.com (спасибо Archive.org ):

Как мне получить название текущего URL / страницы?

Это довольно легко, но есть две части.

Чтобы получить имя текущего файла, вы можете использовать любой из них:

<% 
    Response.Write Request.ServerVariables("SCRIPT_NAME") & "<br>" 
    Response.Write Request.ServerVariables("PATH_INFO") & "<br>" 
    Response.Write Request.ServerVariables("URL") & "<br>" 
%>

Чтобы сделать этот путь локальным (например, для использования с FileSystemObject), просто примените метод server.mappath () к результату.

Чтобы получить полный URL-адрес, включая префикс http: // или https: //, вы можете сделать это:

<% 
    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 внутри него все выполняется в контексте «parent» ' файл). Один из способов обойти это - повторно заполнить переменную current_filename перед загрузкой каждого включаемого файла, например:

<% 
      current_filename = "filetoinclude.asp" 
 %> 

<!--#include file='filetoinclude.asp'-->

(И нет, не пытайтесь передавать current_filename как переменную в директиву #INCLUDE; см. Статью # 2042.)

Затем в файле toinclude.asp:

<% 
    Response.Write "Current file: " & current_filename 
%>

Конечно, вы можете так же легко жестко закодировать имя файла внутри каждого включаемого файла. Но я полагаю, что это решение несколько ослабит цель извлечения этой информации, по крайней мере, несколько динамически.

0 голосов
/ 21 сентября 2015

Не говоря уже о том, что кто-то здесь [вставьте здесь кашель с дискретным горлом] все еще использует Classic ASP для поддержки и поддержки устаревших приложений, но недавно у меня возникла необходимость сделать что-то подобное. Отказываясь от ответов «невозможно с классическим ASP», я решил найти способ и нашел следующее решение.

Этот подход в основном использует базовые команды ОС для буквального определения текущего имени файла (результат которого эквивалентен использованию магической константы __FILE__ в PHP) независимо от того, включает ли он файл (*.inc) или сам скрипт (*.asp).

Во-первых, для поддержки некоторой дезинфекции (вы можете сделать это другим, более «оптимальным» способом, если хотите):

'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

А теперь на время «отражения»:

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

Затем внутри любого файла, который вы хотите «проверить» текущим именем файла, просто удалите следующую строку, передавая некоторый уникальный идентификатор, который не должен существовать ни в каком другом файле в текущем каталоге, кроме этого:

'myfile.inc
Response.Write "This is in " & GetCurrentFilename("908ab098c")

Результат:

This is in somefile.inc

О, и если вам интересно, для чего мне нужно это использовать, вот как это выглядит при использовании простой функции точки останова:

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

Так, чтобы в строке 20 моего кода, если бы я хотел добавить свою собственную точку останова, это выглядело бы так:

Breakpoint 20, "B0001", "Some debug output here"

Выход:

[!] Breakpoint hit at Line 20 in somefile.inc: Some debug output here

Удачного кодирования!

0 голосов
/ 16 января 2009

Я не знаю, существует ли server.mappath на традиционном asp, но если это так, вы можете использовать, если знать имя файла страницы.

...