I'm writing a program to interface with an inspection machine. The machine has the ability to output command lines during its program run.
The machine has an interface application which allows the passing and automatic start of programs into the machine. I can get this to work with a single instance, however I would like to be able to select several programs for it to run back to back.
Below is the code to pass a single program to the machine:
im ProgramName As String = cbProgram.Text
Dim ProgURL = GetXMLNode(1, ProgramName)
Dim exeDir As New IO.FileInfo(Reflection.Assembly.GetExecutingAssembly.FullName)
Dim EXEPath = IO.Path.Combine(exeDir.DirectoryName, "iscmd.exe")
' New ProcessStartInfo created
Dim p As New ProcessStartInfo
' Specify the location of the binary
p.FileName = EXEPath
' Use these arguments for the process
p.Arguments = " /run""" & ProgURL & """ /nowait"
' Use a hidden window
p.WindowStyle = ProcessWindowStyle.Hidden
' Start the process
Dim ISCMD As Process = Process.Start(p)
ISCMD.WaitForExit()
MsgBox("PING!")
The PING will show immediately after the program has been passed to the machine (but not completed). What I want to be able to do is build an array of programs and launch this process once each time a program has completed. Is it possible to use a command line from the machine to signal to my software that the next program can be started? Below is a screenshot the machines command line.
Related
I've written a pair of apps; one that issues powershell scripts to clients (the server) and one that executes powershell scripts passed to it (the client).
I've added functions to detect if a particular script requires elevation.
In the event that a script requires elevation, the server app prompts the user for their credentials. The password is converted to a secure string and saved in a SQL database, as is the username along with the script.
The client app grabs the script and, if elevation is required, grabs the username and secure string then tries to build a credential object from it.
The functionality is working fine for non-elevated scripts, but elevated scripts are not working. Its not erroring or throwing an exception (finally) but the scripts are not executed.
The first part of this process reads the data from SQL into a datatable and then i loop through the rows of that datatable.
Once I've got a row that contains a script that needs running, I build the script.
Here's how I'm building and executing the powershell in VB...
If this_routine_elevation_required = 1 Then
Dim scriptbody As String = row("scriptbody").ToString
Dim elevated_user_un As String = row("elevated_user").ToString
Dim elevated_user_ss As String = row("securestring").ToString
credential_script = "$securepassword = '" & elevated_user_ss & "' | ConvertTo-SecureString; $username='" & elevated_user_un & "';$credential = New-Object System.Management.Automation.PsCredential($username, $securepassword)"
action_response = RunPowershellScript(credential_script & "; " & scriptbody)
End If
and here is the function that executes the powershell (using 'Imports System.Management.Automation)...
Private Function RunPowershellScript(ByVal scriptText As String) As String
' create Powershell runspace
Dim MyRunSpace As Runspace = RunspaceFactory.CreateRunspace()
MyRunSpace.Open()
Dim MyPipeline As Pipeline = MyRunSpace.CreatePipeline()
MyPipeline.Commands.AddScript(scriptText)
Dim results As Collection(Of PSObject) = MyPipeline.Invoke()
MyRunSpace.Close()
Dim MyStringBuilder As New StringBuilder()
For Each obj As PSObject In results
MyStringBuilder.AppendLine(obj.ToString())
Next
Return MyStringBuilder.ToString()
End Function
I've thrown up a messagebox of the script before its passed to the RunPowershellScript function so i could make sure nothing was malformed or to ensure i wasnt doing anything stupid (i've manipulated the secure string for the purposes of this image)...
The example here is just a test to see if the executor could stop the W32Time service, something that would normally require elevation. It does not work.
I get an empty response back from the RunPowershellScript function and the service continues to run.
It occured to me that I'm getting a securestring from the database and then converting that securestring to a securestring, so perhaps its not ending up with the correct valid password in $credential, but from what i understand I have to provide a securestring for the password parameter of PsCredential, and without -ConvertTo-SecureString it would consider the password to just be a string. I tried this and it threw an exception about the password being null.
Can anyone help point me in the right direction?
Many thanks in advance.
Is the script running locally on the target or from the server?
Credential objects are specific to the computer AND user account which creates them, so they are not transferable and can only be used on the computer which creates them.
I'm creating a tool in VB using Visual Studio 2015 and I'm having some issues with forcing one item on a menu strip when clicked to open the SCCM Configuration Manager.
So far I've tried:
Option 1
Dim ProcID As Integer
ProcID = Shell("control smscfgrc", AppWinStyle.NormalFocus)
Option 2
Process.Start("cmd.exe", "control smscfgrc")
Option 3
Dim p as Process = new Process()
Dim pi as ProcessStartInfo = new ProcessStartInfo()
pi.Arguments = "control smscfgrc"
pi.FileName = "cmd.exe"
p.StartInfo = pi
Option 4
Shell=("control smscfgrc", 0)
None of the above work, they just open the console but nothing else.
If I open a regular cmd window using "windows + R" and type the command "control smscfgrc" it open the SCCM Configuration Manager as it should.
I really need this to complete my tool, any help is much appreciated!
Thank you for the time you took to read this.
I'm not a guru with VS nor VB, but your commands to open cmd.exe looks incorrect. You need to add a /c. The command in the Run window ( + R) would look like this ...
cmd.exe /c control smscfgrc
Of course, control is actually control.exe, so you don't even need cmd.exe:
control.exe smscfgrc
Tested and confirmed that this opens the Configuration Manager Properties window from the Run windows on my computer.
You also may need the full path to control.exe. I would use environment variables; I think this is how it would be done in VB:
Dim control_exe As String
control_exe = Environment.GetEnvironmentVariable("SystemRoot") & "\System32\control.exe"
You will automatically get redirected to SysWOW64 if running on as a 32-bit process on a 64-bit OS.
Option 2
Process.Start(control_exe, "smscfgrc")
Option 3
Dim p as Process = new Process()
Dim pi as ProcessStartInfo = new ProcessStartInfo()
pi.Arguments = "smscfgrc"
pi.FileName = control_exe
p.StartInfo = pi
I have a windows batch file which I want to execute using vb.net however the batch as well as the VB.net exe that will execute it are run from the cd rom which means tat i want my vb.net to run the batch from current directory (as both will be placed in the current directory, on CD)
How can I achive this?
You need to create an instance of ProcessStartInfo class, set the property WorkingDir and FileName (eventually also the Arguments property) and pass this instance to the Start static method or the Process class.
Dim pi = new ProcessStartInfo()
pi.WorkingDirectory = Path.GetDirectoryName(Application.ExecutablePath)
pi.FileName = "your_batch_file_name"
pi.Arguments = "arguments that you want to pass to the batch file"
Process.Start(pi)
Keep in mind that if you run from a CD then your current working directory is not writeable
i used this example to open a command prompt from within vb.net 2010
lnk to stackoverflow document
the command prompt opens as expected and i can do directories open commands like regedit etc. without an issue
but what i really want is tftp.exe when i look for it it does not show up, when doing a dir it is not listed when type tftp at command prompt i get the to recognzed command
when comparing to a normal command prompt by type cmd at the run line i can see it in the windows\system32 folder
also when i do a dir from normal command prompt and compare to dir from the cmd prompt opened by vb.net there is a 400+ number of files difference out of close to 3000 files
trying to find out why i cant see all the files here is the actul code i used
Private Sub Button30_Click(sender As System.Object, e As System.EventArgs) Handles Button30.Click
Dim command As String = "tftp -i 192.168.10.177 put test1.bin"
Dim arguments As String = ""
Dim permanent As Boolean = True
Dim p As Process = New Process()
Dim pi As ProcessStartInfo = New ProcessStartInfo()
pi.Arguments = " " + If(permanent = True, "/K", "/C") + " " + command + " " + arguments
pi.FileName = "cmd.exe"
p.StartInfo = pi
p.Start()
End Sub
This seems like a very convuluted approch you are taking, but to answer your question directly, you probably need to set the working directory like so:
pi.WorkingDirectory = "c:\windows\system32"
I have to say though, you might want to reconsider the whole approach of opening a DOS window for the user to type commands. Doesn't see very user friendly.
ok found the answer, it is becuase i am running 64bit windows and when its looking for the tftp.exe it is actually looking in the syswow64 directory and tftp.exe is not in that directory.
since i have this running and compiled for x86 and not 64bit here is the work around
Public Declare Function Wow64DisableWow64FsRedirection Lib "kernel32" (ByRef oldvalue As Long) As Boolean
then
Wow64DisableWow64FsRedirection(0)
after adding tthis to my code the tftp upload works flawlessly
Alright guys I have a copy of minecraft wich is a java program launched by Minecraft.exe.
Inside the same folder is my program (lets call it launcher.exe) wich I am programming in VB.net and a Folder called LocalAppData.
If I place a shortcut in the same folder as Minecraft.exe, clear the "start in" field and put this in the target field:
C:\Windows\System32\cmd.exe /c start cd LocalAppData&& set APPDATA=%cd%\LocalAppData&& javaw -Xms4096M -Xmx4096M -cp LocalAppData\Minecraft.exe net.minecraft.LauncherFrame
then minecraft launches with my custom memory allocation from inside the LocalAppData folder. Two command windows appear as well. One closes when minecraft does, but the other does not and needs to be closed by the user
My Question is: How do I acheive the same result in VB.net instead of with a windows shortcut and is there a way to either stop the command windows appearing or setting them both to close automatically?
My goal is to launch minecraft from a subfolder, so local filepaths would be far preferrable to global filepaths, but figuring out the location of the application at runtime and working from a subfolder would be ok as well.
I thought I would be able to use the same code inside a Shell() command to produce the same effect, but it appears not.
Ideally I want to create a program that runs minecraft with:
Custom memory allocation
Local filepaths so that it can be run portably
The appdata folder changed to the subfolder so that it can be run portably
Those command windows either gone or minimised and then close automatically when minecraft is closed by the user.
I know this is a big ask, but I'm 6 months into a programming course and I'll admit that I'm not the best programmer out there.
Once I know how to do this I can create the rest of the program that manages multiple installations in seperate subfolders and lets you choose wich one to launch, but I just need help with the actual launching of the java application itself.
Note:
I should clarify that Minecraft.exe is not something that I have made and that I don't program java. I'm just looking for a solution in VB.Net.
Thank you for reading all this and sorry for the long post.
Edit
Thank you for the help. This is what I have so far, but it produces an error "Error: Could not create the JavaVirtualMachine. Error: A fatal exception has occurred. Program will exit"
'Declare Processes
Dim appDataStartInfo As ProcessStartInfo = New ProcessStartInfo()
Dim javaStartInfo As ProcessStartInfo = New ProcessStartInfo()
Dim appPath As String = Application.StartupPath()
'Launch appdata relocation process
appDataStartInfo.FileName = "cmd.exe"
appDataStartInfo.Arguments = "/c start cd " & appPath & "&& set APPDATA=" & appPath & "\LocalAppData"
appDataStartInfo.UseShellExecute = True
Process.Start(appDataStartInfo)
'Launch Minecraft
javaStartInfo.FileName = "javaw.exe"
javaStartInfo.Arguments = "-Xms4096M -Xmx4096M -cp " & appPath & "\LocalAppData\.minecraft\bin\Minecraft.jar net.minecraft.LauncherFrame"
javaStartInfo.UseShellExecute = True
Process.Start(javaStartInfo)
Does anyone see where I've gone wrong?
The Process class (http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx )allows you to launch a process. You set it up with a ProcessStartInfo instance (http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.80).aspx ).
I don't have the time to give you all the details, but this pseudo-code should get you started :
Dim startInfo As ProcessStartInfo = new ProcessStartInfo()
startInfo.FileName = "javaw.exe" 'That's the name of your executable
startInfo.Arguments = "your argument line"
startInfo.UseShellExecute = true 'Needed to open a command window
Process.Start(startInfo)