Вот один из подходов, который может сработать для вас. Вы можете подписать пусковая сборка:
И тогда вы могли бы сделать так, чтобы ваш ребенок приложения будет прекращено, если они не запускались из приложения запуска.
Ниже приведен код для вашего приложения (-ей) для детей, которое использует the Windows API NtQueryInformationProcess function. Он получает родительский процесс, сначала получив свой идентификатор процесса через GetParentProcessID
, затем загружает сборку из этого процесса и получает полное (то есть «сильное») имя, которое содержит ваш открытый ключ.
[System.Runtime.InteropServices.DllImport("ntdll.dll")]
private static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref NtQueryInformationProcessProcessInformation processInformation, int processInformationLength, ref int returnLength);
/// <summary>
/// Return the process ID of the process that is the parent of this process, if any, or else return null.
/// </summary>
/// <returns>Return the process ID of the process that is the parent of this process, if any, or else return null.</returns>
/// <remarks></remarks>
private static int? GetParentProcessID()
{
var info = new NtQueryInformationProcessProcessInformation();
var returnLength = 0;
const int ProcessInfoClassProcessBasicInformation = 0;
var status = NtQueryInformationProcess(Process.GetCurrentProcess().Handle, ProcessInfoClassProcessBasicInformation, ref info, System.Runtime.InteropServices.Marshal.SizeOf(info), ref returnLength);
var NTStatusSuccess = 0;
if (status != NTStatusSuccess) throw new System.ComponentModel.Win32Exception(status);
try
{
return Process.GetProcessById(info.InheritedFromUniqueProcessId.ToInt32()).Id;
}
catch (ArgumentException)
{
return new int?(); //not found.
}
}
/// <summary>
/// A structure which is required by the <see cref="NtQueryInformationProcess"/> method.
/// </summary>
/// <remarks></remarks>
private struct NtQueryInformationProcessProcessInformation
{
internal IntPtr Reserved1;
internal IntPtr PebBaseAddress;
internal IntPtr Reserved2_0;
internal IntPtr Reserved2_1;
internal IntPtr UniqueProcessId;
internal IntPtr InheritedFromUniqueProcessId;
}
Тогда вы могли бы использовать его как это:
var parentProcessID = GetParentProcessID();
var parentProcess = parentProcessID.HasValue ? Process.GetProcessById(parentProcessID.Value) : null;
if(parentProcess != null)
{
try
{
var strongName = Assembly.ReflectionOnlyLoadFrom(parentProcess.MainModule.FileName);
// check your strong name to make sure it belongs to the launcher...
}
catch (System.BadImageFormatException e)
{
// not a .net assembly, so it couldn't be your launcher app.
}
}
Это только начало, но вы получите идею ...
Вы можете использовать именованный канал для выполнения межпроцессного для передачи некоторого «ключа» или выполнения некоторой другой проверки. – crashmstr
Был ли способ проверить, что программа запускается только через именованный канал? А также не удалось бы создать другое приложение с тем же самым именованным каналом, которое обходило бы это? –
@AlksandrAlbert - Вам нужно исследовать это самостоятельно. Мы не собираемся делать всю работу за вас. Предположительно, имя канала известно только родительскому приложению и дочерним приложениям (тем, которые запускаются). Дети, конечно же, запустили бы, несмотря ни на что, но они могут прекратить работу, если они не будут начаты через родителя. –