mirror of
https://github.com/cyanfish/naps2.git
synced 2024-10-04 11:27:08 +03:00
Working host process (including auto termination)
This commit is contained in:
parent
3da97ca455
commit
c773054558
@ -233,6 +233,7 @@
|
||||
<Compile Include="Operation\OperationErrorEventArgs.cs" />
|
||||
<Compile Include="Operation\OperationStatus.cs" />
|
||||
<Compile Include="Util\Pipes.cs" />
|
||||
<Compile Include="Util\ProcessJob.cs" />
|
||||
<Compile Include="ImportExport\DirectImageTransfer.cs" />
|
||||
<Compile Include="Util\StillImage.cs" />
|
||||
<Compile Include="Util\StringWrapper.cs" />
|
||||
|
139
NAPS2.Core/Util/ProcessJob.cs
Normal file
139
NAPS2.Core/Util/ProcessJob.cs
Normal file
@ -0,0 +1,139 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace NAPS2.Util
|
||||
{
|
||||
public class Job : IDisposable
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
static extern IntPtr CreateJobObject(IntPtr a, string lpName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
private IntPtr handle;
|
||||
private bool disposed;
|
||||
|
||||
public Job()
|
||||
{
|
||||
handle = CreateJobObject(IntPtr.Zero, null);
|
||||
|
||||
var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
|
||||
{
|
||||
LimitFlags = 0x2000
|
||||
};
|
||||
|
||||
var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
|
||||
{
|
||||
BasicLimitInformation = info
|
||||
};
|
||||
|
||||
int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
|
||||
IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
|
||||
Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
|
||||
|
||||
if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
|
||||
throw new Exception(string.Format("Unable to set information. Error: {0}", Marshal.GetLastWin32Error()));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
if (disposing) { }
|
||||
|
||||
Close();
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
CloseHandle(handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public bool AddProcess(IntPtr processHandle)
|
||||
{
|
||||
return AssignProcessToJobObject(handle, processHandle);
|
||||
}
|
||||
|
||||
public bool AddProcess(int processId)
|
||||
{
|
||||
return AddProcess(Process.GetProcessById(processId).Handle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct IO_COUNTERS
|
||||
{
|
||||
public UInt64 ReadOperationCount;
|
||||
public UInt64 WriteOperationCount;
|
||||
public UInt64 OtherOperationCount;
|
||||
public UInt64 ReadTransferCount;
|
||||
public UInt64 WriteTransferCount;
|
||||
public UInt64 OtherTransferCount;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct JOBOBJECT_BASIC_LIMIT_INFORMATION
|
||||
{
|
||||
public Int64 PerProcessUserTimeLimit;
|
||||
public Int64 PerJobUserTimeLimit;
|
||||
public UInt32 LimitFlags;
|
||||
public UIntPtr MinimumWorkingSetSize;
|
||||
public UIntPtr MaximumWorkingSetSize;
|
||||
public UInt32 ActiveProcessLimit;
|
||||
public UIntPtr Affinity;
|
||||
public UInt32 PriorityClass;
|
||||
public UInt32 SchedulingClass;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
public UInt32 nLength;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
public Int32 bInheritHandle;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
|
||||
{
|
||||
public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
|
||||
public IO_COUNTERS IoInfo;
|
||||
public UIntPtr ProcessMemoryLimit;
|
||||
public UIntPtr JobMemoryLimit;
|
||||
public UIntPtr PeakProcessMemoryUsed;
|
||||
public UIntPtr PeakJobMemoryUsed;
|
||||
}
|
||||
|
||||
public enum JobObjectInfoType
|
||||
{
|
||||
AssociateCompletionPortInformation = 7,
|
||||
BasicLimitInformation = 2,
|
||||
BasicUIRestrictions = 4,
|
||||
EndOfJobTimeInformation = 6,
|
||||
ExtendedLimitInformation = 9,
|
||||
SecurityLimitInformation = 5,
|
||||
GroupInformation = 11
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ServiceModel;
|
||||
using System.Text;
|
||||
|
||||
@ -11,7 +12,7 @@ namespace NAPS2.Util
|
||||
{
|
||||
public static class X86HostManager
|
||||
{
|
||||
private const string PIPE_NAME_FORMAT = "net.pipe://localhost/NAPS2_32/{0}/x86host";
|
||||
public const string PIPE_NAME_FORMAT = "net.pipe://localhost/NAPS2_32/{0}/x86host";
|
||||
|
||||
private static Process _hostProcess;
|
||||
private static string _pipeName;
|
||||
@ -34,8 +35,12 @@ namespace NAPS2.Util
|
||||
{
|
||||
Log.Error("Could not start 32-bit host process; terminating.");
|
||||
Environment.Exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
var job = new Job();
|
||||
job.AddProcess(_hostProcess.Handle);
|
||||
|
||||
_channelFactory = new Lazy<ChannelFactory<IX86HostService>>(
|
||||
() => new ChannelFactory<IX86HostService>(new NetNamedPipeBinding(), new EndpointAddress(_pipeName)));
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@ -9,7 +10,7 @@ namespace NAPS2.Util
|
||||
{
|
||||
public void DoWork()
|
||||
{
|
||||
MessageBox.Show("Hi!");
|
||||
MessageBox.Show("Hi from " + Process.GetCurrentProcess().Id + "!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,10 +11,5 @@
|
||||
</behavior>
|
||||
</serviceBehaviors>
|
||||
</behaviors>
|
||||
<services>
|
||||
<service name="NAPS2.Util.X86HostService">
|
||||
<endpoint address="x86host" binding="netNamedPipeBinding" contract="NAPS2.Util.IX86HostService" />
|
||||
</service>
|
||||
</services>
|
||||
</system.serviceModel>
|
||||
</configuration>
|
||||
|
@ -8,10 +8,21 @@ namespace NAPS2_32
|
||||
{
|
||||
public class BackgroundForm : Form
|
||||
{
|
||||
public BackgroundForm()
|
||||
private readonly string pipeName;
|
||||
|
||||
public BackgroundForm(string pipeName)
|
||||
{
|
||||
this.pipeName = pipeName;
|
||||
WindowState = FormWindowState.Minimized;
|
||||
ShowInTaskbar = false;
|
||||
|
||||
Load += BackgroundForm_Load;
|
||||
}
|
||||
|
||||
void BackgroundForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
MessageBox.Show("Listening at " + pipeName);
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
<WcfConfigValidationEnabled>True</WcfConfigValidationEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
|
@ -11,18 +11,19 @@ namespace NAPS2_32
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
private const string PIPE_BASE_ADDR_FORMAT = "net.pipe://localhost/NAPS2_32/{0}/";
|
||||
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
var pipeBaseAddr = new Uri(string.Format(PIPE_BASE_ADDR_FORMAT, Process.GetCurrentProcess().Id));
|
||||
var host = new ServiceHost(typeof(X86HostService), pipeBaseAddr);
|
||||
host.Open();
|
||||
using (var host = new ServiceHost(typeof (X86HostService)))
|
||||
{
|
||||
string pipeName = string.Format(X86HostManager.PIPE_NAME_FORMAT, Process.GetCurrentProcess().Id);
|
||||
host.AddServiceEndpoint(typeof (IX86HostService), new NetNamedPipeBinding(), pipeName);
|
||||
host.Open();
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new BackgroundForm());
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new BackgroundForm(pipeName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user