I have the following Function intended to identify the username of the user who started a specific process:
Private Function GetProcessAssociatedUserID(ByVal processName As String) As String
Dim user(1) As String
Try
Dim query As New SelectQuery(processName)
Dim searcher As New System.Management.ManagementObjectSearcher(query)
For Each process As ManagementObject In searcher.Get()
process.InvokeMethod("GetOwner", CType(user, Object()))
Next
Catch ex As Exception
End Try
Return user(0)
End Function
However somewhere in the ForEach initiation i'm getting this "ManagementException was Caught: Invalid class" exception thrown into my catch block. I've been in through debug but still cant work out what is. Any help would be much appreciated.
You can try it accomplishing this way
Private Function GetProcessAssociatedUserID(ByVal processName As String) As String
Dim query = "Select * from Win32_Process Where Name = """ + processName + """"
Dim searcher = New ManagementObjectSearcher(query)
Dim processList = searcher.Get()
For Each mObj As ManagementObject In processList
Dim argList As String() = {String.Empty, String.Empty}
Dim returnVal = Convert.ToInt32(mObj.InvokeMethod("GetOwner", argList))
If returnVal = 0 Then
Return argList(1) + "\\" + argList(0)
End If
Next
Return ""
End Function
This snippet works with .NET Framework 3.5 and above. For more details you may refer using-managementobjectsearcher-in-systemmanagement-is-getting-compiling-errors
Related
Firstly, I'm quite new to this so be gentle!
I am trying to create a class/object in VB.net for use in vba. I have used Gary Whitcher's code from the bottom of this post:
Sample vb.net code to upload file to Amazon S3 storage
I have created a class in Visual Studio and managed to get it to output a TLB file which i can import to VBA in Excel.
I can then use the object in VBA to create a new folder in the S3 storage system however I am running into problems when using the 'AddFileToFolder' method.
I have had to edit Gary's code a little to get it to compile in VS, the edited version is below.
Imports Amazon.S3
Imports Amazon.S3.Model
Imports Amazon
Imports Amazon.S3.Util
Imports System.Collections.ObjectModel
Imports System.IO
Public Class aws_s3
Const AWS_ACCESS_KEY As String = "AccessKey" 'is set to MY actual key
Const AWS_SECRET_KEY As String = "SecretKey" 'is set to MY actual key
Private Property s3Client As IAmazonS3
Sub New()
Try
s3Client = New AmazonS3Client(AWS_ACCESS_KEY, AWS_SECRET_KEY, RegionEndpoint.USEast1)
Catch ex As Exception
End Try
End Sub
Public Function CreateFolder(bucketName As String, folderName() As String) As String
Dim returnval As String = ""
Try
Try
Dim folderKey As String = ""
If Not AmazonS3Util.DoesS3BucketExist(s3Client, bucketName) Then
returnval = "Bucket does not exist"
Else
For i = 0 To folderName.Length - 1
folderKey += folderName(i) & "/"
Next
' folderKey = folderKey & "/" 'end the folder name with "/"
Dim request As PutObjectRequest = New PutObjectRequest()
request.BucketName = bucketName
request.StorageClass = S3StorageClass.Standard
request.ServerSideEncryptionMethod = ServerSideEncryptionMethod.None
' request.CannedACL = S3CannedACL.BucketOwnerFullControl
request.Key = folderKey
request.ContentBody = String.Empty
s3Client.PutObject(request)
End If
Catch ex As Exception
returnval = ex.Message
End Try
Catch ex As AmazonS3Exception
returnval = ex.Message
End Try
Return returnval
End Function
Public Function AddFileToFolder(FileName As String, bucketName As String, folderName As String) As String
Dim returnval As String = ""
Try
Try
If Not AmazonS3Util.DoesS3BucketExist(s3Client, bucketName) Then
Dim fname() As String = folderName.Split("/")
CreateFolder(bucketName, fname)
Else
Dim path As String = FileName
Dim file As FileInfo = New FileInfo(path)
Dim key As String = String.Format("{0}/{1}", folderName, file.Name)
Dim por As PutObjectRequest = New PutObjectRequest()
por.BucketName = bucketName
por.StorageClass = S3StorageClass.Standard
por.ServerSideEncryptionMethod = ServerSideEncryptionMethod.None
por.CannedACL = S3CannedACL.PublicRead
por.Key = key
por.InputStream = file.OpenRead()
s3Client.PutObject(por)
End If
Catch ex As Exception
returnval = ex.Message
End Try
Catch ex As AmazonS3Exception
returnval = ex.Message
End Try
Return returnval & " dll"
End Function
End Class
Using VBA, I have created the above object and can successfully execute CreateFolder but when executing addfiletofolder i get the error "Class does not support automation or does not support expected interface"
the VBA code looks like this:
Dim aws As AWS_S3
Dim Result As String
Dim UploadFile As String
UploadFile = "C:\Zipped Builds\Hinchley Legion.zip"
Set aws = New AWS_S3
Dim fld(1) As String
fld(0) = "folder"
fld(1) = "subfolder"
Result = aws.CreateFolder("nsmcustomercontent", fld)
If Result <> "" Then GoTo errHandle
Result = aws.AddFileToFolder(UploadFile, "nsmcustomercontent", fld)
If Result <> "" Then GoTo errHandle
Exit Sub
errHandle:
MsgBox Result
End Sub
I'm guessing from the fact that CreateFolder works fine but AddFileToFolder doesn't, there is a problem in the class as created in VS, missing a dependancy or something?
Thanks Anu6is, that was indeed the problem. The author of the class had wrote the following for usage which had thrown me off:
ADD FILE TO FOLDER
Dim fld(1) As String
fld(0) = <foldername>
fld(1) = <subfoldername>
'List each sub folder as an element in array
Dim rtrn As String = aws.AddFileToFolder(<local file name>,<bucketname>, fld)
I need to get better at reading VB.Net i think! Many thanks for your quick reply, much appreciated.
Trying to fix a warning and not sure how to restructure code as reader.IsClosed is throwing a warning that states "Variable 'reader' is used before it has been assigned a value. A null reference exception could result at run time." Logistically, since reader As SqlDataReader && reader is not initialized with a value then I could ignore as should be fine at runtime, but my inexperience would make me believe there is a better way?
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT"))
Dim spName As String = Me.GetStoreProcname()
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CInt(value)
End If
End If
Catch ex As Exception
Throw
Finally
If Not reader.IsClosed Then
reader.Close()
End If
End Try
Return 0
End Function
We can narrow the problem down to this excerpt:
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader( ... )
Finally
If Not reader.IsClosed Then reader.Close()
End Try
The problem comes if an exception is thrown by the ExecuteReader() function. In that event, the reader variable is never assigned a value. It's still Nothing when you try to evaluate reader.IsClosed, and that will cause an exception.
Given you don't actually do anything with the exception and the SqlHelper takes care of the connection and command objects, you can narrow the entire function down to just this:
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam = {
New SqlClient.SqlParameter("#" + Me.GetMetaData().PrimaryKey.ColumnName, 0),
New SqlClient.SqlParameter("#UserID", userId),
New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT")
}
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam)
If reader.Read() Then Return CInt(reader(0))
End Using
Return 0
End Function
#jmcilhinney, #o_O, #Chris Dunaway ... Thank you for the help + appreciation + admiration for your knowledge + reverence == deverence(); ... This removed the error:
Public Function GetTotalAmount(ByVal userId As Long) As Decimal
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_TOTAL_AMOUNT"))
Dim spName As String = Me.GetStoreProcname()
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CDec(value)
End If
End If
End Using
Return 0
End Function
I'm making a program that looks for processes and can see which user is using them. I've got the scanning code, but not the username code. The username has to be a string. For example: I have 2 people running some processes and the processes will show in the listview. The first column is for processes and the second is for the username. I want it to be like:
(process here) (username here)
(process here) (username here)....
You get the point I think and there's much more processes than that running on the computer. The question is: How do you get the username for someone using the process?
Edit: The code. This is my code.
For Each pr As Process In Process.GetProcesses
Dim lvi As ListViewItem = ListView1.Items.Add(CStr(pr.ProcessName))
'Now I need something to put for the username
Next
This is the other one that is most common.
Public Function GetProcessOwner(processId As Integer) As String
Dim query As String = "Select * From Win32_Process Where ProcessID = " + processId
Dim searcher As New ManagementObjectSearcher(query)
Dim processList As ManagementObjectCollection = searcher.[Get]()
For Each obj As ManagementObject In processList
Dim argList As String() = New String() {String.Empty, String.Empty}
Dim returnVal As Integer = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList))
If returnVal = 0 Then
' argList(0) == User
' argList(1) == DOMAIN
Return argList(0)
End If
Next
Return "NO OWNER"
End Function
This code is taken from here, where you can find more information if you need it. Basically, on a console app this will print the process name and the user to the screen:
Public Shared Sub Main()
Dim selectQuery As SelectQuery = New SelectQuery("Win32_Process")
Dim searcher As ManagementObjectSearcher = New
ManagementObjectSearcher(selectQuery)
For Each proc As ManagementObject In searcher.Get
Console.WriteLine(proc("Name").ToString)
Dim s(1) As String
proc.InvokeMethod("GetOwner", CType(s, Object()))
Console.WriteLine(("User: " & (s(1) + ("\\" + s(0)))))
Next
Console.ReadLine()
End Sub
This could be implemented as a function, like:
Public Function GetUserName(ByVal ProcessName As String)
Dim selectQuery As SelectQuery = New SelectQuery("Win32_Process")
Dim searcher As ManagementObjectSearcher = New ManagementObjectSearcher(selectQuery)
Dim y As System.Management.ManagementObjectCollection
y = searcher.Get
For Each proc As ManagementObject In y
Dim s(1) As String
proc.InvokeMethod("GetOwner", CType(s, Object()))
Dim n As String = proc("Name").ToString()
If n = ProcessName & ".exe" Then
Return ("User: " & s(1) & "\\" & s(0))
End If
Next
End Function
Just for reference, proc.InvokeMethod("GetOwner", CType(s, Object())) will return an array like this:
Index 0: Owner/user name
Index 1: Domain
And in our case, will store it in s(1).
Hope this helps :)
Notes:
If the function returns something like User: \\ then the process is probably a special windows process. To see which processes will act like this (for windows users):
Right click on the task bar
Select Start Task Manager
In the Processes tab, in the User Name column, some processes will have a blank cell instead of a user name.
Edit:
The VB.NET function has been edited and should now work, although I have no idea why the console program still worked. At any rate I've left it alone, if it still works why change it?
I Have Problem About this count Keyword after that appear that stuff
Here Code
Public Sub searchayumiKn()
Dim myKeyWords() As String = TChat.Text.Split(" "c)
Dim mySQLQuery As String = "SELECT AIRes FROM T_GKnowledge WHERE "
Dim KeyWordCount As Integer
For KeyWordCount = 0 To myKeyWords.Length - 1
Dim strKeyParameter As String = String.Format("#Param{0}", KeyWordCount)
Dim strWhereClause As String
If KeyWordCount = 0 Then
strWhereClause = String.Format("Keyword LIKE {0}", strKeyParameter)
Else
strWhereClause = String.Format(" OR Keyword LIKE {0}", strKeyParameter)
End If
mySQLQuery &= strWhereClause
cmdhikari.Parameters.AddWithValue(strKeyParameter, String.Format("{0}{1}{0}", "%", myKeyWords(KeyWordCount)))
Next
With cmdhikari
.CommandText = mySQLQuery
.Connection = conayumi
End With
Try
dthikari = New DataTable
dahikari.Fill(dthikari)
answers.DataBindings.Add("text", dthikari, "AIRes", True)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, "Caution")
End Try
KeyWordCount = 0
TChat.Clear()
Return
End Sub
Got Error #param bla". can anyone delete this count?
i just need original of data record. Not Count every time. just not using count. so freely record
move out from for this declaration
Dim strKeyParameter As String = String.Format("#Param{0}", KeyWordCount)
Dim strWhereClause As String
it's make duplicate declaration the same parameter
hopefully could be useful
regards
Ade Nurhuda
I am trying to get a list of processes running on remote machine and the username running them. So far I've got:
Dim ps As System.Diagnostics.Process
For Each ps In System.Diagnostics.Process.GetProcesses("myserver")
ListBox1.Items.Add(ps.ProcessName)
Next
How to get permissions for using System.Diagnostics.Process.GetProcess(string)? - this might be a better way to do it. It is in C# I can translate it if you want.
''' using System.Management;
' don't forget! in VS you may have to add a new reference to this DLL
Dim op As New ConnectionOptions()
op.Username = "REMOTE_USER"
op.Password = "REMOTE_PASSWORD"
Dim sc As New ManagementScope("\\REMOTE_COMPUTER_NAME\root\cimv2", op)
Dim query As New ObjectQuery("Select * from Win32_Process")
Dim searcher As New ManagementObjectSearcher(sc, query)
Dim result As ManagementObjectCollection = searcher.[Get]()
For Each obj As ManagementObject In result
If obj("Caption") IsNot Nothing Then
Console.Write(obj("Caption").ToString() & vbTab)
End If
If obj("CommandLine") IsNot Nothing Then
Console.WriteLine(obj("CommandLine").ToString())
End If
Next
Public Function GetProcessOwner(processId As Integer) As String
Dim query As String = "Select * From Win32_Process Where ProcessID = " & processId
Dim searcher As New ManagementObjectSearcher(query)
Dim processList As ManagementObjectCollection = searcher.[Get]()
For Each obj As ManagementObject In processList
Dim argList As String() = New String() {String.Empty, String.Empty}
Dim returnVal As Integer = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList))
If returnVal = 0 Then
' return DOMAIN\user
Return argList(1) & "\" & argList(0)
End If
Next
Return "NO OWNER"
End Function