CaptureSource.Start() throws System.UnauthorizedAccessException in Windows Phone Silverlight 8.1 - c#

I have problem with using camera in Windows Phone Silverlight 8.1 application. I want just to initialize camera and see its preview (for now I don't need any photos or video capture). I have found nice and simple example on MSDN and
private CaptureSource captureSource;
private VideoCaptureDevice videoCaptureDevice;
private void InitializeVideoRecorder()
{
try
{
if (captureSource == null)
{
captureSource = new CaptureSource();
var a = captureSource.VideoCaptureDevice;
videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
captureSource.CaptureFailed += OnCaptureFailed;
if (videoCaptureDevice != null)
{
VideoRecorderBrush = new VideoBrush();
VideoRecorderBrush.SetSource(captureSource);
captureSource.Start();
CameraStatus = "Tap record to start recording...";
}
else
{
CameraStatus = "A camera is not supported on this phone.";
}
}
}
catch (Exception ex)
{
CameraStatus = "ERROR: " + ex.Message.ToString();
}
}
The code stops at captureSource.Start(); throwing System.UnauthorizedAccessException: Attempted to perform an unauthorized operation..
First of all I found information (on the same page) that ID_CAP_ISV_CAMERA capability is needed in `WMAppManifest.xml'. But I have problem with adding it, because:
I can't find this capability in designer
I get error when I add it manualy to .xml file
Error reproduced below:
Warning 1 The 'Name' attribute is invalid - The value 'ID_CAP_ISV_CAMERA' is invalid according to its datatype 'http://schemas.microsoft.com/appx/2010/manifest:ST_Capabilities' - The Enumeration constraint failed.
Error 3 App manifest validation failed. Value 'ID_CAP_ISV_CAMERA' of attribute '/Package/Capabilities/Capability/#Name' must be a valid capability.
I have even found the same solution on SO WP8.1 SilverLight Microsoft.Devices.PhotoCamera Access Denied
Can somebody tell me why can't I use original MSDN solution to this problem?

First, it looks like you're trying to add that capability to Package.appxmanifest instead of WMAppManifest.xml. You should be able to find WMAppManifest.xml under Solution Explorer -> <your project> -> Properties:
Opening that file should give you the option to add ID_CAP_* capabilities.
Second, you need to specify both ID_CAP_ISV_CAMERA and ID_CAP_MICROPHONE in order to use CaptureSource.Start(), even if you're only using one of the devices.

Related

c# WebView2 user directory "Access Denied"

I am having issues with the .NET WebView2 control. I thought I had it fixed but it is not working. I have read numerous posts to no avail.
I have a WPF C# application that runs on a server. Various people log into the server via a web browser and run the app.
Within this app, I open up a WebView2 browser, setting the user data directory to a unique directory for each person.
When I set the user data directory and call EnsureCoreWebView2Async(), I get an error in the exception code "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
Below is the code:
public static async void InitializeWebView(WebView2 browser, string path)
{
Directory.CreateDirectory(path);
browser.CreationProperties = new CoreWebView2CreationProperties()
{
UserDataFolder = path
};
try
{
await browser.EnsureCoreWebView2Async();
}
catch( Exception ex)
{
Log.LogString("Ensure error: " + ex.Message);
}
}
I have tried various things without success. What am I doing wrong? Any suggestions?
I'm not all that familiar with CoreWebView2CreationProperties, but according to the documentation.
Its main purpose is to be set to CreationProperties in order to
customize the environment used by a WebView2 during implicit
initialization...If you need complete control over the environment used by a WebView2 control then you'll need to initialize the control explicitly by creating your own environment with CreateAsync(String, String, CoreWebView2EnvironmentOptions) and passing it to EnsureCoreWebView2Async(CoreWebView2Environment) before you set the Source property to anything.
As mentioned in the documentation referenced above, implicit initialization occurs when the Source property is set and CoreWebView2 hasn't been explicitly initialized.
To explicitly initialize CoreWebView2, try the following:
public async Task InitializeCoreWebView2Async(WebView2 wv, string userDataFolder = null)
{
//initialize CoreWebView2
CoreWebView2EnvironmentOptions options = null;
CoreWebView2Environment cwv2Environment = null;
//it's recommended to create the userDataFolder in the same location
//that your other application data is stored (ie: in a folder in %APPDATA%)
//if not specified, we'll create a folder in %TEMP%
if (String.IsNullOrEmpty(userDataFolder))
userDataFolder = Path.Combine(Path.GetTempPath(), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
//create WebView2 Environment using the installed or specified WebView2 Runtime version.
//cwv2Environment = await CoreWebView2Environment.CreateAsync(#"C:\Program Files (x86)\Microsoft\Edge Dev\Application\1.0.1054.31", userDataFolder, options);
cwv2Environment = await CoreWebView2Environment.CreateAsync(null, userDataFolder, options);
//initialize
await wv.EnsureCoreWebView2Async(cwv2Environment);
System.Diagnostics.Debug.WriteLine("UserDataFolder: " + userDataFolder);
}
Note: If one desires to explicitly initialize CoreWebView2, it must be done prior to setting the Source property for the WebView2 control.
Usage:
await InitializeCoreWebView2Async(webView21, Path.Combine(#"C:\Temp", System.Reflection.Assembly.GetExecutingAssembly().GetName().Name));
Resources:
CoreWebView2 Class
CoreWebView2CreationProperties
CoreWebView2Environment Class
CoreWebView2Environment.CreateAsync
WebView2.EnsureCoreWebView2Async(CoreWebView2Environment) Method
Thank you for your continued help. Due to character limitations, I am responding to your questions in an Answer section. In response to your comments...
If the Source was being set prior to initialization, I would be getting a different error (which I have had in the past).
Here is the xaml for the WebView2 control:
<Wpf:WebView2 Name="Browser" Margin="20,20,20,20" CoreWebView2InitializationCompleted="Browser_CoreWebView2InitializationCompleted" />
As you can see, I am subscribed to the InitializationComplete event, which is not being called due to the error.
Here is the source for the form that hosts the WebView2 control:
private async void _DoIt()
{
try
{
var env = await CoreWebView2Environment.CreateAsync(null, Global._GetServerDataDirectory(_Person));
await Browser.EnsureCoreWebView2Async(env);
}
catch( Exception ex)
{
Log.LogString("DoIt error: " + ex.Message);
}
}
public PayPal(Person person)
{
InitializeComponent();
_Person = person;
_DoIt();
Log.LogString("After PayPal constructor");
}
It is erroring in _DoIt().
Okay, after many hours of trying to track this down, the end issue is that Thinfinity's VirtualUI product does not support an application using WebView2. This was my core issue and has been confirmed by the vendor.
Thank you once again for everyone's kind help with this.

Xamarin Android - Exception when calling Environment.GetExternalStorageState(File path)

I’m unable to use the Android.OS.Environment.GetExternalStorageState method as outlined here.
The Android.OS.Environment.GetExternalStorageState property works. However in order to query the state the secondary external SD card’s state I need to use the method (not the property) and pass in the path to the secondary external SD card. When calling this method I receive a .NET exception as follows:
No static method with name=’getExternalStorageState’
signature=’(Ljava/io/File;)Ljava/lang/String;’ in class
Landroid/os/Environment;
A sample app that reliably reproduces the problem can be found here.
Note that this is on a device that has 2 SD cards. One is internal (not removable) and is the default SD card path. The other SD card is an external SD card which is removable. This test app assumes the external secondary removable SD card is at a root path of ‘sdcard1’ and the default internal is ‘sdcard0’. You may need to change this if your device is different.
Here is a trimmed down version of the CheckState from the sample app.
private bool CheckState(string pathStr)
{
try
{
var path = new File(pathStr);
var otherState = Environment.ExternalStorageState;
var state = Environment.GetExternalStorageState(path);
// Good state - set values and be done
return state.Equals(Environment.MediaMounted);
}
catch (Java.Lang.Exception ex)
{
Debug(Tag, $"Java Ex: {ex.Message}");
}
catch (Exception ex)
{
Debug(Tag, $".Net Ex: {ex.Message}");
}
return false;
}
In the example code above, the otherState variable is set with the state of the internal SD card. However when the next line with the state variable executes an exception is thrown.
Also, as an FYI - it is the .Net System.Exception that is thrown, no the Java.Lang.Exception.
If this code is correct and there is in fact a bug in the framework code somewhere (Xamarin and/or Android) then is there a recommended work around to determine if an SD card is available for reading & writing?
No static method with name=’getExternalStorageState’ signature=’(Ljava/io/File;)Ljava/lang/String;’ in class Landroid/os/Environment;
String getExternalStorageState (File path) was added in API 21.
re: https://developer.android.com/reference/android/os/Environment.html#getExternalStorageState(java.io.File)

Retrieving calls history from Windows 10 app - Access denied error

I'm trying to collect the Windows Mobile 10 calls history by using the latest API. I have enabled all possible capabilities for my application, but still I'm getting "Access Denied" error while running this code:
var operation = PhoneCallHistoryManager.RequestStoreAsync(PhoneCallHistoryStoreAccessType.AppEntriesReadWrite);
operation.Completed = (o, ev) =>
{
PhoneCallHistoryStore store = o.GetResults();
PhoneCallHistoryEntryReader reader = store.GetEntryReader();
var operation2 = reader.ReadBatchAsync();
operation2.Completed = (o2, ev2) =>
{
IReadOnlyList<PhoneCallHistoryEntry> callsList = o2.GetResults();
foreach (PhoneCallHistoryEntry entry in callsList)
{
// process calls here
}
};
};
I'm getting the following error message while doing line 4:
An exception of type 'System.UnauthorizedAccessException' occurred in App1.exe but was not handled in user code
Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
I'm running this code on Mobile Emulator in Visual Studio 2015.
This is what I used for that code:
https://msdn.microsoft.com/en-us/library/windows/apps/windows.applicationmodel.calls.aspx
Any idea what can be wrong?
In order to make above code working and view phone call history, need to add the following things:
1) Rescap namespace
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
2) Restricted capability "phoneCallHistory"
<rescap:Capability Name="phoneCallHistory"/>
3) Change PhoneCallHistoryAccessType to AllEntriesLimitedReadAndWrite.
var operation = PhoneCallHistoryManager.RequestStoreAsync(PhoneCallHistoryStoreAccessType.AllEntriesLimitedReadWrite);
Thanks to #RaymondChen for giving me the proper capability name.

MonoDroid evaluation System.UnauthorizedAccessException in Directory.CreateDirectory()

Scenario:
Start MonoDevelop
new Android Application
Replace button click delegate with
string fullPath = "/data/misc.mvvmcross.customermanagement/files/_Caches/Pictures.MvvmCross/";
if (System.IO.Directory.Exists(fullPath))
{
button.Text = "exists";
}
else
{
button.Text = "not found";
Directory.CreateDirectory(fullPath);
}
run and click the button.
Directory.CreateDirectory will fail with
System.UnauthorizedAccessException
Have tried creating a new emulator image with different API levels, but problem is still here
Any thoughts anyone?
Ok, Have created new Android Emulator image and used that.
Everything now works.
Solution:
Create a new android emulator image for the API level you want (don't forget Google API support)
I'm wondering if this is caused by some kind of assembly/package naming issue.
I've tested this code:
string fullPath = Path.Combine(FilesDir.Path, "_Caches2/Pictures.MvvmCross/2/");
if (System.IO.Directory.Exists(fullPath))
{
button.Text = "exists";
}
else
{
button.Text = fullPath;
Directory.CreateDirectory(fullPath);
}
...and it works fine in a 2.3.3 emulator.
The data folder pattern is: /data/ * package name * /files/
And it is correct (I think) for one package not to be able to access the data of another.
So I'm wondering if somehow your package names are wrong - check the manifest tab and the manifest.xml file for your application?

Vista TaskDialog Wrapper: Unable to find an entry point named 'TaskDialogIndirect' in DLL 'ComCtl32'

I'm try to use Vista TaskDialog Wrapper and Emulator and I'm getting the following exception:
"Unable to find an entry point named 'TaskDialogIndirect' in DLL 'ComCtl32'."
...in a simple Console application:
class Program
{
[STAThread]
static void Main(string[] args)
{
System.Threading.Thread.CurrentThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
PSTaskDialog.cTaskDialog.MessageBox(
"MessageBox Title",
"The main instruction text for the message box is shown here.",
"The content text for the message box is shown here and the text willautomatically wrap as needed.",
PSTaskDialog.eTaskDialogButtons.YesNo,
PSTaskDialog.eSysIcons.Information
);
}
}
What am I doing wrong?
UPDATE:
Actually, I'm working on an Excel plugin using excel-dna. How can I control what dll Excel loads?
http://exceldna.codeplex.com/discussions/286990#post728888
I haven't been at Office programming in a while, but my guess is that Excel loads both versions of comctl32, so you may need to use the Activation Context API to direct your code to the version that includes TaskDialog. Some ideas for fixing the problem (not solutions as such):
For test purposes, make a temporary enumeration of all modules in the active process - just to check if 6.10 is actually loaded (see below for a simple example of such an enumeration, albeit with a different intent).
Use the Activation Context API to get to the right version. Example of use from C# (for enabling themes by way of comctl32 6.0) here.
Alternatively (I never actually got this to work reliably in a WPF application I worked on), make a dialog abstraction class, which falls back to MessageDlg depending on the version available to you. There may be better ways of doing the check, but...:
FileVersionInfo version = ProcessUtils.GetLoadedModuleVersion("comctl32.dll");
if (version != null && version.FileMajorPart >= 6 && version.FileMinorPart >= 1)
{
// We can use TaskDialog...
}
else
{
// Use old style MessageBox
}
The enumeration of modules:
internal static FileVersionInfo GetLoadedModuleVersion(string name)
{
Process process = Process.GetCurrentProcess();
foreach (ProcessModule module in process.Modules)
{
if (module.ModuleName.ToLower() == name)
{
return module.FileVersionInfo;
}
return null;
}
}
In addition to what all the others are saying: This error will disappear if you set the ForceEmulationMode on PSTaskDialog to true.

Categories

Resources