How to pass parameters from UWP app to pure C++ console app? - c++

I have a UWP app that launches a C++ console app (not a Windows runtime component or anything related to UWP). I need the UWP app to pass a file path to the C++ console app so the console app can process it.
For reference, I followed these blog posts:
https://stefanwick.com/2018/04/06/uwp-with-desktop-extension-part-1/
https://stefanwick.com/2018/04/06/uwp-with-desktop-extension-part-2/
As for the parameters, I have this code in my Package.appxmanifest file:
<Extensions>
<desktop:Extension xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
Category="windows.fullTrustProcess"
Executable="PTSExtractionWRT\PTSExtractionWRT.exe">
<desktop:FullTrustProcess>
<desktop:ParameterGroup GroupId="ExistingFile" Parameters="/existingFile"/>
</desktop:FullTrustProcess>
</desktop:Extension>
</Extensions>
and I launch the console app like so from MainPage.xaml.cs
if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
{
// store command line parameters in local settings so Launcher can retrieve them
ApplicationData.Current.LocalSettings.Values["parameters"] = filePath;
var appData = ApplicationData.Current.LocalSettings;
await Windows.ApplicationModel.FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync("ExistingFile");
}
The problem is that the filePath variable I'm sending is getting stored in the C:\Users\14087\AppData\Local\Packages\23930191-5d12-44d5-81c3-808263a5b2f9_qe1bgctg42gkj\Settings\settings.dat file with this path, and I can't find a way to access this file from the C++ console app.
What is being sent as arguments to the C++ app is "/existingFile" from the Package.appxmanifest file.
How can I retrieve the real parameter?

Referring to the document, you could configure your pure c++ console app with the Microsoft.Windows.CppWinRT NuGet package to enable the c++ console app use C++/WinRT APIs, so that you can get the parameters by using ApplicationData API in C++ console project.
Please check the following steps for your c++ console project:
Open the NuGet Package Manager(option Tools > NuGet Package Manager > Manage NuGet Package for Solution…).
Input cppwinrt in Browse page, find Microsoft.Windows.CppWinRT and install it for your c++ console project.
Open the Properties page for your c++ console project, in Configuration Properties > General page, set the option C++ Language Standard as ISO C++ 17 Standard(/std:c++ 17).
In your c++ console project, add the necessary header file and code to test the ApplicationData API, for example:
#include <iostream>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
int main()
{
std::cout << "Hello World!\n";
winrt::Windows::Storage::ApplicationDataContainer localSettings= winrt::Windows::Storage::ApplicationData::Current().LocalSettings();
auto values = localSettings.Values();
//values.Insert(L"exampleSetting", winrt::Windows::Foundation::PropertyValue::CreateString(L"Hello Windows"));
winrt::hstring val = winrt::unbox_value<winrt::hstring>(values.Lookup(L"parameters"));
std::wcout << val.c_str() << std::endl;
system("PAUSE");
}
For more information about C++/WinRT, you could refer to the document.

Related

Unable to start program 'MYPATH.exe'. The system cannot find the file specified. When i try to run a new 'hello world' console application

i am new and i was trying to learn c++, so i open my visual studio 2019, then create a new console application and click the run button.
This is the autogenerated code:
#include <iostream>
int main()
{
std::cout << "Hello World!\n";
}
any idea?
To fix the error, i go to Tools > Get Tool And Features...
Then i installed Windows 10 SDK (10.0.19041.0)
and now my program works! Someone know the reason why the SDK is not installed by default?

Using custom script files with C++ project in Visual Studio 2019

TL;DR
My project uses a custom script file at runtime.
My project builds fine in VS and runs on the command line.
However when running in VS an error is thrown implying the file doesn't exist.
Full Details
My c++ project uses a custom scripting file to apply some settings at run time:
these are javascript like but not actual javascript
having these settings not in compiled files means they may be changed without recompiling
Everything builds fine, the script is copied using xcopy in a post build event.
When running in VS2019 it doesn't seem to be able to find the scripting file.
An opaque, library specific error is issued: A GenApi error has occurred
But when running the resulting .exe from cmd everything works, the script is used no problem.
If the script file is removed from the output dir and the .exe is run again I get the same A GenApi error has occurred.
I have tried:
running in release and debug.
including and excluding the file from the build.
I don't want to debug the script, I just need it to be used during start up so I can debug the rest of the program which is in C++.....
Example Code
Main.cpp
#include <iostream>
#include <EGrabber.h>
void configure() {
Euresys::EGenTL gentl;
Euresys::EGrabber<> grabber(gentl);
grabber.runScript("config.js");
}
int main() {
try {
configure();
} catch (const std::exception &e) {
std::cout << "error: " << e.what() << std::endl;
}
}
config.js
var grabber = grabbers[0];
var FPS = 150;
// camera configuration
grabber.RemotePort.set("TriggerMode", "On");
grabber.RemotePort.set("TriggerSource", "CXPin");
grabber.RemotePort.set("ExposureMode", "TriggerWidth");
// frame grabber configuration
grabber.DevicePort.set("CameraControlMethod", "RG");
grabber.DevicePort.set("CycleTriggerSource", "Immediate");
grabber.DevicePort.set("CycleMinimumPeriod", 1e6 / FPS);
More info:
script documentation
based on #john 's comment:
There is a different current working directory when running from VS and when running from the command line.
When run from VS the current working directory is the project directory not the output directory.
The script was in project-dir\src not the immediate project dir.
Moving the script up to the project directory solved everything.
Alternative solutions, which worked:
Use the full path: C:\\full\\path\\config.js
(the application startup path can be extracted from argv[0])
Change the debug working directory in VS:
Project -> Properties -> Configuration Properties -> Debugging -> Working Directory
Enter output path, eg: $(SolutionDir)bin$(Platform)$(Configuration)\

Why Qt Creator's application output does not print from spdlog logger

I have working logging in Visual studio project using spdlog. I used the same project in Qt creator, then the spdlog logging does not output anything. But the std::cout still works and prints to Qt creator's application output window.
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
sinks.push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>("multisink.txt", true));
auto appLogger = std::make_shared<spdlog::logger>("appLogger", begin(sinks), end(sinks));
appLogger->set_level(spdlog::level::debug);
spdlog::register_logger(appLogger);
spdlog::flush_on(spdlog::level::debug);
appLogger->warn("this should appear in both console and file");
Yes, the application output does not output the spdlogs. But, I manage to output to terminal by following steps.
Go to Projects, then choose Run configuration for selected kit
In run settings, check the "Run in terminal" option
Next, add console to CONFIG in Project pro file
Clean the project
Build and run.
If these steps don't help, you can delete entire build directory and run the steps again.
I had the same issue, and only way I could get the log messages to appear in the application output tab was to use the msvc logger.
auto sink = std::make_shared<spdlog::sinks::msvc_sink_mt>();
auto logger = std::make_shared<spdlog::logger>("msvc_logger", sink);
The flip side of this logger is that it doesn't print to the console/terminal.
To write to both the application output and the console using the same logger you could create a distributed sink as this:
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto msvc_sink = std::make_shared<spdlog::sinks::msvc_sink_mt>();
auto dist_sink = std::make_shared<spdlog::sinks::dist_sink_st>();
dist_sink->add_sink(msvc_sink);
dist_sink->add_sink(console_sink);
auto logger = std::make_shared<spdlog::logger>("multi_sink", dist_sink)
logger->info("testing multiple sinks");

std::ifstream::open() fails in Windows 10 Universal apps

I'm working on a Windows 10 Universal C++ project and I'm trying to open a binary file in read-mode using std::ifstream.
This is my code:
std::ifstream imgFile("C:\\Users\\GuiTeK\\Desktop\\picture.bmp", std::ios::binary);
if (imgFile.is_open())
{
std::cout << "OK" << std::endl;
}
else
{
int error = errno;
std::cerr << "KO: " << error << std::endl;
}
Problem is that it keeps failing with error 13, which means "The data is invalid" (C.F. System Error Codes).
However, the exact same code works fine in a Win32 Console Application C++ project.
What's wrong?
UWP apps do not have permission to access all files on the device. By default, apps can access certain file system locations such as application install directory or application data locations. For more info, please see File access permissions.
"C:\Users\GuiTeK\Desktop\picture.bmp" is a location that you app can't directly access. In UWP, we will need a File​Open​Picker to access such a file. One important rule here is that Skip the path: stick to the StorageFile.
For more info about how to handle files in UWP, please see Files, folders, and libraries and also File access sample, File picker sample on GitHub.

Get working directory on Windows Phone

How to get the current working directory on windows phone?
_wgetcwd and GetCurrentDirectory are not supported on windows phone.
Windows Store Apps don't have the notion of a "current directory" (the OS sets it to be the install location and doesn't let you change it).
The more interesting question is what you want to do with the working directory. Ordinarily, you would use WinRT StorageFile APIs to read and write files, but if you want to use CreateFile or fopen then you can get the path from a WinRT StorageFolder:
void foo()
{
using namespace Windows::ApplicationModel;
using namespace Windows::Storage;
auto installLocation = std::wstring(Package::Current->InstalledLocation->Path->Data());
auto dataLocation = std::wstring(ApplicationData::Current->LocalFolder->Path->Data());
OutputDebugString((installLocation + L"\r\n" + dataLocation).c_str());
}
For my test app, this prints
d:\temp\UniversalScratch\UniversalScratch\UniversalScratch.Windows\bin\x86\Debug\AppX
C:\Users\Peter\AppData\Local\Packages\257de9ed-b378-4811-98e6-226e15a3f7f0_tp1tpcm9wdwpy\LocalState
If you use fopen (or fopen_s) with a relative filename, it will be relative to your install package.