How to handle Console Application Close button event - console

I have a console application which communicating with WCF service on startup and after som computation we are entering some data in sql database. and in console app we are handling enter key to close the application and at the time of closing Application i am cleaning relevant data from Database. but It fails when some close the console application using mouse to click on close icon.(Instantly its close).
Please let me know that how to handle Close button event and also ctrl+f4.
The code is below:
Private m_ControllerID As String = String.Empty
Sub Main()
HostControllerService()
End Sub
Private Sub HostControllerService()
m_ControllerID = RegisterMe()
Console.WriteLine("Retention Controller Service is running...")
Console.WriteLine("Press <Enter> key to exit and UnRegister the service.")
Console.ReadLine()
UnRegisterMe(m_ControllerID)
End Sub
Private Function RegisterMe() As String
'Code snippet to Save data In database.
End Function
Private Sub UnRegisterMe(ByVal m_ControllerID As String)
'Cleaning the data from Database.
End Sub

Related

How can I store the data in memory and use by the other Button click event to display the data?

Here is the code, but the datatable is NULL in ButtonExport click event, how can i pass the DataTable to Sub ButtonExport_Click ? I dont want to store in Session as the data is too big
Here is the class clsGlobalVarriable
Public Class clsGlobalVariable
Private _gdt As DataTable
Public Property globalDataTable As DataTable
Get
Return _gdt
End Get
Set(ByVal value As DataTable)
_gdt = value
End Set
End Property
End Class
Here is the From frmTest code:
Public Class frmTest
Inherits System.Web.UI.Page
Private gdt As New clsGlobalVariable
Protected Sub ButtonInactivePC_Click(sender As Object, e As EventArgs) Handles ButtonInactivePC.Click
Try
Dim func As New clsFunction
Dim command As String = "Get-ADComputer -Filter { OperatingSystem -NotLike '*Windows Server*'} -Property * | select Name, CanonicalName, operatingSystem, LastLogonDate, Description, whenChanged | Where {($_.LastLogonDate -lt (Get-Date).AddDays(-90)) -and ($_.LastLogonDate -ne $NULL)}"
Dim arr As New ArrayList
arr.Add("Name")
arr.Add("CanonicalName")
arr.Add("operatingSystem")
arr.Add("LastLogonDate")
arr.Add("whenChanged")
arr.Add("Description")
gdt.globalDataTable = func.PSObjectToDataTable(command, arr)
Me.GridView1.DataSource = gdt.globalDataTable
Me.GridView1.DataBind()
Catch ex As Exception
Me.LabelDebug.Text = "Button Click" + ex.Message
End Try
End Sub
Protected Sub ButtonExport_Click(sender As Object, e As EventArgs) Handles ButtonExport.Click
Dim func As New clsFunction
Dim dt As New DataTable
dt = (DirectCast(Me.GridView1.DataSource, DataTable))
Me.LabelDebug.Text = "Global Data Table Count = " & dt.Rows.Count
End Sub
When working with webpages that show data to the user, and the user takes some action on that data you either need to store the data somewhere in their computer, your computer (the server) or rely on the fact that it's still stored in the computer you got it from. As a process you have undertaken:
You generate a grid from querying AD
You send the grid to the customer's computer - so it's stored there as a visual representation (and maybe also ViewState)
It's still stored in AD, where you got it
You could also store it locally on the server somehow - Session, DB, text file, whatever
Decide on which of these to use when the user clicks Export:
Dig it out of the viewstate or other data that was sent to the user - for this you'll have to code things up so it comes back from the user
Get it out of AD again - simple to do; you did it once and sent it to the user in HTML. Getting it again and sending it to the user again this time as a CSV isn't really any different from the first time you did it
Restore it from wherever you kept it on the server
Choose the first if your user is going to modify the data or choose to export only some of it - the data he sends back to you should indicate which bits he wants exporting.
Choose the second option if you want an easy life, and it's just a straight export, no editing or subset of data. Write one method that gets the data out of AD and then use it in either place, one to form HTML/fill a grid, in the other to send a file to the user. Don't get hung up on "well I already got this data once, it's a waste to get it again" - no-one writes a Login Page and thinks "i'll only ever look up a user from the DB once, then get the server to remember the login data forever more and use it next time there is a login request" - they store the data in the db, and look it up every time there is a login. DBs store data and perform the same queries over and over again. This is no different
You probably wouldn't choose the third option, for reasons already mentioned
I decided to use alternative for the Excel Export, i am not going to pass the DataTable, instead i pass the GridView to the Export to Excel function
Add the following sub right after Page_load, this is to avoid the GridView error
Public Overrides Sub VerifyRenderingInServerForm(ByVal control As Control)
End Sub
Here is the Code:
Public Sub ExportFromGridview(ByVal gv As GridView, ByVal response As HttpResponse
response.Clear()
response.Write("<meta http-equiv=Content-Type content=text/html;charset=utf-8>")
response.AddHeader("content-disposition", "attachment;filename=" & Now & ".xls")
response.ContentType = "application/vnd.xls"
Dim stringWrite As System.IO.StringWriter = New System.IO.StringWriter()
Dim htmlWrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite)
gv.RenderControl(htmlWrite)
response.Write(stringWrite.ToString())
response.End()
End Sub

Serilog is missing log file entries for my ASP VB.NET web project

The following code works fine for one user on the web site.
However as soon an multiple users start logging in simultaneously, Serilog starts missing log file entries. Anybody know what I am missing please?
Public Class cLogger
Public Shared gSerilogger As ILogger = Nothing
Public Shared gblSeriLock As New Object
Public Shared Sub DoSerilog(ByVal sLogMessage As String)
SyncLock gblSeriLock
If gSerilogger Is Nothing Then
gSerilogger = New LoggerConfiguration().WriteTo.Console().WriteTo.File("d:\Logfiles\SERI.log").CreateLogger()
End If
gSerilogger.Information(sLogMessage)
End SyncLock
End Sub
End Class
Usage example:
cLogger.DoSerilog("Test")

Visual basic programmatically pass username and password to https url to make webbrowser display webpage and also download from webpage

With normal HTTP I can download upload and navigate to routers but I can't find any code to do any of that when the routers are on HTTPS.
To download I use this:
Try
My.Computer.Network.DownloadFile("http://" & "180.29.74.70" & "/cgi-bin/log.cgi", "C:\Users\ssb\Desktop\randomword.txt", "username", "password")
WebBrowser1.Refresh()
Catch ex As Exception
MessageBox.Show("Router not sufficient for operation Return for Inspection cannot download log file")
End Try
To upload a file I use this:
My.Computer.Network.UploadFile("C:\Users\ssb\Desktop\tomtn.txt", "http://" & "180.29.74.70" & "/cgi-bin/updateconfig.cgi", "username", "password")
To navigate to a web page on HTTP I use this:
WebBrowser1.Navigate("https://username:password#180.29.74.70 ")
But when I use HTTPS:
WebBrowser1.Navigate("https://username:password#180.29.74.70 ")
I get this security alert:
Then I click on yes and it goes to the pageā€”but I need the code to bypass any security questions like these.
Even though they're loosely related, you've presented two separate questions here.
Why is the call failing when I use the WebBrowser control to load a page via HTTPS?
Why is the call failing when I use the DownloadFile() method to download a file via HTTPS?
First, you need to eliminate the possibility that your code is failing. Try both of the tasks above using public HTTPS URLs that are known to work correctly.
If you discover that the source of the problem is your private URL, you may want to consider whether you want to ignore SSL errors in your WebBrowser control.
You can do so using the (untested, translated to VB) code from this blog post:
Partial Public Class Form1
Inherits Form
Private WithEvents WebBrowser As New WebBrowser
Private Sub WebBrowser_DocumentCompleted(Sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser.DocumentCompleted
If e.Url.ToString() = "about:blank" Then
'create a certificate mismatch
WebBrowser.Navigate("https://74.125.225.229/")
End If
End Sub
End Class
<Guid("6D5140C1-7436-11CE-8034-00AA006009FA")>
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
<ComImport>
Public Interface UCOMIServiceProvider
<PreserveSig>
Function QueryService(<[In]> ByRef guidService As Guid, <[In]> ByRef riid As Guid, <Out> ByRef ppvObject As IntPtr) As <MarshalAs(UnmanagedType.I4)> Integer
End Interface
<ComImport>
<ComVisible(True)>
<Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b")>
<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IWindowForBindingUI
<PreserveSig>
Function GetWindow(<[In]> ByRef rguidReason As Guid, <[In], Out> ByRef phwnd As IntPtr) As <MarshalAs(UnmanagedType.I4)> Integer
End Interface
<ComImport>
<ComVisible(True)>
<Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b")>
<InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IHttpSecurity
'derived from IWindowForBindingUI
<PreserveSig>
Function GetWindow(<[In]> ByRef rguidReason As Guid, <[In], Out> ByRef phwnd As IntPtr) As <MarshalAs(UnmanagedType.I4)> Integer
<PreserveSig>
Function OnSecurityProblem(<[In], MarshalAs(UnmanagedType.U4)> dwProblem As UInteger) As Integer
End Interface
Public Class MyWebBrowser
Inherits WebBrowser
Public Shared IID_IHttpSecurity As New Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b")
Public Shared IID_IWindowForBindingUI As New Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b")
Public Const S_OK As Integer = 0
Public Const S_FALSE As Integer = 1
Public Const E_NOINTERFACE As Integer = &H80004002
Public Const RPC_E_RETRY As Integer = &H80010109
Protected Overrides Function CreateWebBrowserSiteBase() As WebBrowserSiteBase
Return New MyWebBrowserSite(Me)
End Function
Private Class MyWebBrowserSite
Inherits WebBrowserSite
Implements UCOMIServiceProvider
Implements IHttpSecurity
Implements IWindowForBindingUI
Private myWebBrowser As MyWebBrowser
Public Sub New(myWebBrowser As MyWebBrowser)
MyBase.New(myWebBrowser)
Me.myWebBrowser = myWebBrowser
End Sub
Public Function QueryService(ByRef guidService As Guid, ByRef riid As Guid, ByRef ppvObject As IntPtr) As Integer Implements UCOMIServiceProvider.QueryService
If riid = IID_IHttpSecurity Then
ppvObject = Marshal.GetComInterfaceForObject(Me, GetType(IHttpSecurity))
Return S_OK
End If
If riid = IID_IWindowForBindingUI Then
ppvObject = Marshal.GetComInterfaceForObject(Me, GetType(IWindowForBindingUI))
Return S_OK
End If
ppvObject = IntPtr.Zero
Return E_NOINTERFACE
End Function
Public Function GetWindow(ByRef rguidReason As Guid, ByRef phwnd As IntPtr) As Integer Implements IHttpSecurity.GetWindow, IWindowForBindingUI.GetWindow
If rguidReason = IID_IHttpSecurity OrElse rguidReason = IID_IWindowForBindingUI Then
phwnd = myWebBrowser.Handle
Return S_OK
Else
phwnd = IntPtr.Zero
Return S_FALSE
End If
End Function
Public Function OnSecurityProblem(dwProblem As UInteger) As Integer Implements IHttpSecurity.OnSecurityProblem
'ignore errors
'undocumented return code, does not work on IE6
Return S_OK
End Function
End Class
End Class
Regarding problem #2: It appears you may be confusing WebBrowser and DownloadFile(). As you've probably already discovered, the WebBrowser control doesn't download files. However, you can simulate the behavior using this technique:
Partial Public Class Form2
Inherits Form
Private Sub WebBrowser_Navigating(Sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser.Navigating
Dim sFilePath As String
Dim oClient As Net.WebClient
' This can be any conditional criteria you wish '
If (e.Url.Segments(e.Url.Segments.Length - 1).EndsWith(".pdf")) Then
SaveFileDialog.FileName = e.Url.Segments(e.Url.Segments.Length - 1)
e.Cancel = True
If SaveFileDialog.ShowDialog() = DialogResult.OK Then
sFilePath = SaveFileDialog.FileName
oClient = New Net.WebClient
AddHandler oClient.DownloadFileCompleted, New AsyncCompletedEventHandler(AddressOf DownloadFileCompleted)
oClient.DownloadFileAsync(e.Url, sFilePath)
End If
End If
End Sub
Private Sub DownloadFileCompleted(Sender As Object, e As AsyncCompletedEventArgs)
MessageBox.Show("File downloaded")
End Sub
Private WithEvents SaveFileDialog As New SaveFileDialog
Private WithEvents WebBrowser As New WebBrowser
End Class
In any event, the first step in solving this is to figure out whether it's your code or the private URL that's causing your issue.
The main thing needed here is to programatically download a file from a https url while using a username and password blocked by the security certificate issue
and the solution after searching for 2 weeks is
To Download a file you can disable the security cerificate request temporaraly with the following code then after the code ran it enables the security certicate again
First code you dont even need a browser it automatically saves the file to you desktop
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'check if a simular file doesnt exists so you can create a new file and deletes the file if it exists
If File.Exists("C:\pathtoyourfile\yourfilename.txt") Then
File.Delete("C:\pathtoyourfile\yourfilename.txt")
End If
'Type this before your download or hhtps request
'ByPass SSL Certificate Validation Checking
System.Net.ServicePointManager.ServerCertificateValidationCallback =
Function(se As Object,
cert As System.Security.Cryptography.X509Certificates.X509Certificate,
chain As System.Security.Cryptography.X509Certificates.X509Chain,
sslerror As System.Net.Security.SslPolicyErrors) True
'Call web application/web service with HTTPS URL here
'=========================================================================================
'ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications
Try
My.Computer.Network.DownloadFile("https://176.53.78.22/filenameonserveryouwanttodownload", "C:\pathtoyourfile\yourfilename.txt", "Yourusername", "yourpassword")
WebBrowser1.Refresh()
Catch ex As Exception
MessageBox.Show("message saying something didnt work")
'exit sub if it worked
Exit Sub
End Try
MessageBox.Show(" message saying it worked")
'=========================================================================================
'Restore SSL Certificate Validation Checking
System.Net.ServicePointManager.ServerCertificateValidationCallback = Nothing
End Sub
then to browse to a webaddress the following code will popup and the security popup will popup but just select yes browsing on the webpage works normally
WebBrowser1.Navigate("https://username:password#180.29.74.70 ")
As you said:
[...] I need the code to bypass any security questions like these.
In other word, you need to "automatically accept self signed SSL certificate", so in my opinion it is a duplicate question with : VB .net Accept Self-Signed SSL certificate, which may fit your needs.
and most especially slaks answer:
In VB.Net, you need to write:
ServicePointManager.ServerCertificateValidationCallback = AddressOf AcceptAllCertifications

Write to a log file asynchronously from asp.net task

Using VB.Net (Framework version 4.5.1)
I have a program that sets up a list of (System.Threading.Tasks.Task) tasks that are executed as follows (only relevant code is shown):
po = New System.Threading.Tasks.ParallelOptions()
po.MaxDegreeOfParallelism = 5
Parallel.ForEach( task_list, po, AddressOf do_work )
The program works fine, but I want to add a log file rather than using just Console.WriteLine()
In the do_work() Sub, I want to write to a log file, for example:
Sub do_work( param As String )
Dim thread_id as String = "Thread ID " & System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() & ": "
joblog_append( thread_id & "Beg" )
joblog_append( thread_id & "param = " & param )
joblog_append( thread_id & "End" )
End Sub
Ideally, I would like to create three functions such as:
joblog_open() to open a log file at the start o the program.
joblog_append() to append to the log file; callable from within any task
joblog_close() to close the log file
What is the correct way to implement such logging when the joblog_append() will be called from multiple tasks being executed on separate threads?
All attempts I have tried so far seem to be hit and miss; sometimes the data is written to the output file, sometimes it is not.
Any advice (or better yet, a code example) would be most appreciated.
Thanks in advance.
I think that the issue you have is due to the fact multiple threads are accessing the file at the same time.
A better approach would be to make sure only one thread access the file at a time. You could use a lock (see this SO) or append the messages to be written to a concurrentQueue of string, then process that queue on another thread.
The joblog_append calls _Logger.Log, which in turns enqueue the message and start a new thread to process the queue.
private _Logger as new Logger
Private Sub joblog_append(Message As String)
_Logger.Log(Message)
End Sub
The logger class performs the following.
Append message to to a concurrent queue
Create and start a task (if no one already running) to write queue content to the file.
Set the task to nothing when completed
In the event the task is already created, the message is enqueued and the While condition in the task itself should take care of any messages added while it's running.
'Missing: Idisposable, Fileaccess.Shared,
'TODO: remove debugger.break
Public class Logger
Public Property Messages As new ConcurrentQueue(Of string)
private _WorkerTask as Task
private event WorkerTaskCompleted
private _Stream as FileStream
private _Writer as StreamWriter
Public sub New()
_Stream = io.file.OpenWrite("Mylog.txt")
_Writer = New StreamWriter(_Stream)
End sub
Public sub Log(Message as string)
Messages.Enqueue(Message)
if _WorkerTask Is Nothing
_WorkerTask = New Task(sub()
While Messages.Any
Dim CurrentMessage as string = ""
if Messages.TryDequeue(CurrentMessage)
_Writer.WriteLine(CurrentMessage)
else
debugger.Break
End If
End While
_Writer.Flush
_Stream.Flush
RaiseEvent WorkerTaskCompleted
End Sub)
_WorkerTask.Start
End If
End sub
Private Sub Logger_WorkerTaskCompleted() Handles Me.WorkerTaskCompleted
_WorkerTask = Nothing
End Sub
End Class
Please note. This is my approach to this problem but I do not have anything similar implemented and tested. Therefore, you will have to make your tests to confirm it is working properly.

Instantiating a class within WCF

I'm writing a WCF WebMethod to upload files to, of which I taken snippets from around the web. The WCF interface looks like this:
<ServiceContract()>
Public Interface ITransferService
<OperationContract()>
Sub UploadFile(ByVal request As RemoteFileInfo)
End Interface
<MessageContract()>
Public Class RemoteFileInfo
Implements IDisposable
<MessageHeader(MustUnderstand:=True)>
Public FileName As String
<MessageHeader(MustUnderstand:=True)>
Public Length As Long
<MessageBodyMember(Order:=1)>
Public FileByteStream As System.IO.Stream
Public Sub Dispose() Implements IDisposable.Dispose
If FileByteStream IsNot Nothing Then
FileByteStream.Close()
FileByteStream = Nothing
End If
End Sub
End Class
Within ASP.NET, when the web method is consumed, for some reason it only works when the interface is used as part of the instantiation of RemoteFileInfo:
Protected Sub btn_Click(sender As Object, e As EventArgs) Handles btn.Click
If fu.HasFile Then
Dim fi As New System.IO.FileInfo(fu.PostedFile.FileName)
' this is the line in question --------------
Dim cu As ServiceReference1.ITransferService = New ServiceReference1.TransferServiceClient()
' -------------------------------------------
Dim uri As New ServiceReference1.RemoteFileInfo()
Using stream As New System.IO.FileStream(fu.PostedFile.FileName, IO.FileMode.Open, IO.FileAccess.Read)
uri.FileName = fu.FileName
uri.Length = fi.Length
uri.FileByteStream = stream
cu.UploadFile(uri)
End Using
End If
End Sub
Can anyone advise why it is not possible to create an instance of TransferService using the following approach:
Dim cu As New ServiceReference1.TransferServiceClient()
If I try the above, it breaks this line:
cu.UploadFile(uri)
...and UploadFile must be called with three parameters (FileName, Length, FileByteStream) even there is no method that uses this signature.
Why is the Interface required when creating an instance of this class please?
When you create the proxy for your service with the "Add Service Reference" dialog, by default the proxy creation code will "unwrap" message contracts, like the one you have. If you want the message contract to appear as you defined on the server side on your proxy, you need to select the "Advanced" tab, and check the "Always generate message contracts" option. With that you'll get the message contract in your client as well.
The issue is that when a MessageContract is encountered as a parameter, the WCF client generation assumes by default that you want to implement a messaging-style interface, and provides the discrete properties from the message contract as part of the client-side interface.
The Using Messaging Contracts article in MSDN contains a very detailed description of what can be done with a messaging contract and I suspect that Microsoft chose this default behavior because of some of the "games" that you can play with the messages.
However, if you examine the code generated for your UploadFile on the client side, there are some interesting tidbits that help to explain what is going on.
The first is the comments for the UploadFile method in the interface:
'CODEGEN: Generating message contract since the operation UploadFile is neither RPC nor document wrapped.
...
Function UploadFile(ByVal request As ServiceReference1.RemoteFileInfo) As ServiceReference1.UploadFileResponse
This implies that the contract would have been generated differently if the message contract had a different implementation.
The second is that you will see that there is nothing special about the code that is used to actually make the service call:
Public Sub UploadFile(ByVal FileName As String, ByVal Length As Long, ByVal FileByteStream As System.IO.Stream)
Dim inValue As ServiceReference1.RemoteFileInfo = New ServiceReference1.RemoteFileInfo()
inValue.FileName = FileName
inValue.Length = Length
inValue.FileByteStream = FileByteStream
Dim retVal As ServiceReference1.UploadFileResponse = CType(Me,ServiceReference1.ITransferService).UploadFile(inValue)
End Sub
So in this case, your code is doing exactly what the generated code does. However, if the MessageContract were more complex, I suspect that this would no longer be the case.
So, for your question:
Can anyone advise why it is not possible to create an instance of
TransferService using the following approach...
There is no reason not to take this approach as long as you verify that the implementation of the method call is functionality equivalent to your code.
There are a couple of options for changing the default generation of the method in the client:
1) Remove the MessageContract attribute from the RemoteFileInfo class.
2) Although it seems to be counter-intuitive, you can check the Always generate message contracts checkbox in the Configure Service Reference Dialog Box.

Resources