I want to host a web server and want to use VBA to do it. Is this possible? I'm just doing this to prove someone wrong and really want to make this program.
So is it possible to make a really simple web server (just listens for get requests)? Help would be very much appreciated.
EDIT
I'm trying something like this
Sub startServer()
Set wunsock = CreateObject("OSWINSCK.Winsock")
wunsock.LocalPort = 80
wunsock.Listen
End Sub
Sub wunsock_ConnectionRequest(ByVal requestID As Long)
If sockMain.State <> sckClosed Then
sockMain.Close
End If
sockMain.Accept requestID
End Sub
Private Sub wunsock_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
sockMain.GetData strData, vbString
txtStatus.Text = txtStatus.Text & _
strData & vbCrLf
End Sub
However it doesn't work?
Although this is a rather old question, I'd still like to mention that I built an Excel hosted REST webserver using plain VBA macros and some Winsock C calls, as proposed by Daniel A. White.
I added this as an answer instead of a comment, since it's built as a modular library, so you can adjust it to your needs, and others might need exactly this kind of library. It can serve both worksheets, basic files and also create custom hooks using an IWebController to listen on specific routes (which was mentioned by OP in a comment):
http://github.com/michaelneu/webxcel
To use it, you'll have to either import the classes/modules into your workbook, or let the build script create a new one for you. See Main.bas on how to start the server from within VBA.
http://www.ostrosoft.com/oswinsck.asp#inst
is a winsock type of library which can be used from VBA. It is possible to do what you are looking to do though is not the most efficient thing to do.
I do applaud your tenacity hope it works out for you.
I'm not sure I fully understand the question. Generally, you don't "host a web server", you host a web site.
But if you can do TCP sockets with VBA, then you can make an incredibly simple web server by following the HTTP standard protocol.
Edit: based on your comment, yes you can make a simple web server as long as you can open up a TCP socket.
Well, at the risk of violating the spirit of the question, you can always use VB's support for library functions and just create a library binding to one of a number of C-language web server options (such as http://www.acme.com/software/micro_httpd/, http://www.gnu.org/software/libmicrohttpd/ or http://code.google.com/p/mongoose/). You'd have to make DLLs out of the selected web server but that is reasonably easily done and this will work just fine in VBA.
Related
I have the problem, I'm in a network, where everyone sends messages through msg. Through it's really annoying, I thought about killing the messageboxes process. Running under csrss.exe thats not possible. When I looked through the taskmanager I noticed, when opening the tree structure of the csrss.exe, there was the messagebox and I could kill it. Has anyone any idea, how to do that in Visual Basic.
A simple web search led me to this question, which has some good answers already.
With a little work, I came up with this solution. It find the process by name (csrss), then filters by window title (Message from).
Sub Main()
killProcesses("csrss", "Message from")
End Sub
Private Sub killProcesses(processName As String, mainWindowTitle As String)
Dim processes = Process.GetProcesses().
Where(Function(p) p.ProcessName.Contains(processName)).
Where(Function(p) p.MainWindowTitle.Contains(mainWindowTitle))
' (Where clauses can be combined into one of course)
For Each p In processes
p.CloseMainWindow()
Next
End Sub
It works like this. Send a message
C:\Users\djv>msg djv hey whats up
Get a message
Here is the task
And what the code sees
It is closed upon the p.CloseMainWindow() call. It will also close any other window which matches the description, since it's not limited to one. This should satisfy your requirement.
Just so the question hast a proper answer, I found a solution using the win32 api (PInvokes) specifically the user32.dll. It provides methods like GetWindow, GetWindowThreadProcessId and CloseWindow, which solved my problem.
I currently have made an all in one peer to peer 'chat' program. It currently uses a timer to receive messages, and a client to send them to other people running the program. I would really like to make this whole system async so I stop getting complaints of the main executable freezing and such.
I have pasted all of my code(VB.net) here: http://pastebin.com/EcrtCgVc
Could someone assist me in making this system faster, async, or done better.
If you would like a link to the dropbox of the full source, I can provide this also.
I would suggest you to take a look at this example project:
Asynchronous Server Socket Example
http://msdn.microsoft.com/en-us/library/fx6588te%28v=vs.110%29.aspx
You can use it together with this example:
Asynchronous Client Socket Example
http://msdn.microsoft.com/en-us/library/bew39x2a%28v=vs.110%29.aspx
You may need to use async methods in your server code and you may use Delegate Sub to make your server run in another thread, so main thread(UI) will be still responsive.
http://msdn.microsoft.com/en-us/library/ms172879.aspx
Without looking at your code, I am also working with socket programming.
"Do not mix GUI code with business code."
Like jgauffin said, you should not combine code that run in the background with the GUI.
For example, if you're using a socket to accept data, or connections, you must run that method on a new thread.
Example...
Public Sub YourMainSub()
Dim threadOne As New System.Threading.Thread(AddressOf ListenCode)
threadOne.Start()
'Put other code here.....
End Sub
Public Sub ListenCode()
Dim newPerson = yourServer.Accept()
'Or
Dim newData = yourServer.Receive()
End Sub
Sorry if the code isn't exactly correct. I typed that by memory.
This would be easier if I were able to have the external computer get its own name and just pass it to a web service as a variable, but I'm not able to do that right now. There are a variable number of computers from several different entities that regurarly access a web service on one of our servers. Changing only some VB.Net code on the server and nothing at all on any of those external computers, how would I be able to get their names programmatically in VB.Net? Thanks!
EDIT: Some of the answers look like they're designed to get the IP of either the server, the server's router, or something else along those lines. Maybe I'm just misreading the code or something, but I was talking about getting the names of client, external computers who try to access a webmethod on the server, using the webmethod's code to do so.
If there is no address translation and computers has DNS entries:
Dim ip As String = System.Web.HttpContext.Current.Request.UserHostAddress
Dim name as String = System.Net.Dns.GetHostEntry(ip).HostName()
System.Net.Dns.GetHostAddresses(My.Computer.Name)(5).ToString
Quick solution for getting external IP in VB.Net
Dim sIp As String
Dim webClient As System.Net.WebClient = New System.Net.WebClient()
sIp = webClient.DownloadString("http://lbb.ie/ip.php")
And that's it It is my own php file on my own server so go ahead :) Enjoy
I'm using Silverlight 4 OOB & elevated trust.
I need to get all the filenames on specific directory & populate an object List(Of String)
The compiler throws an error "Method not found" on .Getfiles() method.
Dim files() As String = System.IO.Directory.Getfiles(Path) 'this line is failing..
Help!
The GetFiles is marked as "Security Critical" and therefore cannot be used from your code.
You will want to use the EnumerateFiles method instead. GetFiles is sooo .NET 1.0, EnumerateFiles is much slicker, even in the full framework you'd want avoid this older Array returning API if you can.
As far as I know you cannot directly access the whole hard drive using Silverlight OOB.
Quoting from Silverlight site:
When running in a trusted environment, you can access only files in
user folders, specifically the MyDocuments, MyMusic, MyPictures, and
MyVideos folders. Although this makes sense from a security point of
view, it’s limiting. You want to enable the user to drag their data
from any location. As it stands right now, if you try to drop a file
from a location other than stated above, Silverlight will throw a
security error.
Please refer to this link for details on how to work with the hard drive using Silverlight OOB:
http://www.silverlight.net/learn/overview/out-of-browser-applications/advanced-silverlight-out-of-browser-introduction#Exercise3
Despite my lack of coding knowledge I managed to write a small little app in VB net that a lot of people are now using. Since I made it for free I have no way of knowing how popular it really is and was thinking I could make it ping some sort of online stat counter so I could figure out if I should port it to other languages. Any idea of how I could ping a url via vb without actually opening a window or asking to receive any data? When I google a lot of terms for this I end up with examples with 50+ lines of code for what I would think should only take one line or so, similar to opening an IE window.
Side Note: Would of course fully inform all users this was happening.
Just a sidenote: You should inform your users that you are doing this (or not do it at all) for privacy concerns. Even if you aren't collecting any personal data it can be considered a privacy problem. For example, when programs collect usage information, they almost always have a box in the installation process asking if the user wants to participate in an "anonymous usage survey" or something similar. What if you just tracked downloads?
Might be easier to track downloads (assuming people are getting this via HTTP) instead of installs. Otherwise, add a "register now?" feature.
You could use something simple in the client app like
Sub PingServer(Server As String, Port As Integer)
Dim Temp As New System.Net.Sockets();
Temp.Connect(Server, Port)
Temp.Close()
End Sub
Get your webserver to listen on a particular port and count connections.
Also, you really shouldn't do this without the user's knowledge, so as others have said, it would be better to count downloads, or implement a registration feature.
I assume you are making this available via a website. So you could just ask people to give you their email address in order to get the download link for the installer. Then you can track how many people add themselves to your email list each month/week/etc. It also means you can email them all when you make a new release so that they can keep up to date with the latest and greatest.
Note: Always ensure they have an unsubscribe link at the end of each email you send them.
The guys over at vbdotnetheaven.com have a simple example using the WebClient, WebRequest and HttpWebRequest classes. Here is their WebClient class example:
Imports System
Imports System.IO
Imports System.Net
Module Module1
Sub Main()
' Address of URL
Dim URL As String = http://www.c-sharpcorner.com/default.asp
' Get HTML data
Dim client As WebClient = New WebClient()
Dim data As Stream = client.OpenRead(URL)
Dim reader As StreamReader = New StreamReader(data)
Dim str As String = ""
str = reader.ReadLine()
Do While str.Length > 0
Console.WriteLine(str)
str = reader.ReadLine()
Loop
End Sub
End Module
.NET? Create an ASMX Web Service and set it up on your web site. Then add the service reference to your app.
EDIT/CLARIFICATION: Your Web Service can then store passed data into a database, instead of relying on Web Logs: Installation Id, Install Date, Number of times run, etc.