How to find 64-bit process info using a 32-bit process - vb.net

I have a 32 bit application that shells a second application that can be 32 or 64-bit depending upon the computer it's running on.
I only want one instance of the second application to run at a time, and I need the first application to prevent the second from being launched more than once.
I want to be able to use GetProcessesByName to obtain the running processes. This seems to work fine. It's when I attempt to obtain the module data to find out what folder the second application was run from that things fall apart.
Does anyone have a suggestion for identifying 64-bit processes and their folder of origin from a 32-bit application?
Thank you,
SH

You can use the WMI API (System.Management namespace) for this, specifically the ManagementObjectSearcher. The example below shows to get the process id and full command line from all running notepad instances.
Imports System.Management
Module Module1
Sub Main()
Dim wmi = New ManagementObjectSearcher("SELECT ProcessId, CommandLine FROM Win32_Process WHERE CommandLine LIKE ""%notepad%""")
Dim result = wmi.Get().OfType(Of ManagementObject)()
For Each r In result
Console.WriteLine("Process ID: {0}, Command Line: {1}" r("ProcessId"), r("CommandLine"))
Next
End Sub
End Module

I think it could be easier if you set a Mutex when launching second app.
In main app you could do this: if Mutex doesn't exist you run second app (which creates Mutex when run and release it when closing), otherwise you skip...
EDITED:
You can't edit second app to insert the creation of a mutex, ok.
But you can do this in main app:
Create a background worker BackgroudWorker wrk
Set a private bool to true: bool running = false
Execute wrk when you want the new app run: if (running) return; running = true;
wrk creates a Process and waits for its end
when wrk ends running = false
Just an idea...
EDITED AGAIN:
If you close first app and reopen it, user is able to run second app again.
So you could do this:
Create a background worker BackgroudWorker wrk
Write a tmp file (on NTFS it can be empty)
Execute wrk when you want the new app run:
if your tmp file exists then exit;
wrk creates a Process and waits for its end
when wrk ends deletes tmp file
With this method, even if user quits your first app, tmp file remains on hdd; so when user runs first app again, second app will not be executed.
Remeber that if user is smart enough to undestand this, he could manully delete file and the trick is done.
Finally: are you sure user cannot run directly second app?

Related

using environment variables in excel

So I am using this code in excel to read environment parameters on startup:
Dim ExcelArgs As String
Dim arg As String
ExcelArgs = Environ("ExcelArgs")
MsgBox ExcelArgs
If InStr(UCase(ExcelArgs), "CREO") >= 0 Then
Application.DisplayAlerts = False
If Len(ExcelArgs) > Len("CREO") Then
arg = Split(ExcelArgs, ",")(1)
Call Creo.addNewPartToPartslist(arg)
End If
Application.DisplayAlerts = True
End If
and this line in my batch script:
echo "Launch excel"
Set "ExcelArgs=CREO,DXFWITHOUTDRW
"C:\Program Files (x86)\Microsoft Office\OFFICE16\Excel.exe" /r "%APPDATA%\Microsoft\Excel\XLSTART\PERSONAL.XLSB"
exit 0
The problem is that if i run the batch file once, keep excel open change the excelargs to CREO,wqhatever in batch file and rerun batch file the excelargs, dos not get updated!!!
So my theory is that excel either caches out the environment variable or that if it is being used by one instance the batch script can not set it
link with some info about passing arguments to excel:
https://superuser.com/questions/640359/bat-file-to-open-excel-with-parameters-spaces
Usually excel sees if there is a previous instance running and let this instance handle the file opening.
Is this important? Yes, in your case both requests to open the file are handled by the same excel process.
How does it make a difference? Environment variables are not shared. Each process has it own environment block that is initialized when the process is created (can be a customized block or a copy of the environment of the parent process) and once the environment is created for a process, only this process can change its environment.
In your case, when you start excel the new process gets a copy of the environment block of the cmd process. Later, when you change the cmd environment, the already running excel instance sees no changes in environment and, as the new request to open excel is converted to a request to the previous process, there is not a new process with a new copy of the cmd environment with the changes.
The only way I see to make it work is to force excel to start a new process (that will inherit the changes in the cmd instance) instead of reusing the previous one.
But this depends on the excel version. As far as I know, the 2013 version includes an /x switch to force separate process usage. For previous versions, maybe this question, or this one could help you.
Excel is open
Then i start the batch script:
The it does not open it as read only by default, but prompt me instead, not a big issue but a bit annoying, and it also make it impossible to loop through to run the batch several times for different input parameters.
A bit unsure how I should post this, couldnt paste images in comments, and to edit the the original question, which was how to start excel with enviroment variable in new instance (/x did the trick), but now /r does not work, Should I post as new question and refer to this one or can I leave it as an answer?

Preventing Scheduled Agent from executing when modified

I have a scheduled agent that runs Weekly at one particular time on a target of All new & modified documents.
If I modify this agent, even if I only save it, it runs again.
If I remember correctly from long long ago, I have to add code such as this:
Dim db As NotesDatabase
Dim agent As NotesAgent
Set db = s.CurrentDatabase
Set agent = db.GetAgent("myAgent")
If agent.HasRunSinceModified = False
Exit Sub
End If
Am I remembering correctly? And I always wondered, why would an agent fire off after being modified? Makes no sense to me.
My response corresponds to your title: Preventing Scheduled Agent from executing when modified.
The solution is to move all your code to a script library, and never change the agent (since no need of it).
When you modify your code in the script library the agent is not fired.
You can also read Notes Designer runs agent after saving which suggest (I didn't test) Amgr_SkipPriorDailyScheduledRuns=1

vb.net MS Word crash cleanup

I have a program that takes a template .docx file and populates it with data, saving a copy afterwards. The program itself works fine and I got a nice try..catch in main sub in case something fails, so the file is closed regardless.
The problem is that if it crashes completely, i.e. is forced to close (or manually force closed if it hangs), it will keep the process running with the opened template, so next time it;s launched, you'll get the read only error when trying to open it.
So the question: Is there a way to clean up afterwards, without having to end process via task manager? Or maybe a way of opening it without locking it out? Making a temp copy maybe?
Fixed with this:
Sub KillUnusedWordProcess()
Dim oXlProcess As Process() = Process.GetProcessesByName("Winword")
For Each oXLP As Process In oXlProcess
If Len(oXLP.MainWindowTitle) = 0 Then
oXLP.Kill()
End If
Next
End Sub

VB: Encapsulating an Application Object with a Process

I am starting an external application from Visual Basic to perform CPU and memory intensive computations. The code more or less looks like the following:
gApp = New CANoe.ApplicationgApp = New CANoe.Application
While gApp Is Nothing 'wait until CANoe started
Threading.Thread.Sleep(100)
End While
gApp.Open(canoeConfigFile, False, False)
gApp.Configuration.OfflineSetup.Source = dataFile
gMeasurement.Start()
While (gMeasurement.Running)
Threading.Thread.Sleep(1000)
End While
gApp.Quit()
Would it be possible to encapsulate the above code into a process? I am ultematelly looking for something like:
Dim canoeProcess As New Process
canoeProcess.StartInfo.FileName = "C:\Program Files (x86)\Vector CANoe 8.1\Exec32\CANoe32.exe"
canoeProcess.Start()
gApp = canoeProcess.Application
...
' (the code continues as the above)
...
The reason why I want to encapusalte the application into the process is that (i) I want to run muliple instances of the executable with different dataFiles as jobs and (ii) in case the canoe software hangs or does something weird I'd like to be able to kill the process from the VB application.
Is it possible to achieve the reverse? I.e., giving gApp Application object (that is running) to get its Process ID?
Any comments?
I believe the answer is that it is not possible. I am requesting the resources through the Windows COM interface and encapsulating it into a process might be even impossible (maybe a process does not exist at all)

An issue with reading DB when program runs at startup in vb.net

I'm new here and to vb.net and I'm stuck on something that I feel SHOULD be simple to resolve. I setup my program to let the user decide if he or she wants to have the program run at windows start. It actually works fine as it is assigning the registry value to CurrentUser instead of Local Machine because of admin rights needing to be bypassed. However, when I restart my computer the program comes up like normal, but it will not read my access db that is located in the same folder as the program; it tries to read the DB from Windows\System32.
Is there a way to force it to read from the executablepath instead of System32?
Here is my simple code:
Private Sub startup()
If cbStartup.Checked = True Then
My.Computer.Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", True).SetValue("CC_List", System.Windows.Forms.Application.ExecutablePath)
ElseIf cbStartup.Checked = False Then
My.Computer.Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Run", True).DeleteValue("CC_List", False)
End If
End Sub
So when the O/S starts your program the Current Directory is %windir%\System32.
You need to either adjust all your existing paths to be explicitly relative to Application.ExecutablePath, or put
My.Computer.FileSystem.CurrentDirectory = My.Application.Info.DirectoryPath
at the start of your program (which is the modern version of ChDir ...).