I would have the task pass in a command line parameter to tell you the app was started by the task
https://www.wpf-tutorial.com/wpf-application/command-line-parameters/
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
I've never used a WPF project before. We're trying to determine, if in the
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
}
Can we determine if the application was started by the user clicking on the Icon or if the application was started by a Task? I'm not sure where to start looking?
Any insight would be helpful, thank you.
I would have the task pass in a command line parameter to tell you the app was started by the task
https://www.wpf-tutorial.com/wpf-application/command-line-parameters/
A way is to get the parent PID, with NtQueryInformationProcess then QueryFullProcessImageName to get the parent name
I tested on Windows 10, I get :
From Explorer : c:\windows\explorer.exe
From Task Scheduler : c:\windows\system32\svchost.exe
(must be executed with maximum authorizations with Task Scheduler, otherwise OpenProcess returns ACCESS_DENIED )
int nStatus = STATUS_SUCCESS;
PROCESS_BASIC_INFORMATION pbi = new PROCESS_BASIC_INFORMATION();
nStatus = NtQueryInformationProcess(GetCurrentProcess(), PROCESSINFOCLASS.ProcessBasicInformation, pbi, (int)Marshal.SizeOf(pbi), null);
if (nStatus == 0)
{
IntPtr hProcessForName = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, true, (uint)pbi.InheritedFromUniqueProcessId);
if (hProcessForName != IntPtr.Zero)
{
uint nSize = 260;
StringBuilder sProcessImageName = new StringBuilder((int)nSize);
QueryFullProcessImageName(hProcessForName, 0, sProcessImageName, ref nSize);
string sName = sProcessImageName.ToString();
CloseHandle(hProcessForName);
MessageBox.Show(sName, "Information");
}
else
{
int nError = Marshal.GetLastWin32Error();
// ...
}
}
Declarations (using System.Runtime.InteropServices;):
public const int STATUS_SUCCESS = 0x0;
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetCurrentProcess();
public const int SYNCHRONIZE = 0x100000;
public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
public const int PROCESS_VM_READ = (0x10);
public const int PROCESS_VM_WRITE = (0x20);
public const int PROCESS_DUP_HANDLE = (0x40);
public const int PROCESS_CREATE_PROCESS = (0x80);
public const int PROCESS_SET_QUOTA = (0x100);
public const int PROCESS_SET_INFORMATION = (0x200);
public const int PROCESS_QUERY_INFORMATION = (0x400);
public const int PROCESS_SUSPEND_RESUME = (0x800);
public const int PROCESS_QUERY_LIMITED_INFORMATION = (0x1000);
public const int PROCESS_SET_LIMITED_INFORMATION = (0x2000);
public const long PROCESS_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool QueryFullProcessImageName(IntPtr hProcess, int dwFlags, StringBuilder lpExeName, ref uint lpdwSize);
[DllImport("NtDll.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int NtQueryInformationProcess(IntPtr ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PROCESS_BASIC_INFORMATION info, int ProcessInformationLength, int[] ReturnLength);
public enum PROCESSINFOCLASS
{
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessUnusedSpare1,
ProcessExecuteFlags,
ProcessResourceManagement,
ProcessCookie,
ProcessImageInformation,
MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum
}
[StructLayout(LayoutKind.Sequential)]
public class PROCESS_BASIC_INFORMATION
{
public int ExitStatus = 0;
public IntPtr PebBaseAddress = (IntPtr)0;
public IntPtr AffinityMask = (IntPtr)0;
public int BasePriority = 0;
public IntPtr UniqueProcessId = (IntPtr)0;
public IntPtr InheritedFromUniqueProcessId = (IntPtr)0;
}