Closing a window after response.binarywrite

M

Max Dupenois

I've seen numerous articles with similair (similar sp?) titles to this
in my search.. unfortunately none of them seem to contain what i want,
(or if they do i need someone to point out my stupidity for me :p )

Anyway I have a file dialog box being opened using

Response.AddHeader "Content-Disposition", "attachment;filename=""" &
displayName & """"

Response.ContentType = "application/binary"

Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = adTypeBinary
objStream.LoadFromFile strFilePath
Response.BinaryWrite objStream.Read
objStream.Close

And am left with a blank rather pointless window from the ASP that used
the above code. I would like to find a way to close the window after
the file has been downloaded/canceled/opened. I have tried
response.flush and rewriting the headers to text/html after the
obStream.close so i could have an onload function to close the window..
but no luck.. i've tried having the above code run in a frame with a
second frame opened afterward to close the window but still no luck. I
also tried something similair with inline frames. I don't want to
resort to a timer in a seperate frame as the file, which is an rtf file
generated from a passed in set of sql queries, can occasionally be
quite large and take some time to download (let alone the fact it has
to be created first). This would make the timer highly inefficient as i
have no idea how long or how short an amount of time would be
required...

Cheers for any help provided

Max

P.s This my first time in a newsgroup and if i have posted this in the
wrong place or have been unclear i apologise.
 
P

Patrice

Instead just don't open a new window. The browser knows that this is not an
HTML document and will left the current window unchanged.
(for example a a tag with no target attribute is enough).
 
M

MaxD

Thanks for the reply but unfortunately due to the nature of the web
application i have to add the code too this isn't possible.. it gets
very complicated but the the asp calls a vb dll to create the report
(based on passed parameters) on the fly, saves it too a temporary
folder, opens the save dialog box then (once the user is done with it)
deletes the file.. and just because my life isn't comlicated enough the
link used to set this up is also created on the fly based on the
existance of an asp in the current directory. The full ASP code looks a
little like this.

The page to first redirect (used to create the link in the
application):

<%@ Language=VBScript %>
<% if 1=0 then%>
<!--
[WIZARD OPTIONS]
Caption=Event Sheet^|0|^
ToolTip=Event Sheet^|0|^
NewWindow=YES
WindowProperties=HEIGHT=500,WIDTH=500

Target=ArrangementDocs
[END WIZARD OPTIONS]
[START CONDITIONS]
function testConditions(newIndex)
testconditions = true
end function
[END CONDITIONS]
--><%
end if%>


<%
Response.Redirect
"ReportLauncher/ReportLauncher.Asp?ReportName=BC%20Function%20Sheet&Parameters=@@ArrNo%3D"
& request("ArrangementNumber") & "%3b@@UserName%3D%27Andy
Wheeler%27%3b@@JobTitle%3D%3b"

%>

Which calls the launcher:
<%
Dim ReportPath
Dim TemplatePath
Dim ClientServer

Dim ReportParameters
Dim mainPath
Dim ADOConnection
Dim pathToReport
pathToReport = "C:\Temp\"

'Sets The Paths for the report
ReportName = Request.QueryString("ReportName")
ParameterString = Request.QueryString("Parameters")

ReportPath = pathToReport & ReportName & ".ars"
TemplatePath = pathToReport & ReportName & ".rtf"

ClientServer = "#Missing#"


ADOConnection = Security.ConnString

ReportPath = encode(ReportPath)
TemplatePath = encode(TemplatePath)
ClientServer = encode(ClientServer)
ParameterString = encode(ParameterString)
ADOConnection = encode(ADOConnection)




'Response.Redirect "RunReport.asp?ReportPath=" & ReportPath &
"&TemplatePath=" & TemplatePath & "&ClientServer=" & ClientServer &
"&ParameterString=" & ParameterString & "&ADOConnection=" &
ADOConnection & "&Run=True"


Function encode(toEncode)
Dim tempString
tempString = Replace(toEncode, "=", "%3D")
tempString = Replace(toEncode, """", "%22")
tempString = Replace(tempString, "'", "%27")
tempString = Replace(tempString, ";", "%3b")
tempString = Replace(tempString, " ", "%20")
tempString = Replace(tempString, "\", "%5c")
tempString = Replace(tempString, ":", "%3a")
tempString = Replace(tempString, "#", "%23")
tempString = Replace(tempString, ".", "%2e")
encode = tempString
End Function
%>

Which then finally calls the run report page:

<%

Response.Buffer = True

Dim ReportPath
Dim TemplatePath
Dim ClientServer
Dim ParameterString
Dim ADOConnection
Dim Run

ReportPath = Request.QueryString("ReportPath")
TemplatePath = Request.QueryString("TemplatePath")
ClientServer = Request.QueryString("ClientServer")
ParameterString = Request.QueryString("ParameterString")
ADOConnection = Request.QueryString("ADOConnection")
Run = Request.QueryString("Run")


If Run = "True" Then

RunReport ReportPath, TemplatePath, ClientServer, ParameterString,
ADOConnection


End If

Dim rpt
Sub RunReport(ReportPath, TemplatePath, ClientServer, ReportParameters,
ADOConnection)

Dim SaveFilePath
Dim LogPath
Dim randomNumber
Dim mainPath

'Base Path to store temp files
mainPath = "C:\Temp\"

'For use in temporary file names
Rnd -1
Randomize Timer
randomNumber = Rnd()
randomNumber = CStr(randomNumber)
randomNumber = Replace(RandomNumber, ".", "")

'The path to Save the file too
SaveFilePath = mainPath & "Report" & randomNumber & ".rtf"

'The path to log errors too
LogPath = mainPath & "events" & randomNumber & ".log"


'Make sure the object doesn't exist already
If rpt Then
Set rpt = Nothing
End If
'Create the report object
Set rpt = Server.CreateObject("ReportEngine.Report")

'Assign the various required report attributes
rpt.OpenReport ReportPath, True, LogPath
rpt.TemplateName = TemplatePath
rpt.Action = "Save"
rpt.UserInterface = False
rpt.ClientServerProperty = ClientServer
rpt.SaveFileNameProperty = SaveFilePath
rpt.ADOConnection = ADOConnection

Dim dummy
Dim ParaName
Dim ParaValue

Set rpt.RptParameters =
Server.CreateObject("ReportEngine.RptParameters")
Do
dummy = StripValue(ReportParameters, "@@")
ParaName = StripValue(ReportParameters, "=")
ParaValue = StripValue(ReportParameters, ";")
'assume all external parameters are strings
If ParaName <> "" Then rpt.RptParameters.Add ParaName,
ParaValue, 200 , "" 'ADODB.adVarChar =200
Loop Until ReportParameters = ""

'Run the report
rpt.Run

SaveReport SaveFilePath, LogPath

Set rpt = Nothing



End Sub


Sub SaveReport (SaveFilePath, LogPath)


'Checking for files existence
Dim FileSysObj
Set FileSysObj = Server.CreateObject("Scripting.FileSystemObject")

Dim eventLogExists
Dim reportExists

reportExists = FileSysObj.FileExists(SaveFilePath)
eventLogExists = FileSysObj.FileExists(LogPath)

Dim FileName
Dim displayName
Dim strFilePath
Const adTypeBinary = 1

If reportExists Or eventLogExists then

If (reportExists And (Not eventLogExists)) then
FileName = mid(SaveFilePath,instrrev(SaveFilePath,"\")+1)
strFilePath = SaveFilePath 'This is the path to the file on disk.
displayName = rpt.name & ".rtf"
'response.write strFilePath
'response.end
ElseIf ((Not reportExists) And eventLogExists) then

FileName = mid(LogPath,instrrev(LogPath,"\")+1)
strFilePath = LogPath 'This is the path to the file on disk.
displayName = rpt.name & " Events.log"

ElseIf (reportExists And eventLogExists) then

FileName = mid(SaveFilePath,instrrev(SaveFilePath,"\")+1)
strFilePath = SaveFilePath 'This is the path to the file on disk.
displayName = rpt.name & ".rtf"

End If



'Open the save file dialog
Response.AddHeader "Content-Disposition", "attachment;filename=""" &
displayName & """"

Response.ContentType = "application/binary" ' For some reason this
works for all extensions I've come across

Set objStream = Server.CreateObject("ADODB.Stream") 'ADO can do the
clever bit for you
objStream.Open
objStream.Type = adTypeBinary
objStream.LoadFromFile strFilePath
Response.BinaryWrite objStream.Read
objStream.Close

'Delete the temporary files
If reportExists then
FileSysObj.DeleteFile SaveFilePath
End If

If eventLogExists then
FileSysObj.DeleteFile LogPath
End If

Set objStream = Nothing


'Response.Close


End If
End Sub

Public Function StripValue(DataString, Separator)
Dim sSpace
Dim bInQuotes
Dim sChar
Dim iQuoteCount()
Dim iQuoteType
Dim iQuoteIndex
Dim iCount
Dim iCounter
Dim NoTrim
Dim QuoteString

QuoteString = "''"

ReDim iQuoteCount(Len(QuoteString) / 2)
bInQuotes = False
sSpace = 0
Do
sSpace = sSpace + 1
sChar = Mid(DataString, sSpace, Len(Separator))
iCount = InStr(1, QuoteString, sChar)
If iCount > 0 Then
iQuoteType = ((2 * ((iCount) Mod 2)) - 1) '1 is open, -1 is
close
iQuoteIndex = ((iCount + 1) \ 2)
If iQuoteType = 1 And Mid(QuoteString, iCount + 1, 1) =
sChar Then
'if open quote is same as close quote then
iQuoteCount(iQuoteIndex) = 1 - iQuoteCount(iQuoteIndex)
Else
iQuoteCount(iQuoteIndex) = iQuoteCount(iQuoteIndex) +
iQuoteType
End If

bInQuotes = False
For iCounter = 1 To UBound(iQuoteCount)
If iQuoteCount(iCounter) > 0 Then bInQuotes = True
Next
End If
Loop Until (sChar = Separator And Not bInQuotes) Or sSpace >
Len(DataString)

StripValue = Trim(CStr(Left(DataString, sSpace - 1)))
DataString = Trim(CStr(Mid(DataString, sSpace + Len(Separator))))

End Function
%>

Basically i'm being asked to force a program that wasn't designed to
work in web applications into a web application.. it all works now
apart from closing the window.. which seems to insignificant but is
driving me insane because it makes it look very messy!

Max

P.s. i've tried rewriting this a few times, and it still reads badly so
it's my fault if you can't understand what i'm trying to get across.
 
P

Patrice

Do you have existing reports rendered by this application ? You could then
see how then dealt with this issue.

From what I saw, it could be needed because of response.redirect.

You could likely either :
- call the reportlauncher directly
- or use server.transfer so that nothing at all is passed back to the
browser
- or make available the Reporting function so that it can be called directly
by your page
(I don't really see what does the first page, looks like it only redirect ?)

The only thing you can't do is to render HTML while rendering the report
output so that the current window is left unchanged.

Here you'll have to fight against two issues :
- you can't output some script that would close the current window as you
are precisely streaming a non HTML document
- even doing this using an IFRAME or something similar, you'll have perhaps
then some difficulties to know when to close the window.

Sorry for the poor help.
--
Patrice

MaxD said:
Thanks for the reply but unfortunately due to the nature of the web
application i have to add the code too this isn't possible.. it gets
very complicated but the the asp calls a vb dll to create the report
(based on passed parameters) on the fly, saves it too a temporary
folder, opens the save dialog box then (once the user is done with it)
deletes the file.. and just because my life isn't comlicated enough the
link used to set this up is also created on the fly based on the
existance of an asp in the current directory. The full ASP code looks a
little like this.

The page to first redirect (used to create the link in the
application):

<%@ Language=VBScript %>
<% if 1=0 then%>
<!--
[WIZARD OPTIONS]
Caption=Event Sheet^|0|^
ToolTip=Event Sheet^|0|^
NewWindow=YES
WindowProperties=HEIGHT=500,WIDTH=500

Target=ArrangementDocs
[END WIZARD OPTIONS]
[START CONDITIONS]
function testConditions(newIndex)
testconditions = true
end function
[END CONDITIONS]
--><%
end if%>


<%
Response.Redirect
"ReportLauncher/ReportLauncher.Asp?ReportName=BC%20Function%20Sheet&Paramete
rs=@@ArrNo%3D"
& request("ArrangementNumber") & "%3b@@UserName%3D%27Andy
Wheeler%27%3b@@JobTitle%3D%3b"

%>

Which calls the launcher:
<%
Dim ReportPath
Dim TemplatePath
Dim ClientServer

Dim ReportParameters
Dim mainPath
Dim ADOConnection
Dim pathToReport
pathToReport = "C:\Temp\"

'Sets The Paths for the report
ReportName = Request.QueryString("ReportName")
ParameterString = Request.QueryString("Parameters")

ReportPath = pathToReport & ReportName & ".ars"
TemplatePath = pathToReport & ReportName & ".rtf"

ClientServer = "#Missing#"


ADOConnection = Security.ConnString

ReportPath = encode(ReportPath)
TemplatePath = encode(TemplatePath)
ClientServer = encode(ClientServer)
ParameterString = encode(ParameterString)
ADOConnection = encode(ADOConnection)




'Response.Redirect "RunReport.asp?ReportPath=" & ReportPath &
"&TemplatePath=" & TemplatePath & "&ClientServer=" & ClientServer &
"&ParameterString=" & ParameterString & "&ADOConnection=" &
ADOConnection & "&Run=True"


Function encode(toEncode)
Dim tempString
tempString = Replace(toEncode, "=", "%3D")
tempString = Replace(toEncode, """", "%22")
tempString = Replace(tempString, "'", "%27")
tempString = Replace(tempString, ";", "%3b")
tempString = Replace(tempString, " ", "%20")
tempString = Replace(tempString, "\", "%5c")
tempString = Replace(tempString, ":", "%3a")
tempString = Replace(tempString, "#", "%23")
tempString = Replace(tempString, ".", "%2e")
encode = tempString
End Function
%>

Which then finally calls the run report page:

<%

Response.Buffer = True

Dim ReportPath
Dim TemplatePath
Dim ClientServer
Dim ParameterString
Dim ADOConnection
Dim Run

ReportPath = Request.QueryString("ReportPath")
TemplatePath = Request.QueryString("TemplatePath")
ClientServer = Request.QueryString("ClientServer")
ParameterString = Request.QueryString("ParameterString")
ADOConnection = Request.QueryString("ADOConnection")
Run = Request.QueryString("Run")


If Run = "True" Then

RunReport ReportPath, TemplatePath, ClientServer, ParameterString,
ADOConnection


End If

Dim rpt
Sub RunReport(ReportPath, TemplatePath, ClientServer, ReportParameters,
ADOConnection)

Dim SaveFilePath
Dim LogPath
Dim randomNumber
Dim mainPath

'Base Path to store temp files
mainPath = "C:\Temp\"

'For use in temporary file names
Rnd -1
Randomize Timer
randomNumber = Rnd()
randomNumber = CStr(randomNumber)
randomNumber = Replace(RandomNumber, ".", "")

'The path to Save the file too
SaveFilePath = mainPath & "Report" & randomNumber & ".rtf"

'The path to log errors too
LogPath = mainPath & "events" & randomNumber & ".log"


'Make sure the object doesn't exist already
If rpt Then
Set rpt = Nothing
End If
'Create the report object
Set rpt = Server.CreateObject("ReportEngine.Report")

'Assign the various required report attributes
rpt.OpenReport ReportPath, True, LogPath
rpt.TemplateName = TemplatePath
rpt.Action = "Save"
rpt.UserInterface = False
rpt.ClientServerProperty = ClientServer
rpt.SaveFileNameProperty = SaveFilePath
rpt.ADOConnection = ADOConnection

Dim dummy
Dim ParaName
Dim ParaValue

Set rpt.RptParameters =
Server.CreateObject("ReportEngine.RptParameters")
Do
dummy = StripValue(ReportParameters, "@@")
ParaName = StripValue(ReportParameters, "=")
ParaValue = StripValue(ReportParameters, ";")
'assume all external parameters are strings
If ParaName <> "" Then rpt.RptParameters.Add ParaName,
ParaValue, 200 , "" 'ADODB.adVarChar =200
Loop Until ReportParameters = ""

'Run the report
rpt.Run

SaveReport SaveFilePath, LogPath

Set rpt = Nothing



End Sub


Sub SaveReport (SaveFilePath, LogPath)


'Checking for files existence
Dim FileSysObj
Set FileSysObj = Server.CreateObject("Scripting.FileSystemObject")

Dim eventLogExists
Dim reportExists

reportExists = FileSysObj.FileExists(SaveFilePath)
eventLogExists = FileSysObj.FileExists(LogPath)

Dim FileName
Dim displayName
Dim strFilePath
Const adTypeBinary = 1

If reportExists Or eventLogExists then

If (reportExists And (Not eventLogExists)) then
FileName = mid(SaveFilePath,instrrev(SaveFilePath,"\")+1)
strFilePath = SaveFilePath 'This is the path to the file on disk.
displayName = rpt.name & ".rtf"
'response.write strFilePath
'response.end
ElseIf ((Not reportExists) And eventLogExists) then

FileName = mid(LogPath,instrrev(LogPath,"\")+1)
strFilePath = LogPath 'This is the path to the file on disk.
displayName = rpt.name & " Events.log"

ElseIf (reportExists And eventLogExists) then

FileName = mid(SaveFilePath,instrrev(SaveFilePath,"\")+1)
strFilePath = SaveFilePath 'This is the path to the file on disk.
displayName = rpt.name & ".rtf"

End If



'Open the save file dialog
Response.AddHeader "Content-Disposition", "attachment;filename=""" &
displayName & """"

Response.ContentType = "application/binary" ' For some reason this
works for all extensions I've come across

Set objStream = Server.CreateObject("ADODB.Stream") 'ADO can do the
clever bit for you
objStream.Open
objStream.Type = adTypeBinary
objStream.LoadFromFile strFilePath
Response.BinaryWrite objStream.Read
objStream.Close

'Delete the temporary files
If reportExists then
FileSysObj.DeleteFile SaveFilePath
End If

If eventLogExists then
FileSysObj.DeleteFile LogPath
End If

Set objStream = Nothing


'Response.Close


End If
End Sub

Public Function StripValue(DataString, Separator)
Dim sSpace
Dim bInQuotes
Dim sChar
Dim iQuoteCount()
Dim iQuoteType
Dim iQuoteIndex
Dim iCount
Dim iCounter
Dim NoTrim
Dim QuoteString

QuoteString = "''"

ReDim iQuoteCount(Len(QuoteString) / 2)
bInQuotes = False
sSpace = 0
Do
sSpace = sSpace + 1
sChar = Mid(DataString, sSpace, Len(Separator))
iCount = InStr(1, QuoteString, sChar)
If iCount > 0 Then
iQuoteType = ((2 * ((iCount) Mod 2)) - 1) '1 is open, -1 is
close
iQuoteIndex = ((iCount + 1) \ 2)
If iQuoteType = 1 And Mid(QuoteString, iCount + 1, 1) =
sChar Then
'if open quote is same as close quote then
iQuoteCount(iQuoteIndex) = 1 - iQuoteCount(iQuoteIndex)
Else
iQuoteCount(iQuoteIndex) = iQuoteCount(iQuoteIndex) +
iQuoteType
End If

bInQuotes = False
For iCounter = 1 To UBound(iQuoteCount)
If iQuoteCount(iCounter) > 0 Then bInQuotes = True
Next
End If
Loop Until (sChar = Separator And Not bInQuotes) Or sSpace >
Len(DataString)

StripValue = Trim(CStr(Left(DataString, sSpace - 1)))
DataString = Trim(CStr(Mid(DataString, sSpace + Len(Separator))))

End Function
%>

Basically i'm being asked to force a program that wasn't designed to
work in web applications into a web application.. it all works now
apart from closing the window.. which seems to insignificant but is
driving me insane because it makes it look very messy!

Max

P.s. i've tried rewriting this a few times, and it still reads badly so
it's my fault if you can't understand what i'm trying to get across.
 
M

MaxD

The first page is needed because of the comment block at the top, it's
essentially used by a previous page to render a button and thereby
create a link to itself.. i didn't write it and it seems a little
overcomplicated to me but it's the way the application has been set
up... I'll look into the server.transfer bit and see what happens.

Cheers for the help

Max
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top