Is there a way to work with the ResponseStream property of WinHttp.WinHttpRequest.5.1 in VBScript/ASP? At least the IStream interface (to which ResponseStream is related) is integrated into ASP to a certain degree.
Or is that the limit of what you can achieve in script? Requiring you to roll your own COM component if you want to go any further?
<html><body><h1>WinHttp</h1>
<%
Dim req, url, o
Set req = CreateObject( "WinHttp.WinHttpRequest.5.1" )
url = "http://www.google.de"
req.Open "GET", url, False
req.Send
Response.Write "<p>Hier kommt <code>" & url & "</code> :</p>"
Response.Write "<pre>"
Response.Write req.Status & " " & req.StatusText & VbNewLine
Response.Write req.GetAllResponseHeaders
Response.Write "</pre>"
' Response.Write Mid( req.ResponseText, InStr( req.ResponseText, "<div" ) )
' Set o = req.ResponseStream
' o = req.ResponseStream
' Same result for Write and BinaryWrite:
' VarType = 13, TypeName = Unknown
' ASP 0106 : 80020005; Typkonflikt; Unbehandelter Datentyp
' o = req.ResponseStream
' o = req.ResponseBody ' mit BinaryWrite
o = req.ResponseText ' mit Write
Response.Write "<p><code>IsObject " & IsObject(o) & "</code></p>"
Response.Write "<p><code>IsNull " & IsNull(o) & "</code></p>"
Response.Write "<p><code>VarType " & VarType(o)
Response.Write " " & TypeName(o) & "</code></p>"
Response.Write o
' Response.BinaryWrite o
%>
Note that I know I can use either req.ResponseText or req.ResponseBody. The interest is in knowing whether you can go further in script using stuff that's only documented for C but maybe (speculating) accessible to script. I'm not knowledgeable about COM.
There is nothing you can do with an IStream directly in script code. All you could do is pass it to a COM object that might use it.
The IStream is very alien to Vbscript even in VB6 one has to jump through some fiery hoops to work with it.
Related
Below is the SQL query I have in my vbscript file.
with temp as (
select distinct user_id,
user_email_addr,
proj_nm
from test_table1
where user_enabled_ind='Y'
and user_extrl <> 'Y'
and datediff(dd,user_ts,getdate()) between 83 and 90
and proj_src_nm <>'testproject1'
and user_id <>'testproject2'
) SELECT Name=p1.user_id,
Address=p1.user_email_addr,
(SELECT proj_nm + ', '
FROM temp p2
WHERE p2.user_id = p1.user_id
ORDER BY proj_nm FOR XML PATH('')) AS Project
FROM temp p1
GROUP BY user_id,user_email_addr;
When I run this query, I get result something like this:
Name Address Project
abc1 abc1#xyz.com Apple,Mango
abc2 abc2#xyz.com Apple,Banana,Mango
abc3 abc3#xyz.com Mango
As per my vbscript, it is supposed to send email with project in the email body. But, the email alert is breaking where I put the project field.
Please help.
VbScript:
option explicit
const connstr = "DSN=DSN_APP"
dim connexion, recordset, record
dim sqltxt
sqltxt = "with temp as (select distinct user_id,user_email_addr,proj_nm from test_table1 where user_enabled_ind='Y' and user_extrl <> 'Y'and datediff(dd,user_ts,getdate()) between 83 and 90 and proj_src_nm <>'testproject1' and user_id <>'testproject2') SELECT Name=p1.user_id,Address=p1.user_email_addr, (SELECT proj_nm + ', ' FROM temp p2 WHERE p2.user_id = p1.user_id ORDER BY proj_nm FOR XML PATH('')) AS Project FROM temp p1 GROUP BY user_id,user_email_addr;"
set connexion = CreateObject("ADODB.Connection")
set recordset = CreateObject("ADODB.Recordset")
connexion.Open connstr
recordset.Open sqltxt, connexion
if recordset.Eof then
wscript.Echo "The result is empty."
else
do until recordset.Eof
if not IsNull(recordset("address")) then
SendMail recordset("name"), recordset("address"), recordset("project")
end if
recordset.MoveNext
loop
end if
recordset.Close
connexion.Close
function SendMail(TheName, TheAddress, TheProjectList)
dim strTable1, strTable2, strTable3, strTable4
dim objMessage
rem override TheAddress for testing purpose
rem TheAddress = "abc#xyz.com"
set objMessage = CreateObject("CDO.Message")
strTable1 = "<TABLE border=0 width=900><TR><TD align=center bgcolor=#ffab00 nowrap><FONT color='white'><B>~Application Inactive User Account Notification~</B></FONT></TD></TR></TABLE>"
strTable1 = strTable1 & "<DIV style=text-align: center;><B><BR>" & FormatDateTime(Date(),1) & "</DIV><BR><BR></B>"
strTable2 = "<TABLE border=0 width=800><TR><TD align=left borderColor=white>Dear Application user " & "<B>(NT ID: "& TheName & ")," & "</B></TD></TR></TABLE>"
strTable2 = strTable2 & "<br/>"
strTable3 = <TABLE border=0 width=800><TR><TD align=left borderColor=white>This is a notification alert to inform you that you will result in deactivation of your id after 5 days. Please login to the following projects:- " & "<B>(" & TheProjectList & ")</B>" & " to become 'Active' again and prevent being disabled." & "</TD></TR></TABLE>"
strTable3 = strTable3 & "<br/>"
strTable4 = "<TABLE border=0 width=800><TR><TD align=left borderColor=white><B>Thank You," & "</B></TD></TR></TABLE>"
strTable4 = strTable4 & "<TABLE border=0 width=800><TR><TD align=left borderColor=white><B>IIS Team" & "</B></TD></TR></TABLE>"
objMessage.Subject = "Application Inactive User Account Notification"
objMessage.From = "IPC Services <informationservices#xyz.com>"
objMessage.To = "abc#xyz"
rem put your address for testing purpose
rem objMessage.CC = "abc#xyz.com"
rem objMessage.CC = "test#xyz.com"
objMessage.TextBody = "***************THIS IS AN AUTO GENERATED MESSAGE. PLEASE DO NOT REPLY.***************" & vbCrLf & vbCrLf
objMessage.HTMLBody = strTable1 & vbCrLf & vbCrLf & strTable2 & vbCrLf & vbCrLf & strTable3 & vbCrLf & vbCrLf & strTable4
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
'Name or IP of Remote SMTP Server
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "internet1.xyz.com"
'Server port (typically 25)
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
objMessage.Configuration.Fields.Update
objMessage.Send
set objMessage = Nothing
rem test run output
rem wscript.Echo "TheName=" & TheName & " TheAddress=" & TheAddress
end function
The above VB script generates an email alert, which breaks at the place where project is called. And the text next to project does not appear in the email alert. Please help.
This is because in newer versions of VBscript, 'XML PATH' might not support.
So please check the server and version of VBScript compatibility.
In order to achieve this extract name and email through one query and extract project name with another variable to store comma separated project names.
I'm attempting to write a WebPart for SharePoint that will display a list of the most recent uploads and modifications to the Site (including all Document Lists)
To that end I have created an SPGridView and I am using an SPSiteDataQuery to populate that with my (customisable) selected Lists. I'm aware that SPQuery has the ListItemCollectionPosition, but as far as I know this will not work for multiple lists, and doing one at a time ruins sorting/paging.
This is a snippet of what I have:
Dim query As New SPQuery()
Dim lists As String = "<Lists ServerTemplate='101'>"
For Each li As Guid In SelectedLists ' Personalisable Property
lists &= "<List ID='" & li.ToString & "' />"
Next
lists &= "</Lists>"
query.Lists = lists
query.RowLimit = 30 ' This will be the page size and is temporarily hardcoded
' These Id's are all SPBuildInFieldId's converted ToString
query.ViewFields = "<FieldRef ID'" & _filenameId & "' />" &
"<FieldRef ID='" & _modifiedId & "' />" &
"<FieldRef ID='" & _modifiedById & "' />" &
"<FieldRef ID='" & _versionId & "' />" &
"<FieldRef ID='" & _checkedOutToId & "' />" &
"<FieldRef ID='" & _fileSizeId & "' />" &
"<FieldRef ID='" & _createdId & "' />" &
"<FieldRef ID='" & _createdById & "' />"
query.Webs = "<Webs Scope='Recursive' />"
query.Query = "<OrderBy><FieldRef ID='" & _modifiedId & "' Ascending='FALSE' /></OrderBy>"
Dim temp as DataTable = objWeb.GetSiteData(query)
For Each row As DataRow In temp.Rows
Dim aRow = dtTable.Rows.Add()
' Get List Information
Dim listId As Guid = New Guid(row.Item("ListId").ToString)
Dim thisList As SPList = objWeb.Lists(listId)
Dim fileName As String = row.Item(_filenameId).ToString
aRow.Item("DocIcon") = "/_layouts/15/images/" & Utilities.SPUtility.MapToIcon(objWeb, fileName, "")
aRow.Item("FileName") = fileName
aRow.Item("FileLink") = objWeb.Url & "/" & thisList.Title & "/" & fileName
aRow.Item("ListName") = thisList.Title
aRow.Item("ListLink") = objWeb.Url & "/" & thisList.Title
aRow.Item("Modified") = row.Item(_modifiedId).ToString
aRow.Item("ModifiedBy") = New SPFieldLookupValue(row.Item(_modifiedById).ToString).LookupValue
aRow.Item("Version") = row.Item(_versionId).ToString
aRow.Item("CheckedOutTo") = New SPFieldLookupValue(row.Item(_checkedOutId).ToString).LookupValue
aRow.Item("FileSize") = row.Item(_fileSizeId).ToString
aRow.Item("Created") = row.Item(_createdId).ToString
aRow.Item("Author") = New SPFieldLookupValue(row.Item(_createdById).ToString).LookupValue
Next
This DataTable is set to the source of my SPGridView, and that allows paging (I am currently using an SPGridViewPager), but it will always return the full collection of documents from the query, which is going to cause some overhead once there are a lot of documents.
What I'd like is to be able to paginate in the query itself so that it only returns correct documents for the current page (~30 at a time), but I'm hitting a wall trying to achieve this.
Is there a solution I'm missing that will allow me to both query a predetermined set of lists in modified order, and also paginate at query time?
Thanks in advance and apologies for any bad wording/formatting, this is my first question on this site.
There is a workaround for this case, while it may not 'best choice' if you have huge data volume.
"Imagine If we want to display 25 records in a page & the user wants to navigate to page no 2.
uint recordsPerPage = 25;
uint pageNumber = 2;
So the rowLimit property of our query should be 25 * 2 = 50."
https://nivas07.wordpress.com/2010/06/15/paging-using-spsitedataquery/
Ok, I am new to the forum and fairly new to coding, I've searched high and low, and I understand that vbscript requires escapes or Chr() to use special characters. In the following code I need to concatenate a '%' after the "doc_no" as a wildcard for a sybase database to pull up the list of document numbers that I need to appear in my table.
I have tried
' " & doc_no " ' & Chr(37) " 'this returned that "&" is an invalid character
' " & doc_no " ' || Chr(37) "
' " & doc_no " ' + ""%"" " returned + as an invalid character
I have tried several variations of each type, and I cannot find any similar situation online. Any advice? Again, I am only 4 months into my programming life so bear with me please. Below is a snippet of the code from which the above originates.
<%
Dim document(1024)
counter = 0
cmdString = ""
cmdString = cmdString & "SELECT dbo.dsk_obj.obj_id,"
cmdString = cmdString & " docno = dbo.dsk_obj.obj_usr_num "
cmdString = cmdString & "FROM dbo.dsk_obj "
cmdString = cmdString & "WHERE dbo.dsk_obj.obj_usr_num LIKE '" & doc_no & "' I NEED TO CONCAT. % HERE "
objRS.Open cmdString, objConn, adOpenStatic, 3, adCmdText
WHILE (objRS.EOF = False)
document(counter) = objRS("docno")
counter = counter + 1
objRS.MoveNext
WEND
objRS.Close
%>
<% FOR ii = 0 TO counter -1 %>
<%=document(ii)%>
<%
NEXT
%>
the output should look something like this
1555307375-0001
1555307375-0002
1555307375-0003
Any help would be greatly appreciated! Thanks! Jeremy
First, you should avoid string concatenation because of SQL injection.
Now what you are trying to do is to create a SQL string in VBScript. The SQL you desire looks something like:
LIKE '123%'
To create this, you need a string in VBScript like:
Dim string = "LIKE '123%'"
To change out 123 for your doc number, you can do:
Dim string = "LIKE '" & doc_no & "123%'"
In your case, it would be:
cmdString = cmdString & "WHERE dbo.dsk_obj.obj_usr_num LIKE '" & doc_no & "%'"
But please don't do this. You should pass the parameter in instead of using string concatenation.
VB.NET 2.0:
I'm issuing a backup command to a SQL server from a VB.NET application. I'm capturing the messages it sends out and appending them to a multiline textbox.
What I'm trying to do, though, is to allow the application to keep responding to GUI control events (mainly so that the user can resize the output window or cancel the backup). So I use BeginExecuteReader and spin in a loop with Application.DoEvents(). But it seems that as soon as the backup starts issuing its print statements, I get IAsyncResult.IsCompleted = True and it drops down to EndExecuteReader, and the GUI is now locked up again. How can I get it to stay in the loop until the backup command completes and yet still get those output statements and keep the GUI responsive? Thanks.
Here's my code:
' Enable retrieve print statements from the server'
AddHandler oConn.InfoMessage, AddressOf LogToBufferHandler
strSQL &= vbNewLine & "begin try"
strSQL &= vbNewLine & " declare #BackupName as varchar(255)"
strSQL &= vbNewLine & " declare #BackupDesc as varchar(255)"
strSQL &= vbNewLine & " declare #backupTime as varchar(50)"
strSQL &= vbNewLine & " set #backupTime = (select convert(datetime, getdate(), 100))"
strSQL &= vbNewLine & " set #BackupName = (SELECT '[' + db_name() + '] Full Backup')"
strSQL &= vbNewLine & " set #BackupDesc = (SELECT 'Automated full backup of [' + db_name() + '] on ' + #backupTime + '.')"
strSQL &= vbNewLine & " "
strSQL &= vbNewLine & " BACKUP DATABASE [#Database#]"
strSQL &= vbNewLine & " TO DISK = #BackupFullPath"
strSQL &= vbNewLine & " WITH stats,"
strSQL &= vbNewLine & " NAME = #BackupName,"
strSQL &= vbNewLine & " DESCRIPTION = #BackupDesc;"
strSQL &= vbNewLine & " select [IsSuccessful] = 1"
strSQL &= vbNewLine & " end try"
strSQL &= vbNewLine & " begin catch"
strSQL &= vbNewLine & " SELECT [IsSuccessful] = 0"
strSQL &= vbNewLine & " end catch"
'Workaround: Backup Database requires the name of the object, not a string'
' and I dont want to use dynamic SQL.'
strSQL = strSQL.Replace("#Database#", sb.InitialCatalog)
oConn.Open()
oCmd = New SqlCommand()
oCmd.Connection = oConn
oCmd.CommandText = strSQL
oCmd.CommandType = CommandType.Text
oCmd.Parameters.AddWithValue("#BackupFullPath", backupFullPath)
oCmd.CommandTimeout = 60 * 5
'Spin until complete, cancel, or timeout'
Dim result As IAsyncResult = oCmd.BeginExecuteReader(CommandBehavior.CloseConnection)
While Not result.IsCompleted
Application.DoEvents()
If blnCancel Then
oCmd.Cancel()
End If
System.Threading.Thread.Sleep(50)
End While
Try
oDataReader = oCmd.EndExecuteReader(result)
oDataTable.Load(oDataReader)
'Get results'
' (unfourtunately, you cannot do BeginExecuteScalar ASync in .Net 2.0,'
' so we are using a DataTable first column, row)'
If oDataTable IsNot Nothing _
AndAlso oDataTable.Rows.Count > 0 _
AndAlso oDataTable.Columns.Contains("IsSuccessful") _
AndAlso oDataTable.Rows(0).Item("IsSuccessful") = 1 Then
eBackupResult = BackupStatus.Succeeded
returnPath = backupFullPath 'Only set return path if the backup succeeded'
Else
eBackupResult = BackupStatus.Failed
End If
Catch ex As Exception
If Not ex.Message.Contains("cancelled by user") Then Throw ex
eBackupResult = BackupStatus.Canceled
End Try
Polling loops (DoEvents) are considered evil for many reasons. It is probably the easiest way for you to switch to BackgroundWorker and abandon the nasty Begin-poll-End scheme.
If you want to keep it, here is the bug: Accepting the reader can be quick but that doesn't mean that all results have arrived (let me illustrate: what if you had queried 1TB of data? - reading that is a long process). You need to Read in an async (polling) way too. Now the thing gets out of hand. Just abandon it.
In other words, oDataTable.Load is blocking which is hard to fix.
You can use TASKS for this. A task is similar in concept to a thread. By putting your code into a task the main thread can continue to run (which is the thread that takes user input and responds to resize commands).
Here's an article that talks more about tasks and has a VB.NET example.
http://www.dotnetcurry.com/ShowArticle.aspx?ID=491
Have fun!
BackGroundWorker and ReportProgress
BackgroundWorker Class
In my application I have created I need it to write a visual basic script to change the ip address
The script is as follows...
Dim strIPAddress
Dim strSubnetMask
Dim strGateway
Dim intGatewayMetric
Dim strDns1
Dim strDns2
strIPAddress = "192.168.1.211"
strSubnetMask = "255.255.255.0"
strGateway = "192.168.0.11"
intGatewayMetric = 1
strDns1 = "8.8.8.8"
strDns2 = "4.4.4.4"
Set objShell = WScript.CreateObject("Wscript.Shell")
objShell.Run "netsh interface ip set address name=""Local Area Connection"" static " & strIPAddress & " " & strSubnetMask & " " & strGateway & " " & intGatewayMetric, 0, True
objShell.Run "netsh interface ip set dns name=""Local Area Connection"" static "& strDns1, 0, True
objShell.Run "netsh interface ip add dns name=""Local Area Connection"" addr="& strDns2, 0, True
Set objShell = Nothing
WScript.Quit
The way I am trying to write this is like the following..
Directory.CreateDirectory("C:\SpecMee\IPChanger\")
Dim objwriter As New System.IO.StreamWriter("C:\SpecMee\IPChanger\IpChanger.vbs")
objwriter.WriteLine("Dim strIPAddress" & Environment.NewLine & "Dim strSubnetMask" & Environment.NewLine & "Dim strGateWay" & Environment.NewLine & "Dim intGatewayMetric" & Environment.NewLine & "Dim strDns1" & Environment.NewLine & "Dim strDns2" & Environment.NewLine & "strIPAddress = """ & Environment.NewLine & TB_IPAddress & Environment.NewLine &)
objwriter.Close()
MessageBox.Show("Created")
The problem I am having is one, it is taking ages and two, how would i include the "" in the script.
I dont mind spending time on this, I just dont know if im going about this the right way.
any help would be appreciated.
Thanks
Chris
Add the script as a text file resource to your project. Replace all instances of the IP Address in the script with some known value, then use string.replace:
Const ipPlaceHolder As String = "##IP##"
Dim scriptContent As String = My.Resources.script.Replace(ipPlaceHolder, myTextBox.Text)
IO.File.WriteAllText("C:\SpecMee\IPChanger\IpChanger.vbs", scriptContent)
Where myTextBox contains user input and the text file resource is named "Script"
Two quotation marks in a row makes one in the output.
"And he said ""Thar she blows!"""
( You have two questions in one. That is not considered good customs on Stackoverflow. )