How to Programmatically Launch a Specific Application

How do I programmatically launch a specific application?

You use the package name / class directly, for example to create a new intent to call the twidroid program you'd use the followinglink text:

 Intent intent = new Intent("com.twidroid.SendTweet");

You'd probably want to put a try/catch around for a ActivityNotFoundException for when the application is not installed.

How do I programmatically launch an application?

I think you are talking about Tasks. All available tasks can be consulted here: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks(v=vs.92).aspx

The call app you are talking about is the PhoneCallTask: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.phonecalltask(v=vs.92).aspx

If you want to call and app, that is, to open an application from the phone, you can't really do it. Please look at: Launching other applications in Windows phone 7 Programatically

How to programmatically start an application on a specific monitor on Windows 10?

As suggested by others, this is intended behavior of Windows and for the good reasons.

Also, you can not rely on default window placement atleast for SumatraPDF, since it surely does not use CW_USEDEFAULT, and instead stores these values in :

%USERPROFILE%\AppData\Roaming\SumatraPDF\SumatraPDF-settings.txt

There are multiple options though:

  1. Use third party tools that monitor top level windows and based on pre-configured rules moves them to specified display. E.g. DisplayFusion, etc.
  2. Use ligher weight solutions like AutoHotkey/AutoIt.
  3. Try and do this in code itself. Following is a working solution. I smoke tested on my box.

Disclaimer: I have not written the entire code, for saving time I pulled it up from couple of sources, tweaked it, glued it together, and tested with SumantraPDF. Do also note, that this code is not of highest standards, but solves your problem, and will act as a can-be-done example.

C++ code: (scroll down for C# code)

#include <Windows.h>
#include <vector>

// 0 based index for preferred monitor
static const int PREFERRED_MONITOR = 1;

struct ProcessWindowsInfo
{
DWORD ProcessID;
std::vector<HWND> Windows;

ProcessWindowsInfo(DWORD const AProcessID)
: ProcessID(AProcessID)
{
}
};

struct MonitorInfo
{
HMONITOR hMonitor;
RECT rect;
};

BOOL WINAPI EnumProcessWindowsProc(HWND hwnd, LPARAM lParam)
{
ProcessWindowsInfo *info = reinterpret_cast<ProcessWindowsInfo*>(lParam);
DWORD WindowProcessID;

GetWindowThreadProcessId(hwnd, &WindowProcessID);

if (WindowProcessID == info->ProcessID)
{
if (GetWindow(hwnd, GW_OWNER) == (HWND)0 && IsWindowVisible(hwnd))
{
info->Windows.push_back(hwnd);
}
}

return true;
}

BOOL CALLBACK Monitorenumproc(HMONITOR hMonitor, HDC hdc, LPRECT lprect, LPARAM lParam)
{
std::vector<MonitorInfo> *info = reinterpret_cast<std::vector<MonitorInfo>*>(lParam);

MonitorInfo monitorInfo = { 0 };

monitorInfo.hMonitor = hMonitor;
monitorInfo.rect = *lprect;

info->push_back(monitorInfo);
return TRUE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{

// NOTE: for now this code works only when the window is not already visible
// could be easily modified to terminate existing process as required

SHELLEXECUTEINFO info = { 0 };
info.cbSize = sizeof(info);
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.lpFile = L"C:\\Program Files\\SumatraPDF\\SumatraPDF.exe";
info.nShow = SW_SHOW;

std::vector<MonitorInfo> connectedMonitors;

// Get all available displays
EnumDisplayMonitors(NULL, NULL, Monitorenumproc, reinterpret_cast<LPARAM>(&connectedMonitors));

if (ShellExecuteEx(&info))
{
WaitForInputIdle(info.hProcess, INFINITE);

ProcessWindowsInfo Info(GetProcessId(info.hProcess));

// Go though all windows from that process
EnumWindows((WNDENUMPROC)EnumProcessWindowsProc, reinterpret_cast<LPARAM>(&Info.ProcessID));

if (Info.Windows.size() == 1)
{
// only if we got at most 1 window
// NOTE: applications can have more than 1 top level window. But at least for SumtraPDF this works!

if (connectedMonitors.size() >= PREFERRED_MONITOR)
{
// only move the window if we were able to successfully detect available monitors

SetWindowPos(Info.Windows.at(0), 0, connectedMonitors.at(PREFERRED_MONITOR).rect.left, connectedMonitors.at(PREFERRED_MONITOR).rect.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
}

CloseHandle(info.hProcess);
}

return 0;
}

To emphasize one of my comments in code. This code will only work if the process in question is not already running. You can tweak the code as per your requirements otherwise.

Update: Added C# code below, as I realized OP prefers C#. This code also has the termination logic cooked in.

C# code:

[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);

private const int SWP_NOSIZE = 0x0001;
private const int SWP_NOZORDER = 0x0004;

private const int PREFERRED_MONITOR = 1;

static void Main(string[] args)
{

// NOTE: you will have to reference System.Windows.Forms and System.Drawing (or
// equivalent WPF assemblies) for Screen and Rectangle

// Terminate existing SumatraPDF process, else we will not get the MainWindowHandle by following method.
List<Process> existingProcesses = Process.GetProcessesByName("SumatraPDF").ToList();

foreach (var existingProcess in existingProcesses)
{
// Ouch! Ruthlessly kill the existing SumatraPDF instances
existingProcess.Kill();
}

// Start the new instance of SumantraPDF

Process process = Process.Start(@"C:\Program Files\SumatraPDF\SumatraPDF.exe");

// wait max 5 seconds for process to be active
process.WaitForInputIdle(5000);

if (Screen.AllScreens.Length >= PREFERRED_MONITOR)
{
SetWindowPos(process.MainWindowHandle,
IntPtr.Zero,
Screen.AllScreens[PREFERRED_MONITOR].WorkingArea.Left,
Screen.AllScreens[PREFERRED_MONITOR].WorkingArea.Top,
0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
}

How to open a particular app's setting from WinUI/UWP application

there are lot of options but it does not provide details about how to open a setting for a particular app.

You need register launch uri for particular app, and you can get parameter in target app's onactive method. For example testapp:setting, you could get setting string from parameter.

Then call navigate method to setting page base base on the received parameter. For more info please refer to Handle URI activation.

And the other way is build jump list for the app. The jump list is a system-provided menu that appears when the user right-clicks a program in the taskbar or on the Start menu.

var jumpList = await Windows.UI.StartScreen.JumpList.LoadCurrentAsync();

// Disable the system-managed jump list group.
jumpList.SystemGroupKind = Windows.UI.StartScreen.JumpListSystemGroupKind.None;

var taskItem = JumpListItem.CreateWithArguments(
"/Setting", "Setting");

// Set the description. (Optional.)
taskItem.Description = "Compose a new message to " + "Nico";

// Set the logo for this jump list item. Must be ms-appx: or ms-appdata:.
taskItem.Logo = new Uri("ms-appx:///Assets/StoreLogo.png");

// Remove any previously added custom jump list items.
jumpList.Items.Add(taskItem);

// Save the changes to the app's jump list.
await jumpList.SaveAsync();

And you could process launch parameter.

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
if (e.Kind == ActivationKind.Launch && e.Arguments == "/Setting")
{
// navigate to setting page.
}
}

Update

You could use ms-settings:appsfeatures-app to open current app's setting page with launcher in code behind. But it could not use to open other app's setting content.

How to programmatically start an application at user login?

The Input/output error means the .plist file you provided is incorrect either in xml way or in target way.

You can read about all this here, and I will just post some advices, that should help for this specific case. Some of them are not necessary to make this work, but believe me, it is better to stay with them.

  1. Use the full xml header. (example on website above)
  2. The Label value must be the same with the plist file name. It is also almost always a bundle id. So, make it com.my.application.plist, and the value of Label field should be com.my.application
  3. Don't do spaces where they are unneeded, e.g. true/, not true /
  4. The program path should be the path to unix binary. Try, if you can launch your app from terminal using this path /Users/user/Desktop/osx-x64/application
    If no, you need to fix this at first.

This should work for you.

Open a Windows app programmatically, when it was installed with MSIX Application Packager

This turned out to be fairly simple.

Edit your Package.appmanifest and add the following in the Application element

<Extensions>
<uap5:Extension Category="windows.appExecutionAlias">
<uap5:AppExecutionAlias>
<uap5:ExecutionAlias Alias="MyApp.exe"/>
</uap5:AppExecutionAlias>
</uap5:Extension>
</Extensions>

And ensure this namespace is referenced at the top of the manifest file xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5"
and is in the ignorable namespaces too.

Rebuild and re-install the MSIX.

Test at a new command-prompt - just type MyApp.exe - it should open the app.

Now the second program can execute Process.Start("MyApp.exe") and it works.

Reference: https://learn.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-uap5-extension

Detecting programmatically whether a specific UWP app is installed on system

You should be able to use PackageManager.FindPackage or PackageManager.FindPackageForUser to see if the target package is available universally or for the specific or current user.

See Calling Windows 10 APIs From a Desktop Application for info on how to call this from your WinForms app.

Also check out the Enumerate app packages by user SID sample which demonstrates enumerating app packages from a C# console app. The project used is out of date (it's for VS2013), but the overall code flow should still work.

Depending on your specific scenario (why do you need to know this and what will you do with that information?) there may be better ways for your specific use case. For example: you asked elsewhere about launching a UWP app. If you define and launch a protocol for the app you don't need to check if it's already there first as the protocol launch will offer to look for the app in the store if it's not installed.



Related Topics



Leave a reply



Submit