Brain fart... How to run .EXE from within code?

  • Thread starter Thread starter Sacha Korell
  • Start date Start date
S

Sacha Korell

I've got a brain fart. How do you start an executable from within your CF
code? In "normal" Windows (even .NET) I would use the Shell("PathName")
command, but that doesn't seem to be available, at least not in the Compact
Framework.

Any ideas?

Thnaks,

Sacha
 
#region StartProcess
/// <summary>
///
/// GetLastError -- Used to return last error
///
/// </summary>

[DllImport("CoreDll")]
public extern static Int32 GetLastError();

/// <summary>
///
/// CreateProcess -- Used to instantiate another program
///
/// </summary>

public class ProcessInfo
{
public IntPtr hProcess = IntPtr.Zero;
public IntPtr hThread = IntPtr.Zero;
public Int32 dwProcessId = 0;
public Int32 dwThreadId = 0;
};
[DllImport("CoreDll", SetLastError=true)]
private extern static int CreateProcess( String imageName
, String cmdLine
, IntPtr lpProcessAttributes
, IntPtr lpThreadAttributes
, Int32 boolInheritHandles
, Int32 dwCreationFlags
, IntPtr lpEnvironment
, IntPtr lpszCurrentDir
, IntPtr si
, ProcessInfo pi );

public static bool CreateProcess( String ExeName, String CmdLine)
{
ProcessInfo pi = new ProcessInfo();
return CreateProcess(ExeName
, CmdLine
, IntPtr.Zero
, IntPtr.Zero
, 0
, 0
, IntPtr.Zero
, IntPtr.Zero
, IntPtr.Zero
, pi) != 0;
}
#endregion
 
Chris,

Thanks...I never actually used GetLastError(), so you probably saved me from an error down the road! This was code that I used from a posting months ago when the forums were still IDSS forums (from someone with the user name ctacke, posting was referenced by Ginny (http://www.opennetcf.org/forums/topic.asp?TOPIC_ID=63), hmmm :-) . In any case, I'm glad to know the proper methodology.

Oh, and thanks for the help the other day on getting set up to contribute to the OpenNETCF effort...


Mark,

You shouldn't P/Invoke GetLastError as it may return an error set by the framework and not the actual API called. Instead use Marshal.GetLastWin32Error()

--
Chris Tacke, eMVP
Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

#region StartProcess
/// <summary>
///
/// GetLastError -- Used to return last error
///
/// </summary>

[DllImport("CoreDll")]
public extern static Int32 GetLastError();

/// <summary>
///
/// CreateProcess -- Used to instantiate another program
///
/// </summary>

public class ProcessInfo
{
public IntPtr hProcess = IntPtr.Zero;
public IntPtr hThread = IntPtr.Zero;
public Int32 dwProcessId = 0;
public Int32 dwThreadId = 0;
};
[DllImport("CoreDll", SetLastError=true)]
private extern static int CreateProcess( String imageName
, String cmdLine
, IntPtr lpProcessAttributes
, IntPtr lpThreadAttributes
, Int32 boolInheritHandles
, Int32 dwCreationFlags
, IntPtr lpEnvironment
, IntPtr lpszCurrentDir
, IntPtr si
, ProcessInfo pi );

public static bool CreateProcess( String ExeName, String CmdLine)
{
ProcessInfo pi = new ProcessInfo();
return CreateProcess(ExeName
, CmdLine
, IntPtr.Zero
, IntPtr.Zero
, 0
, 0
, IntPtr.Zero
, IntPtr.Zero
, IntPtr.Zero
, pi) != 0;
}
#endregion
 
Thanks everybody,

Now I just have to "translate" the code to VB.NET ;-)

Sacha


#region StartProcess
/// <summary>
///
/// GetLastError -- Used to return last error
///
/// </summary>

[DllImport("CoreDll")]
public extern static Int32 GetLastError();

/// <summary>
///
/// CreateProcess -- Used to instantiate another program
///
/// </summary>

public class ProcessInfo
{
public IntPtr hProcess = IntPtr.Zero;
public IntPtr hThread = IntPtr.Zero;
public Int32 dwProcessId = 0;
public Int32 dwThreadId = 0;
};
[DllImport("CoreDll", SetLastError=true)]
private extern static int CreateProcess( String imageName
, String cmdLine
, IntPtr lpProcessAttributes
, IntPtr lpThreadAttributes
, Int32 boolInheritHandles
, Int32 dwCreationFlags
, IntPtr lpEnvironment
, IntPtr lpszCurrentDir
, IntPtr si
, ProcessInfo pi );

public static bool CreateProcess( String ExeName, String CmdLine)
{
ProcessInfo pi = new ProcessInfo();
return CreateProcess(ExeName
, CmdLine
, IntPtr.Zero
, IntPtr.Zero
, 0
, 0
, IntPtr.Zero
, IntPtr.Zero
, IntPtr.Zero
, pi) != 0;
}
#endregion
 
Hence the reason I'm familiar with the reasons you should *not* P/Invoke it :)
Live and learn I guess.

--
Chris Tacke, eMVP
Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

Chris,

Thanks...I never actually used GetLastError(), so you probably saved me from an error down the road! This was code that I used from a posting months ago when the forums were still IDSS forums (from someone with the user name ctacke, posting was referenced by Ginny (http://www.opennetcf.org/forums/topic.asp?TOPIC_ID=63), hmmm :-) . In any case, I'm glad to know the proper methodology.

Oh, and thanks for the help the other day on getting set up to contribute to the OpenNETCF effort...


Mark,

You shouldn't P/Invoke GetLastError as it may return an error set by the framework and not the actual API called. Instead use Marshal.GetLastWin32Error()

--
Chris Tacke, eMVP
Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

#region StartProcess
/// <summary>
///
/// GetLastError -- Used to return last error
///
/// </summary>

[DllImport("CoreDll")]
public extern static Int32 GetLastError();

/// <summary>
///
/// CreateProcess -- Used to instantiate another program
///
/// </summary>

public class ProcessInfo
{
public IntPtr hProcess = IntPtr.Zero;
public IntPtr hThread = IntPtr.Zero;
public Int32 dwProcessId = 0;
public Int32 dwThreadId = 0;
};
[DllImport("CoreDll", SetLastError=true)]
private extern static int CreateProcess( String imageName
, String cmdLine
, IntPtr lpProcessAttributes
, IntPtr lpThreadAttributes
, Int32 boolInheritHandles
, Int32 dwCreationFlags
, IntPtr lpEnvironment
, IntPtr lpszCurrentDir
, IntPtr si
, ProcessInfo pi );

public static bool CreateProcess( String ExeName, String CmdLine)
{
ProcessInfo pi = new ProcessInfo();
return CreateProcess(ExeName
, CmdLine
, IntPtr.Zero
, IntPtr.Zero
, 0
, 0
, IntPtr.Zero
, IntPtr.Zero
, IntPtr.Zero
, pi) != 0;
}
#endregion
 
Not bad, thanks!

It actually helped me find a bug in my "translation" that was driving me
nuts with a "Native Exception occured".

Thanks,

Sacha
 
Sorry that message escaped when I wasn't looking. What I was going to ask
was, which of the 3 execute methods is the best. I assume it depeneds on
exact needs but I'm not sure why one method might be better than another.
The 3 methods being ShellExecute, CreateProcess and ExecuteAssembly.

John.
 
Back
Top