My goal is to launch a file from an app that the user specifies in my UWP app. When I hit on the Launch button, I navigate backwards into my AppData (UWP) Packages folder, then I iterate through folder and utilize the PackageManager class to retrieve packages by name. I try to initialize a package with the right package name using FindPackage (here). However, it doesn't work for me and I get an exception "Value does not fall within the expected range" when calling FindPackage.
Here's what I've tried so far:
StorageFolder currApp = Windows.Storage.ApplicationData.Current.LocalFolder;
Debug.WriteLine(currApp.Path);
// move up and get parent folder for all packages
DirectoryInfo currAppFolder = Directory.GetParent(currApp.Path);
DirectoryInfo pkgs = Directory.GetParent(currAppFolder.FullName);
StorageFolder pkgFldr = await StorageFolder.GetFolderFromPathAsync(pkgs.FullName);
var pkgDirs = await pkgFldr.GetFoldersAsync();
Package UwpPkg = null;
var PkgMgr = new PackageManager();
foreach (StorageFolder dir in pkgDirs)
{
string folderName = dir.Name;
var currPkg = PkgMgr.FindPackage(folderName);
if (filter == currPkg.DisplayName)
{
// we found it
UwpPkg = currPkg;
break;
}
}
I've also already configured necessary permissions (rescap: broadFileSystemAccess).
Did someone also have such problems/a possible solution? Thank you!
Windows 10 UWP App Launch from Package List (FindPackage)
Please check PackageManager document, for this api it need packageQuery capability
<Package
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap" >
......
<rescap:Capability Name="packageQuery" />
And please note
This method requires administrative privileges. The returned package may be installed for the current user or for another user. So please invoke above in the elevated desktop extension. For more you could stefan's blog App Elevation Samples.
Related
I have downloaded and attached the FixedVersionRuntime.88.0.705.81.x64 for WebView2 and attached it to my project.
Using the following it should load the necessary page but when loading the WebView is not crashing but no page is loaded:
public async Task InitializeAsync()
{
string installPath = #"C:\Program Files (x86)\WebView2Runtime\Microsoft.WebView2.FixedVersionRuntime.88.0.705.81.x64\";
var webView2Environment = await CoreWebView2Environment.CreateAsync(installPath);
await browserControl.EnsureCoreWebView2Async(webView2Environment);
}
I am then setting the source after this:
await InitializeAsync();
me.Source = new Uri(((MainViewModel)this.DataContext).Config.DefaultURL);
When using the evergreen installer it worked fine but when moving to the fixed version it seems to not load correctly when deployed.
I've tested the following, which seems to work:
Download WebView2 Fixed Version
Example
Given:
WebView2 Fixed Version: Microsoft.WebView2.FixedVersionRuntime.88.0.705.81.x86.cab
Project folder: C:\Projects\WpfTestFixedVersion
Output folder: C:\Projects\WpfTestFixedVersion\WpfTestFixedVersion\bin\Debug
Project compiled using:
Configuration: Debug
Platform: Any CPU (Prefer 32-bit)
Extract files from .cab
Open a cmd window
cmd window
C:\Users\Test\Downloads> expand Microsoft.WebView2.FixedVersionRuntime.88.0.705.81.x86.cab -F:* "C:\Projects\WpfTestFixedVersion\WpfTestFixedVersion\bin\Debug"
Note: When using expand in the above command, the destination folder must already exist and the name must not end with '\'.
C:\Projects\WpfTestFixedVersion\WpfTestFixedVersion\bin\Debug
C:\Projects\WpfTestFixedVersion\WpfTestFixedVersion\bin\Debug\Microsoft.WebView2.FixedVersionRuntime.88.0.705.81.x86
Option 1:
InitializeAsync
public async Task InitializeAsync()
{
string installPath = #".\Microsoft.WebView2.FixedVersionRuntime.88.0.705.81.x86";
var webView2Environment = await CoreWebView2Environment.CreateAsync(installPath);
await browserControl.EnsureCoreWebView2Async(webView2Environment);
}
Option 2:
Note: This option allows one to specify the userDataFolder. If it's not specified, it uses the user's temp folder as the location for the userDataFolder.
InitializeAsync
public async Task InitializeAsync(WebView2 wv, string webCacheDir = "")
{
CoreWebView2EnvironmentOptions options = null;
string tempWebCacheDir = string.Empty;
CoreWebView2Environment webView2Environment = null;
//set value
tempWebCacheDir = webCacheDir;
if (String.IsNullOrEmpty(tempWebCacheDir))
{
//get fully-qualified path to user's temp folder
tempWebCacheDir = System.IO.Path.GetTempPath();
tempWebCacheDir = System.IO.Path.Combine(tempWebCacheDir, System.Guid.NewGuid().ToString("N"));
}
//use with WebView2 FixedVersionRuntime
webView2Environment = await CoreWebView2Environment.CreateAsync(#".\Microsoft.WebView2.FixedVersionRuntime.88.0.705.81.x86", tempWebCacheDir, options);
//webView2Environment = await CoreWebView2Environment.CreateAsync(#"C:\Program Files (x86)\Microsoft\Edge Dev\Application\90.0.810.1", tempWebCacheDir, options);
//webView2Environment = await CoreWebView2Environment.CreateAsync(null, tempWebCacheDir, options);
//wait for CoreWebView2 initialization
await wv.EnsureCoreWebView2Async(webView2Environment);
}
The answer by #user9938 is comprehensive. But please also note that the version of "WebView2Loader.dll" which is in use is very crucial. I had almost the same problem with "Microsoft.WebView2.FixedVersionRuntime.101.0.1210.39.x64" when I tried to use the WebView2 component in the MMC Snap-Ins with types of "HTMLView" or "FormView".
I just copied the abovementioned dll file (version 1.0.1248.0, size=157640 bytes) in a proper path that was accessible for the project (you could just put it beside your project output files first to test it) and then WebView2 browser started to function as expected. Microsoft error messages sometimes (at least in my case) was a little bit misleading and did not convey enough and to the point information.
I received "BadImageFormatException" that normally occurs when you mix platform targets (for example using a dll file compiled in X64 in an application that targeted for x86 or vice versa) or mix native code and .NET but that was not my problem at all. I hope this help one who may stuck in.
My goal is to find and launch a UWP app by name (e.g. Twitter). I'm currently using an elevated desktop extension, following a guide by Stefan Wick.
In my full-trust Win32 console process, I'm currently using the PackageManager to find and list all the UWP apps, and it works on my machine. However, when I send my finalized app package to another user, nothing appears on his screen, even after running elevated.
Here's my current code:
var PkgMgr = new PackageManager();
var currUserPkgs = PkgMgr.FindPackagesForUser(string.Empty);
foreach (Package pkg in currUserPkgs)
{
string pkgName = pkg.DisplayName;
if (pkgName == "")
{
continue;
}
if (pkgName.Contains(appName) || appName.Contains(pkgName) ||
percentSimilarity(appName, pkgName) >= 0.50)
{
// we found it
appPkgName = pkg.Id.FamilyName;
break;
}
}
Why does this not bring up any packages on another user's machine? There's no error message that's called.
Also, is there another solution that can locate all UWP packages? Thank you!
I wish to find the target of a shortcut (.lnk file, not a symlink) in Windows 10 using C#.
I have searched for hours and found numerous methods for doing this, but two comments I found are memorable, that shortcuts in Windows 10 are somewhat different. The other is that it's trickier than it sounds. None of the methods I have tried work. I've referenced all the necessary COM objects.
They compile (the full programs do) but produce no output, with the exception of the Shell32 idea that has a permission error.
Examples of what I've tried (snippets)
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(filePath);
return shortcut.TargetPath;
// supposed to reference an existing shortcut, but no output
---or---
dynamic shortcut;
dynamic windowsShell;
Type shellObjectType = Type.GetTypeFromProgID("WScript.Shell");
windowsShell = Activator.CreateInstance(shellObjectType);
shortcut = windowsShell.CreateShortcut(LinkName);
string Properfile = shortcut.TargetPath;
// Release the COM objects
shortcut = null;
windowsShell = null;
return Properfile;
//no output
---or---
string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);
Shell shell = new Shell();
Folder folder = shell.NameSpace(pathOnly);
FolderItem folderItem = folder.ParseName(filenameOnly);
if (folderItem != null)
{
Shell32.ShellLinkObject link = (Shell32.ShellLinkObject)folderItem.GetLink;
return link.Path;
}
// permission error
They're snippets but convey the idea of input, procedure and result.
The only other lead I found was to a Microsoft document on the structure of a .lnk file. I've seen solutions that parse them (older versions) but would really like to stay with a modern API.
So I summarised (yep, Aus spelling) what I want, what I've tried and how the code failed.
To put in perspective, the goal is to have a window of shortcuts, but it seems I need to go back to the executable to get different sized icons in a ListView.
This has been answered here by Alexey:
Add Application Manifest File, app.manifest, to your Solution's Startup project if not currently there (Right Click on Project -> Add -> New Item -> General -> Application Manifest File).
In your app.manifest file,
replace this line of code:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
with this:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
the requireAdministrator makes your app run with Administrator's Right that gives you the required access.
You can try on something like this:
public static void CreateShortcut(string shortcutName, string shortcutPath, string targetFileLocation)
{
string shortcutLocation = System.IO.Path.Combine(shortcutPath, shortcutName + ".lnk");
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutLocation);
shortcut.Description = "Discription"; // The description of the shortcut
shortcut.IconLocation = "Path";// The icon of the shortcut
shortcut.TargetPath = targetFileLocation; // The path of the file that will launch when the shortcut is run
shortcut.Save(); // Save the shortcut
}
And this is how you would use it:
CreateShortcut("Name", PathToDesktop, InstallPathwitheExtention");
Using .NET Core, C#, Linux
I've searched around a bit and can't seem to find anything. Maybe it's not possible and I need a different approach?
Can someone kindly point me in the direction of how I can go about getting the directory listing for a given path for a specific username?
I am running a web application service as Root but need to check and return directories and files for a given username (no password is available) - to report directories and files that a given username has read-access to.
Say for example "/opt/mydata/" and in there I will have a number of directories that I will manually create and set the permissions for each user group. I.e. "/opt/mydata/user_1_readable" will be returned when I do a directory listing for user1 (because this user is in the respective permissions group, or is the owner, or it is set for everyone to read) but will not be returned for user2 (this user is not in the correct group).
Essentially, I want to "impersonate" or in Linux, do the equivalent of "sudo su user1" and report what directories/files are readable within "/opt/mydata/" for a given user.
I can get the directory listing and files fine running as Root. What I can't do / don't know how to is getting the directory listing for a specific user. The examples I found and tried are all Windows Identity and Windows Security specific.
E.g. I found this example but it seemed to apply to "Mono" which I am not running, but essentially I really want to do something along the lines of this:
// Impersonate a user
using (WindowsIdentity newId = new WindowsIdentity("user1"))
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
var content = _fileProvider.GetDirectoryContents(uri);
}
Is there some third party library or some other way please?
Resource:
Change current Linux user in a C# application running with Mono?
If you look at this issue on .net core repository, Proposal: Expose POSIX functions , it looks like it won't be implemented in .net core, but only in Mono.Posix.NETStandard.
The library is compatible with .net core 2.0, and it shouldn't be too hard to implement this yourself.
You could try something like this with the package to filter which files the user can read.
public UserHasReadPermission(string username, string file)
{
var user = new UnixUserInfo(username);
var file = new UnixFileInfo(file);
// Everyone has read permission
if (file.FileAccessPermissions.HasFlag(FileAccessPermissions.OtherRead))
return true;
// User owns the file and has read permission
if (file.OwnerUser == user && file.FileAccessPermissions.HasFlag(FileAccessPermissions.UserRead))
return true;
// User group owns the file and has read permission
if (file.OwnerGroup == user.Group && file.FileAccessPermissions.HasFlag(FileAccessPermissions.GroupRead))
return true;
return false;
}
Perhaps you want to read the /etc/passwd file to get users' directories?
Once you have that, you can then get all subdirs inside the folders:
List<string> AllFiles = new List<string>();
void ParsePath(string path)
{
string[] SubDirs = Directory.GetDirectories(path);
AllFiles.AddRange(SubDirs);
AllFiles.AddRange(Directory.GetFiles(path));
foreach (string subdir in SubDirs)
ParsePath(subdir);
}
I've got a URL to a OneDrive folder (https://1drv.ms/f/s!AtXoQFW327DIyMwPjZhmauUCSSHXUA). Everyone with that link can access the folder via browser.
Now, my goal is to create an .NET application that, given that link, is able to get a list of the files/folders inside that folder.
Is that even possible?
The best way to do this is to use the OneDrive API exposed via Graph.
You can read the "Using Sharing Links" documentation for full details, but you'd essentially make a call to:
https://graph.microsoft.com/v1.0/shares/u!aHR0cHM6Ly8xZHJ2Lm1zL2YvcyFBdFhvUUZXMzI3REl5TXdQalpobWF1VUNTU0hYVUE/driveItem/children
You can also use the .NET SDK to avoid making the calls to the API yourself, in which case your code would look something like:
client.Shares["u!aHR0cHM6Ly8xZHJ2Lm1zL2YvcyFBdFhvUUZXMzI3REl5TXdQalpobWF1VUNTU0hYVUE"].DriveItem.Children.Request().GetAsync();
Selenium Web Driver is good option for tasks like that.
Open Solution Explorer.
Right Click on your project.
Select Manage NuGet Packages..
Browse and install these two : Selenium.Chrome.WebDriver and Selenium.WebDriver.
You have just installed selenium to your project!
So now, we need to create a driver service, and find needed elements in our website.
As far as i see, filenames are stored as a span class named signalFieldValue_03700093.
But "Last Modified infos" are stored under this class too, i needed to skip "Last Modified infos" using the code below:
bool skip = false;
List<string> myFiles = new List<string>();
ChromeDriverService service = ChromeDriverService.CreateDefaultService();
ChromeOptions option = new ChromeOptions();
var driver = new ChromeDriver(service, option);
driver.Url = "https://1drv.ms/f/s!AtXoQFW327DIyMwPjZhmauUCSSHXUA";
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
foreach (IWebElement element in driver.FindElements(By.XPath("//span[#class='signalFieldValue_03700093']")))
{
if (!skip)
{
myFiles.Add(element.Text);
skip = true;
}
else
skip = false;
}
As a result, we have our filenames in string array named myFiles.
Hope this helps!