fbpx
Welcome, Guest
Username: Password: Remember me
Share your code snippets, screen shots etc. here
  • Page:
  • 1

TOPIC: Executable started from the IDE

Executable started from the IDE 2 years 2 weeks ago #1

  • wriedmann
  • wriedmann's Avatar Topic Author
  • Offline
  • Posts: 1423
  • Karma: 6
For me one of the important functions in Visual Objects is
IsStartedFromIDE()

I'm using this for special debugging output or other specific behavior.
Unfortunately this is not so easy in X# as there is no special executable when started from XIDE or Visual Studio.

The solution is to check whether the executable was started from XIDE or devenv (Visual Studio's executable).

This is the code (and you'll find a complete XIDE export attached to this message):
// Source (C#):
// http://stackoverflow.com/questions/2531837/how-can-i-get-the-pid-of-the-parent-process-of-my-application
// translated to X# and adapted by Wolfgang Riedmann wolfgang@riedmann.it 

using System
using System.Diagnostics
using System.Management

function Start( ) as void          
  local oProcess as Process
  local oParent  as Process
  local nId      as int
	
  oProcess := Process.GetCurrentProcess()
  nId := oProcess:Id
  oParent := ProcessUtil.GetParentProcess( nId )
  if oParent != null                            
    if oParent:ProcessName:Tolower() == "cmd"
      oParent := ProcessUtil.GetParentProcess( oParent:Id )
    endif
    if oParent:ProcessName:ToLower() == "xide"
      System.Console.WriteLine( String.Format( "Executable was launched from development environment {0}", oParent:ProcessName ) )
    else
      System.Console.WriteLine( String.Format( "Executable was launched by {0}", oParent:ProcessName ) )
    endif
  else
    System.Console.WriteLine( "No parent process!" ) 
  endif 
	
  return
	
static class ProcessUtil
	
static method GetParentProcess( nProcessId as int ) as Process
  local oParent as Process
  local nParentId as dword
  local cQuery as string
  local oSearch as ManagementObjectSearcher 
  local oResults as ManagementObjectCollection
  local oEnumerator as ManagementObjectCollection.ManagementObjectEnumerator 
  local oQueryObj as ManagementBaseObject

  oParent := null
	
  try

  cQuery := String.Format( "SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", nProcessId )
  oSearch := ManagementObjectSearcher{ "root\CIMV2", cQuery }
  oResults := oSearch:Get()
  oEnumerator := oResults:GetEnumerator()
  oEnumerator:MoveNext()       
  oQueryObj := oEnumerator:Current
  nParentId := ( dword ) oQueryObj["ParentProcessId"]
  if nParentId > 0
    oParent				:= Process.GetProcessById( int( nParentId ) )
  endif 
	
  catch oEx as Exception
		
  Debug.WriteLine( String.Format( e"Error occurred: {0} \n{1}", oEx:Message, oEx:StackTrace ) )
	
  end try
	
  return oParent
	
end class

File Attachment:

File Name: IsStartedFromIDE.zip
File Size:2 KB
Wolfgang Riedmann
Meran, South Tyrol, Italy
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it
Attachments:

Please Log in or Create an account to join the conversation.

Executable started from the IDE 2 years 2 weeks ago #2

  • robert
  • robert's Avatar
  • Away
  • Posts: 844
  • Karma: 6
Wolfgang,

What about:

System.Diagnostics.Debugger:IsAttached

Robert
XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

Executable started from the IDE 2 years 2 weeks ago #3

  • wriedmann
  • wriedmann's Avatar Topic Author
  • Offline
  • Posts: 1423
  • Karma: 6
Hi Robert,

at least in XIDE this works only when I'm debugging and not when I'm running normally from the IDE. I haven't tested it in Visual Studio.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it

Please Log in or Create an account to join the conversation.

Last edit: by wriedmann.

Executable started from the IDE 2 years 2 weeks ago #4

Hi Wolfgang,

Very interesting piece of code...I had no idea about this functionality.
Thanks for sharing!

Chris
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

Executable started from the IDE 1 year 6 months ago #5

  • wriedmann
  • wriedmann's Avatar Topic Author
  • Offline
  • Posts: 1423
  • Karma: 6
Hi,

sometimes in the last weeks my code to detect if my executables were started from the IDE stopped working - I suspect Microsoft has changed something in the WMI interface to fix a security issue.

So I had to change the implementation of the GetParentProcess() function.

The new code is the following:
using System.Diagnostics
using System.Management

static class Utility
	
static method GetParentProcess( nId as dword ) as Process
  local nParentId as dword
  local oHandle as IntPtr
  local oProcInfo as WindowsAPI.PROCESSENTRY32
  local oReturn as Process

  nParentId := 0	
  oReturn := null
  oHandle := WindowsAPI.CreateToolhelp32Snapshot( WindowsAPI.TH32CS_SNAPPROCESS, nId )
  if oHandle != IntPtr.Zero
    oProcInfo := WindowsAPI.PROCESSENTRY32{}
    oProcInfo.dwSize := dword( System.Runtime.InteropServices.Marshal.SizeOf( typeof( WindowsAPI.PROCESSENTRY32 ) ) )
    if WindowsAPI.Process32First( oHandle, oProcInfo ) 
      while nId != oProcInfo.th32ProcessID .and. WindowsAPI.Process32Next( oHandle, oProcInfo )
      end
      if nId == oProcInfo.th32ProcessID
        nParentId := oProcInfo.th32ParentProcessID 
      endif
    endif
  endif 
  if nParentId != 0
    oReturn := Process.GetProcessById( nParentId )  
  endif

   return oReturn
using System.Runtime.InteropServices

static class WindowsAPI
	
[DllImport("kernel32.dll",SetLastError:= true,EntryPoint:="CreateToolhelp32Snapshot")];
static method CreateToolhelp32Snapshot( dwFlags as dword, th32ProcessID as dword ) as IntPtr
 
[DllImport("kernel32.dll",EntryPoint:="Process32First")];
static method Process32First( hSnapshot as IntPtr, oEntry ref PROCESSENTRY32 ) as logic
 
[DllImport("kernel32.dll",EntryPoint:="Process32Next")];
static method Process32Next( hSnapshot as IntPtr, oEntry ref PROCESSENTRY32 ) as logic

[StructLayout(LayoutKind.Sequential)];
structure PROCESSENTRY32 
  dwSize as dword
  cntUsage as dword
  th32ProcessID as dword
  th32DefaultHeapID as IntPtr
  th32ModuleID as dword
  cntThreads as dword
  th32ParentProcessID as dword
  pcPriClassBase as int
  dwFlags as dword
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst:=260)] szExeFile as string       
  // requires /unsafe compiler switch to compile
  // unsafe FIXED dim szExeFile[260] as byte 
end structure

static property TH32CS_SNAPPROCESS as dword get winTH32CS_SNAPPROCESS

end class

static define winTH32CS_SNAPPROCESS := 2 as dword

You can find a complete (working) sample together with the old WMI based function here:

https://riedmann.it/download/StartedFromIDE.viaef

and attached to this message.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
This email address is being protected from spambots. You need JavaScript enabled to view it.
www.riedmann.it - docs.xsharp.it
Attachments:

Please Log in or Create an account to join the conversation.

  • Page:
  • 1