Is it possible to communicate with AppServiceConnection and uwp in WinForm? Error: does not contain the definition of "GetAwaiter", this is my code:
Thank you!
This is the code in WinForm:
private AppServiceConnection calculatorService;
static Form1 mainForm;
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
//Add the connection
if (calculatorService == null)
{
calculatorService = new AppServiceConnection();
calculatorService.AppServiceName = "com.yanscorp.appservicedemo.Values";
calculatorService.PackageFamilyName = "c97887ad-1f75-4b48-9e3b-21b89c061715_6evysfdvxt248";
var status = await calculatorService.OpenAsync();//A mistake here
if (status != AppServiceConnectionStatus.Success)
{
string d = "Failed to connect";
return;
}
}
var message = new ValueSet();
message.Add("Request", "GetCallCount");
AppServiceResponse response = await calculatorService.SendMessageAsync(message);//A mistake here
string result = "";
if (response.Status == AppServiceResponseStatus.Success)
{
result = response.Message["Response"] as string;
// Get the data that the service sent to us.
textBlock.Text = result;
}
}
Error:
错误 CS4036 “IAsyncOperation”不包含“GetAwaiter”的定义,并且找不到可接受类型为“IAsyncOperation”的第一个参数的扩展方法“GetAwaiter”(是否缺少针对“System”的 using 指令?) WindowsFormsApplication1
Is it possible to communicate with AppServiceConnection and uwp in WinForm
Yes. You could use App service in WinForm. Check this article for more details.
Error: does not contain the definition of "GetAwaiter"
You could access the Windows 10 APIs in WinForm by reference winmd file and System.Runtime.WindowsRuntime.dll. It looks like you have already referenced winmd , but you may forget to reference System.Runtime.WindowsRuntime.dll which you could find it in the directory C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5.
Adding the reference of System.Runtime.WindowsRuntime.dll will resolve your issue. Details please reference Calling Windows 10 APIs From a Desktop Application.
Related
I have a Xamarin Project where I generate a .pdf file from scratch and save it in my local storage. This works perfectly fine and can find it and open it in the disk where I saved it. However, I need to open the .pdf file immediately after creation programmatically.
I already tried different variations using Process and ProcessStartInfo but these just throw errors like "System.ComponentModel.Win32Exception: 'The system cannot find the file specified'" and "'System.PlatformNotSupportedException'".
This is basically the path I am trying to open using Process.
var p = Process.Start(#"cmd.exe", "/c start " + #"P:\\Receiving inspection\\Inspection Reports\\" + timestamp + ".pdf");
I also tried ProcessStartInfo using some variations but I'm getting the same errors all over and over.
var p = new Process();
p.StartInfo = new ProcessStartInfo(#"'P:\\Receiving inspection\\Inspection Reports\\'" + timestamp + ".pdf");
p.Start();
The better way is that use LaunchFileAsync method to open file with browser. You could create FileLauncher DependencyService to invoke uwp LaunchFileAsync method from xamarin share project.
Interface
public interface IFileLauncher
{
Task<bool> LaunchFileAsync(string uri);
}
Implementation
[assembly: Dependency(typeof(UWPFileLauncher))]
namespace App14.UWP
{
public class UWPFileLauncher : IFileLauncher
{
public async Task<bool> LaunchFileAsync(string uri)
{
var file = await Windows.Storage.StorageFile.GetFileFromPathAsync(uri);
bool success = false;
if (file != null)
{
// Set the option to show the picker
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = true;
// Launch the retrieved file
success = await Windows.System.Launcher.LaunchFileAsync(file, options);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
else
{
// Could not
}
return success;
}
}
}
Usage
private async void Button_Clicked(object sender, EventArgs e)
{
await DependencyService.Get<IFileLauncher>().LaunchFileAsync("D:\\Key.pdf");
}
Please note if you want to access D or C disk in uwp, you need add broadFileSystemAccess capability. for more please refer this .
Update
If the UWP files are network based, not local zone based, you could use Xamarin.Essentials to open file with browser. And you must specify the privateNetworkClientServer capability in the manifest. For more please refer this link.
I am trying to drag from another windows application (EM Client, thunderbird or outlook) onto my form. When an email is dragged from the other application to windows explore it will drop as a file. If the user drags onto my application I would like to get the file contents as a file stream.
I was able to get this working with a UWP app, but I need to get it working in a Windows Form app so it will work in Windows 7.
I have found lots of examples of going the other way (dragging from App to windows).
The thing that makes this so annoying is it is easy in the UWP app.
Here is how I did it in the UWP app, the results of which is I get a new file saved in the roaming folder at name "email.eml":
XAML
<Grid AllowDrop="True" DragOver="Grid_DragOver" Drop="Grid_Drop"
Background="LightBlue" Margin="10,10,10,353">
<TextBlock>Drop anywhere in the blue area</TextBlock>
</Grid>
XAML.CS
namespace App1
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Grid_DragOver(object sender, DragEventArgs e)
{
e.AcceptedOperation = DataPackageOperation.Copy;
}
private async void Grid_Drop(object sender, DragEventArgs e)
{
if (e.DataView.Contains(StandardDataFormats.StorageItems))
{
var items = await e.DataView.GetStorageItemsAsync();
if (items.Count > 0)
{
var storageFile = items[0] as StorageFile;
var reader = (await storageFile.OpenAsync(FileAccessMode.Read));
IBuffer result = new byte[reader.Size].AsBuffer();
var test = await reader.ReadAsync(result, result.Length,Windows.Storage.Streams.InputStreamOptions.None);
Windows.Storage.StorageFolder storageFolder =
Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile = await storageFolder.CreateFileAsync("email.eml",Windows.Storage.CreationCollisionOption.ReplaceExisting);
await Windows.Storage.FileIO.WriteBufferAsync(sampleFile, test);
}
}
}
}
}
I have read every article that that is listed on this answer, plus more:
Trying to implement Drag and Drop gmail attachment from chrome
Basically no matter how I attack it I end up with one of 3 results:
a exception for "Invalid FORMATETC structure (Exception from HRESULT: 0x80040064(DV_E_FORMATETC))"
my MemoryStream is null
I get a security violation
This is the Code that gets a security violation:
MemoryStream ClipboardMemoryStream = new MemoryStream();
BinaryFormatter bft = new BinaryFormatter();
bft.Serialize(ClipboardMemoryStream, e.Data.GetData("FileGroupDescriptorW", false));
byte[] byteArray = ClipboardMemoryStream.ToArray();
My guess is that I need to implement the e.Data.GetData("FileGroupDesciptorW") is returning a IStorage Class, and I need to implement that class, but I am loss on how to do it, plus I am not sure that is the case
e.Data.GetType shows its a marshalbyrefobject, I have attempted to do the Remoting manually, but I got stuck on not having an open channel.
https://learn.microsoft.com/en-us/windows/desktop/api/objidl/nn-objidl-istorage
https://learn.microsoft.com/en-us/windows/desktop/shell/datascenarios#dragging-and-dropping-shell-objects-asynchronously
So After reaching out to a professional for help I have a working example. The trick was to get "FileDescriptorW" working in the Custom ComObject class. You will find a version of this class in the Drag from Outlook example but it does not work when dragging from EM Client, this does.
Here is the Code:
Code is too Big to post
Then You can use it like this:
MyDataObject obj = new MyDataObject(e.Data);
string[] fileNames = { };
//ThunderBird Does a FileDrop
if (obj.GetDataPresent(DataFormats.FileDrop, true))
{
string[] tempFileNames = (string[])obj.GetData(DataFormats.FileDrop);
List<string> tempFileNameList = new List<string>();
foreach(string f in tempFileNames)
{
tempFileNameList.Add(Path.GetFileName(f));
}
fileNames = tempFileNameList.ToArray();
} else if (fileNames.Length == 0)
{
//EM Client uses "FileGroupDescriptorW"
fileNames = (string[])obj.GetData("FileGroupDescriptorW");
}else if (fileNames.Length == 0)
{
//Outlook Uses "FileGroupDescriptor"
fileNames = (string[])obj.GetData("FileGroupDescriptor");
}
int index = 0;
foreach (string f in fileNames)
{
File.WriteAllBytes("C:\\FilePath\\"+f, obj.GetData("FileContents", index).ToArray());
index++;
}
Using the VLC library provided by Vlc.DotNet, I have tried to implement it in a simple WPF.
I copied exactly the code from the repository, and got the NuGet online, but can't seem to make it work. I get a Directory Not Found exception straight from the load of the file on the disk.
Here is my code:
public MainWindow()
{
InitializeComponent();
VLCControl.MediaPlayer.VlcLibDirectoryNeeded += OnVlcControlNeedsLibDirectory;
}
private void OnVlcControlNeedsLibDirectory(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e)
{
var currentAssembly = Assembly.GetEntryAssembly();
var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;
if (currentDirectory == null)
return;
if (AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86)
e.VlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(currentDirectory, #"..\..\..\lib\x86\"));
else
e.VlcLibDirectory = new DirectoryInfo(System.IO.Path.Combine(currentDirectory, #"..\..\..\lib\x64\"));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var d = new Microsoft.Win32.OpenFileDialog();
d.Multiselect = false;
if (d.ShowDialog() == true)
{
Uri src = new Uri(d.FileName);
VLCControl.MediaPlayer.Play(src); //Exception here
}
}
VLCControl being the VLC control in the xaml.
By changing the VlcLibDirectory with another path where I put the libraries (for example the root of application), I get this StackTrace :
at Vlc.DotNet.Core.Interops.VlcInteropsManager..ctor(DirectoryInfo dynamicLinkLibrariesPath)
at Vlc.DotNet.Core.Interops.VlcManager..ctor(DirectoryInfo dynamicLinkLibrariesPath)
at Vlc.DotNet.Core.Interops.VlcManager.GetInstance(DirectoryInfo dynamicLinkLibrariesPath)
at Vlc.DotNet.Core.VlcMediaPlayer..ctor(DirectoryInfo vlcLibDirectory)
at Vlc.DotNet.Forms.VlcControl.EndInit()
at Vlc.DotNet.Forms.VlcControl.Play(Uri uri, String[] options)
at VLCTest.MainWindow.Button_Click(Object sender, RoutedEventArgs e) in c:\Users\ME\Documents\Visual Studio 2013\Projects\VLCTest\VLCTest\MainWindow.xaml.cs:ligne 56
The code becomes :
if(AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86)
e.VlcLibDirectory = new DirectoryInfo(currentDirectory);
else
e.VlcLibDirectory = new DirectoryInfo(currentDirectory);
Thank you for your help.
The problem is definitely with your library path, though you have to debug the problem yourself in order to find the exact discrepancy between provided path and actual path.
The misunderstanding may be, which libraries are missing. You do have the Vlc.DotNet.Core.Interops.dll but your are missing the nativ libraries behind. This is the reason, why the exception occurs inside Vlc.DotNet.Core.Interops.dll when it tries to load the actual libraries.
The OnVlcControlNeedsLibDirectory function is called inside VLCControl.MediaPlayer.Play(src);, so the Path from OpenFileDialog has nothing to do with the problem.
Steps I taken to reproduce / fix:
Downloaded your project
Tested / Debugged
Exception occurred as you describe
Downloaded the libraries from Vlc.DotNet repository
Changed the paths to absolute values
Tested / Debugged again
Successfully played a music file
Another exception occured on closing (different story alltogether)
My folder layout:
Solution path:
D:\Programmierung\VLCTest-VAlphaTesting\VLCTest-VAlphaTesting\
Actual Assembly location on execute
D:\Programmierung\VLCTest-VAlphaTesting\VLCTest-VAlphaTesting\VLCTest\bin\Debug
ProcessorArchitecture: x86
Library Path:
D:\Programmierung\Vlc.DotNet-master\Vlc.DotNet-master\lib\x86
Contents of library path:
plugins (folder)
.keep (file)
libvlc.dll (file)
libvlccore.dll (file)
For testing purposes I hardcoded the library path - you may want to do that as well
if (AssemblyName.GetAssemblyName(currentAssembly.Location).ProcessorArchitecture == ProcessorArchitecture.X86)
e.VlcLibDirectory = new DirectoryInfo(#"D:\Programmierung\Vlc.DotNet-master\Vlc.DotNet-master\lib\x86");
else
e.VlcLibDirectory = new DirectoryInfo(#"D:\Programmierung\Vlc.DotNet-master\Vlc.DotNet-master\lib\x64");
i have done a server using this example socketAsyncEventArgs
in visual studio 2010 and .net 4.0.
Now i'm trying to connect to it from a windows 8 app using StreamSocket but i'm getting a "Acces denied" message.
here is the Client code:
private StreamSocket streamSocket;
public string Server = "192.168.0.101";
public int Port = 9900;
public async void Connect()
{
streamSocket = new StreamSocket();
Connect();
try
{
await streamSocket.ConnectAsync(
new Windows.Networking.HostName(Server),
Port.ToString()); // getting Acces Denied here
DataReader reader = new DataReader(streamSocket.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
while (true)
{
var bytesAvailable = await reader.LoadAsync(1000);
var byteArray = new byte[bytesAvailable];
reader.ReadBytes(byteArray);
}
}
catch (Exception e)
{
MessageBox(e.StackTrace);
}
}
How to fix the problem? Is there another way to send and receive messages using this server?
You are probably also seeing the following as part of your error message:
WinRT information: A network capability is required to access this network resource
This is because you need to add a capability to your application that allows you to access local networks. Double click on the Package.appxmanifest file in your project. Click on the Capabilities tab. Add the Private Networks (Client & Server) capability to your project.
A while back I wrote a silverlight user control which had a csv import/export feature. This has been working fine, until recently I discovered it erroring in one scenario. This may have been due to moving to Silverlight 3.
The Error:
Message: Unhandled Error in Silverlight 2 Application
Code: 4004
Category: ManagedRuntimeError
Message: System.Security.SecurityException: Dialogs must be user-initiated.
at System.Windows.Controls.OpenFileDialog.ShowDialog()
at MyControl.OpenImportFileDialog()
at ...
The Code:
private void BrowseFileButton_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(lblFileName.Text))
{
if (MessageBox.Show("Are you sure you want to change the Import file?", "Import", MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
return;
}
}
EnableDisableImportButtons(false);
var fileName = OpenImportFileDialog();
lblFileName.Text = fileName ?? string.Empty;
EnableDisableImportButtons(true);
}
private string OpenImportFileDialog()
{
var dlg = new OpenFileDialog { Filter = "CSV Files (*.csv)|*.csv" };
if (dlg.ShowDialog() ?? false)
{
using (var reader = dlg.File.OpenText())
{
string fileName;
//process the file here and store fileName in variable
return fileName;
}
}
}
I can open an import file, but if i want to change the import file, and re-open the file dialog, it errors. Does anyone know why this is the case?
Also, I am having trouble debugging because placing a breakpoint on the same line (or prior) to the dlg.ShowDialog() call seems to cause this error to appear as well.
Any help would be appreciated?
You do two actions on one user click.
You show a messagebox which effectively uses your permission to show a dialog on user action.
You then try to show the dialog, since this is a second dialog on user action it's not allowed.
Get rid of the confirmation dialog and you'll be fine.
Remove Break Points before if (dlg.ShowDialog() ?? false) code will run its work for me.