When using OpenSeeLauncher with pinvoke, it will now log process output to log files.
This commit is contained in:
parent
e157e9d5c9
commit
7de50b2e25
2 changed files with 217 additions and 22 deletions
|
|
@ -9,6 +9,185 @@ namespace OpenSee {
|
|||
|
||||
public class OpenSeeProcessInterface {
|
||||
#region DllImport
|
||||
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
|
||||
private static extern IntPtr CreateFile(
|
||||
string lpFileName,
|
||||
EFileAccess dwDesiredAccess,
|
||||
EFileShare dwShareMode,
|
||||
SECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
ECreationDisposition dwCreationDisposition,
|
||||
EFileAttributes dwFlagsAndAttributes,
|
||||
IntPtr hTemplateFile
|
||||
);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
public int nLength;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
public int bInheritHandle;
|
||||
}
|
||||
|
||||
[Flags]
|
||||
enum EFileAccess : uint {
|
||||
//
|
||||
// Standart Section
|
||||
//
|
||||
|
||||
AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type
|
||||
MaximumAllowed = 0x2000000, // MaximumAllowed access type
|
||||
|
||||
Delete = 0x10000,
|
||||
ReadControl = 0x20000,
|
||||
WriteDAC = 0x40000,
|
||||
WriteOwner = 0x80000,
|
||||
Synchronize = 0x100000,
|
||||
|
||||
StandardRightsRequired = 0xF0000,
|
||||
StandardRightsRead = ReadControl,
|
||||
StandardRightsWrite = ReadControl,
|
||||
StandardRightsExecute = ReadControl,
|
||||
StandardRightsAll = 0x1F0000,
|
||||
SpecificRightsAll = 0xFFFF,
|
||||
|
||||
FILE_READ_DATA = 0x0001, // file & pipe
|
||||
FILE_LIST_DIRECTORY = 0x0001, // directory
|
||||
FILE_WRITE_DATA = 0x0002, // file & pipe
|
||||
FILE_ADD_FILE = 0x0002, // directory
|
||||
FILE_APPEND_DATA = 0x0004, // file
|
||||
FILE_ADD_SUBDIRECTORY = 0x0004, // directory
|
||||
FILE_CREATE_PIPE_INSTANCE = 0x0004, // named pipe
|
||||
FILE_READ_EA = 0x0008, // file & directory
|
||||
FILE_WRITE_EA = 0x0010, // file & directory
|
||||
FILE_EXECUTE = 0x0020, // file
|
||||
FILE_TRAVERSE = 0x0020, // directory
|
||||
FILE_DELETE_CHILD = 0x0040, // directory
|
||||
FILE_READ_ATTRIBUTES = 0x0080, // all
|
||||
FILE_WRITE_ATTRIBUTES = 0x0100, // all
|
||||
|
||||
//
|
||||
// Generic Section
|
||||
//
|
||||
|
||||
GenericRead = 0x80000000,
|
||||
GenericWrite = 0x40000000,
|
||||
GenericExecute = 0x20000000,
|
||||
GenericAll = 0x10000000,
|
||||
|
||||
SPECIFIC_RIGHTS_ALL = 0x00FFFF,
|
||||
FILE_ALL_ACCESS =
|
||||
StandardRightsRequired |
|
||||
Synchronize |
|
||||
0x1FF,
|
||||
|
||||
FILE_GENERIC_READ =
|
||||
StandardRightsRead |
|
||||
FILE_READ_DATA |
|
||||
FILE_READ_ATTRIBUTES |
|
||||
FILE_READ_EA |
|
||||
Synchronize,
|
||||
|
||||
FILE_GENERIC_WRITE =
|
||||
StandardRightsWrite |
|
||||
FILE_WRITE_DATA |
|
||||
FILE_WRITE_ATTRIBUTES |
|
||||
FILE_WRITE_EA |
|
||||
FILE_APPEND_DATA |
|
||||
Synchronize,
|
||||
|
||||
FILE_GENERIC_EXECUTE =
|
||||
StandardRightsExecute |
|
||||
FILE_READ_ATTRIBUTES |
|
||||
FILE_EXECUTE |
|
||||
Synchronize
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum EFileShare : uint
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
None = 0x00000000,
|
||||
/// <summary>
|
||||
/// Enables subsequent open operations on an object to request read access.
|
||||
/// Otherwise, other processes cannot open the object if they request read access.
|
||||
/// If this flag is not specified, but the object has been opened for read access, the function fails.
|
||||
/// </summary>
|
||||
Read = 0x00000001,
|
||||
/// <summary>
|
||||
/// Enables subsequent open operations on an object to request write access.
|
||||
/// Otherwise, other processes cannot open the object if they request write access.
|
||||
/// If this flag is not specified, but the object has been opened for write access, the function fails.
|
||||
/// </summary>
|
||||
Write = 0x00000002,
|
||||
/// <summary>
|
||||
/// Enables subsequent open operations on an object to request delete access.
|
||||
/// Otherwise, other processes cannot open the object if they request delete access.
|
||||
/// If this flag is not specified, but the object has been opened for delete access, the function fails.
|
||||
/// </summary>
|
||||
Delete = 0x00000004
|
||||
}
|
||||
|
||||
public enum ECreationDisposition : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new file. The function fails if a specified file exists.
|
||||
/// </summary>
|
||||
New = 1,
|
||||
/// <summary>
|
||||
/// Creates a new file, always.
|
||||
/// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
|
||||
/// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
|
||||
/// </summary>
|
||||
CreateAlways = 2,
|
||||
/// <summary>
|
||||
/// Opens a file. The function fails if the file does not exist.
|
||||
/// </summary>
|
||||
OpenExisting = 3,
|
||||
/// <summary>
|
||||
/// Opens a file, always.
|
||||
/// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
|
||||
/// </summary>
|
||||
OpenAlways = 4,
|
||||
/// <summary>
|
||||
/// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
|
||||
/// The calling process must open the file with the GENERIC_WRITE access right.
|
||||
/// </summary>
|
||||
TruncateExisting = 5
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum EFileAttributes : uint
|
||||
{
|
||||
Readonly = 0x00000001,
|
||||
Hidden = 0x00000002,
|
||||
System = 0x00000004,
|
||||
Directory = 0x00000010,
|
||||
Archive = 0x00000020,
|
||||
Device = 0x00000040,
|
||||
Normal = 0x00000080,
|
||||
Temporary = 0x00000100,
|
||||
SparseFile = 0x00000200,
|
||||
ReparsePoint = 0x00000400,
|
||||
Compressed = 0x00000800,
|
||||
Offline = 0x00001000,
|
||||
NotContentIndexed= 0x00002000,
|
||||
Encrypted = 0x00004000,
|
||||
Write_Through = 0x80000000,
|
||||
Overlapped = 0x40000000,
|
||||
NoBuffering = 0x20000000,
|
||||
RandomAccess = 0x10000000,
|
||||
SequentialScan = 0x08000000,
|
||||
DeleteOnClose = 0x04000000,
|
||||
BackupSemantics = 0x02000000,
|
||||
PosixSemantics = 0x01000000,
|
||||
OpenReparsePoint = 0x00200000,
|
||||
OpenNoRecall = 0x00100000,
|
||||
FirstPipeInstance= 0x00080000
|
||||
}
|
||||
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError=true)]
|
||||
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
|
||||
const UInt32 INFINITE = 0xFFFFFFFF;
|
||||
|
|
@ -122,16 +301,32 @@ public class OpenSeeProcessInterface {
|
|||
}
|
||||
#endregion
|
||||
|
||||
public static uint Start(string exePath, string commandline, string dir, bool hidden, out IntPtr handle)
|
||||
public static uint Start(string exePath, string commandline, string dir, bool hidden, string outputLog, string errorLog, out IntPtr handle, out IntPtr handleStdOut, out IntPtr handleStdErr)
|
||||
{
|
||||
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
|
||||
sa.nLength = Marshal.SizeOf<SECURITY_ATTRIBUTES>();
|
||||
sa.lpSecurityDescriptor = IntPtr.Zero;
|
||||
sa.bInheritHandle = 1;
|
||||
|
||||
handle = IntPtr.Zero;
|
||||
handleStdOut = IntPtr.Zero;
|
||||
handleStdErr = IntPtr.Zero;
|
||||
if (outputLog != null)
|
||||
handleStdOut = CreateFile(outputLog, EFileAccess.FILE_WRITE_DATA, EFileShare.Read | EFileShare.Write, sa, ECreationDisposition.CreateAlways, EFileAttributes.Normal, IntPtr.Zero);
|
||||
if (errorLog != null)
|
||||
handleStdErr = CreateFile(errorLog, EFileAccess.FILE_WRITE_DATA, EFileShare.Read | EFileShare.Write, sa, ECreationDisposition.CreateAlways, EFileAttributes.Normal, IntPtr.Zero);
|
||||
|
||||
ProcessCreationFlags flags = hidden ? ProcessCreationFlags.CREATE_NO_WINDOW : ProcessCreationFlags.NONE;
|
||||
STARTUPINFO startupinfo = new STARTUPINFO
|
||||
{
|
||||
cb = (uint)Marshal.SizeOf<STARTUPINFO>()
|
||||
cb = (uint)Marshal.SizeOf<STARTUPINFO>(),
|
||||
dwFlags = 0x00000100,
|
||||
hStdInput = IntPtr.Zero,
|
||||
hStdOutput = handleStdOut,
|
||||
hStdError = handleStdErr
|
||||
};
|
||||
PROCESS_INFORMATION processinfo = new PROCESS_INFORMATION();
|
||||
if (!CreateProcessW(exePath, commandline, IntPtr.Zero, IntPtr.Zero, false, flags, IntPtr.Zero, dir, ref startupinfo, ref processinfo))
|
||||
if (!CreateProcessW(exePath, commandline, IntPtr.Zero, IntPtr.Zero, true, flags, IntPtr.Zero, dir, ref startupinfo, ref processinfo))
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue