Showing posts with label ASP. Show all posts
Showing posts with label ASP. Show all posts

July 19, 2007

Microsoft Message Queue from Classical ASP

After days and days of doing absolutely nothing, I needed something to reaffirm my skills. Here it is - a task assigned to a couple of junior programmers. They weren't able to complete. Their supervisors weren't able to help them. Enter technosock! I took on the challenge and succeeded. Yay! The problem: We have a long running ASP transaction. We want to use MSMQ to store the event and do the processing later. Task: Use ASP to store the event.

Setup

MSMQ needs to be installed on a domain controller. I think so. So create a Windows 2003 server, and a new domain. I make it the Primary Domain Controller. I also install the Microsoft Message Queue components. All of them.

On the client side, I tried writing VB6 code from my PC - it didn't work. My guess is that you have to be a domain member. Fuck that! I'll write ASP and host it directly of the server in question. So I install IIS and enable Classical ASP (its disabled by default).

Code

There are four functions which I tried. First of all, we need to create the queue. Secondly, we write a message to the queue. Thirdly we read from the queue and fourth we delete the queue. Straight forward? Yes.

Create the queue


Set qi = Server.CreateObject("MSMQ.MSMQQueueInfo")
qi.PathName = ".\MyQueue"
qi.Create


qi is a queue info. MyQueue is the name of the queue. .\ means use the local hostname.

Send a message the queue


DIM MQ_SEND_ACCESS, MQ_DENY_NONE
MQ_SEND_ACCESS = 2
MQ_DENY_NONE = 0

Set qi = Server.CreateObject("MSMQ.MSMQQueueInfo")
Set msg= Server.CreateObject("MSMQ.MSMQMessage")
qi.PathName = ".\MyQueue"
Set objQ = qi.Open( MQ_SEND_ACCESS, MQ_DENY_NONE )

msg.Label = "Label"
msg.Body = "Body"

msg.Send objQ, 0


objQ is the queue. Use qi.Open to get it. The parameters MQ_SEND_ACCESS and MQ_DENY_NONE are constants. The values are 2 and 0. Create a message object msg then send it to the queue objQ.


Receive a message from the queue


Dim qi
Dim ReceiveQ
Dim msg
DIM MQ_DENY_NONE
Dim MQ_RECEIVE_ACCESS

MQ_DENY_NONE = 0
MQ_RECEIVE_ACCESS = 1

Set qi = Server.CreateObject("MSMQ.MSMQQueueInfo")
Set msg = Server.CreateObject("MSMQ.MSMQMessage")

qi.PathName = ".\MyQueue"

Set ReceiveQ = qi.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)

Set msg = ReceiveQ.Receive(3, false, true, 1000, false)
If msg is Nothing Then
     Response.write "No message was received"
Else
     Response.write "Message received<br>"
     Response.write msg.Body
End If

ReceiveQ.Close


ReceiveQ is the queue. Its opened with MQ_RECEIVE_ACCESS. Call ReceiveQ.Receive to get the message. The parameters 3, false, true, 1000, false are mostly flags. The value 1000 is the timeout in milliseconds.

Delete the queue


Set qi = Server.CreateObject("MSMQ.MSMQQueueInfo")
qi.PathName = ".\MyQueue"
qi.Delete


Same as the first snippet. Just change Create to Delete

Conclusion

There you have it. MSMQ in under five minutes. Ok so it took a couple hours to set up Windows Server 2003 and IIS and MSMQ. But after you start writing ASP code, its just a few lines of code. There's lots more you can do with message queues like sending binary objects, restricting who has access to the queue and so forth. Message Queues are a good idea. MS has some good tools but documentation is a but lacking in my opinion. I had trouble searching for most of the things - could be because my connection is terrible. Anyway I've done all the hard stuff so you don't have to.

June 22, 2007

Shell commands from classical ASP

If for some reason your boss think its a good idea to make shell calls from ASP, this web page may help you, regardless of whether or not you feel compelled to agree to his ridiculous demands. Certainly there are right a proper uses for this technology but we are not here to judge, only to code.

Its actually quite simple. Three easy lines to remember. First we create the object. The object we want to create is the scripting object called wscript.shell.


set wshell = server.createobject("wscript.shell")



The next line is the command we want to run. Let's not worry ourselves with silly scripts and what have you. Put whatever you want to execute in an EXE or BAT and call it.


intReturn = wshell.run("c:\myCommand.exe")


Lastly a good programmer releases whatever he/she has taken.


set wshell = nothing


Here are the 5 important notes which you must know:


  1. If you enclose your asp scripting with anything other than <% ... %> you may be in trouble.

  2. The process runs under IWAM_MachineName. If your computer is called ServerA, That user is IWAM_ServerA. Thus you must give that user execute rights to your executing exe which is myCommand.exe and other other resource it uses such as folders and log files.

  3. IWAM_MachineName is hardly ever logged on interactively (like never) so don't expect code such as MsgBox("Hello world") or running notepad.exe to work. It won't!

  4. The exe runs asynchronously. Which means line 2 returns before the application has finished running. Probably there's a way for the thread to wait but I can't be bothered about that now.

  5. Running shells in a webserver is .... not advisable. Don't try it unless you know what you're doing and even if you are I'm not responsible if your webserver gets hacked.



Thanks and goodnight