I am trying to use two different windows UWP project in a Windows 10 cordova app. Both projects produce the same error. The code in one of the projects is as follows:
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage;
namespace DiskSpaceLibrary
{
public sealed class DiskSpace
{
internal static readonly StorageFolder[] APP_FOLDERS = {
ApplicationData.Current.LocalFolder,
ApplicationData.Current.RoamingFolder,
ApplicationData.Current.TemporaryFolder
};
[DataContract]
internal class Result
{
[DataMember]
internal ulong app = 0;
[DataMember]
internal ulong total = 0;
[DataMember]
internal ulong free = 0;
}
// Manually compute total size of the given StorageFolder
private static ulong sizeFolder(StorageFolder folder)
{
ulong folderSize = 0;
try
{
DirectoryInfo dirInfo = new DirectoryInfo(folder.Path);
// Get back a prefilled (with size) list of files contained in given folder
foreach (var fileInfo in dirInfo.EnumerateFiles("*", SearchOption.AllDirectories))
{
folderSize += (ulong)fileInfo.Length;
}
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e.ToString());
return 0;
}
return folderSize;
}
// Return the system FreeSpace and Capacity properties
private async static Task<IDictionary<string, object>> getExtraProperties()
{
var basicProperties = await Windows.Storage.ApplicationData.Current.LocalFolder.GetBasicPropertiesAsync();
return await basicProperties.RetrievePropertiesAsync(new string[] { "System.FreeSpace", "System.Capacity" });
}
// Class Entry point
public static IAsyncOperation<string> info(string args)
{
// Entry point in WinRT can not return Task<T> - so here is a trick to convert IAsyncOperation (WinRT) into classic C# async
return infoTask().AsAsyncOperation();
}
// The real disk space work is done here within some asynchronous stuff
private async static Task<string> infoTask()
{
Result result = new Result();
// Run folder discovery into another Thread to not block UI Thread
await Task.Run(() => {
foreach (var folder in APP_FOLDERS)
{
result.app += sizeFolder(folder);
}
});
await getExtraProperties().ContinueWith(propertiesTask =>
{
result.free = (ulong)propertiesTask.Result["System.FreeSpace"];
result.total = (ulong)propertiesTask.Result["System.Capacity"];
});
// Return JSON Result
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Result));
MemoryStream outputMs = new MemoryStream();
serializer.WriteObject(outputMs, result);
outputMs.Position = 0;
StreamReader sr = new StreamReader(outputMs);
return sr.ReadToEnd();
}
}
}
This project is from https://github.com/sqli/sqli-cordova-disk-space-plugin
It simply looks for used disk space and reports the used and available space using the System.IO.DirectoryInfo and the async methods to get the free space and capacity.
When I build this is it generates the winmd files no problems, I have correctly registered and loaded these in my cordova (Visual Studio 2017) project, Build for Windows 10 and run - when I run this code in the main cordova project
DiskSpacePlugin.info({}, function (ok) { console.log(ok); }, function (err) { console.log(err); });
I get this result in the console
WinRTError: The system cannot find the file specified.
System.IO.FileNotFoundException: Could not load file or assembly 'System.IO.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
at DiskSpaceLibrary.DiskSpace.sizeFolder(StorageFolder folder)
at DiskSpaceLibrary.DiskSpace.<>c__DisplayClass5_0.<infoTask>b__0()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.Ex
console-via-logger.js (173,15)
{
[functions]: ,
__proto__: { },
asyncOpCausalityId: 461,
asyncOpSource: { },
asyncOpType: "Windows.Foundation.IAsyncOperation`1<String>",
description: "The system cannot find the file specified.
System.IO.FileNotFoundException: Could not load file or assembly 'System.IO.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
at DiskSpaceLibrary.DiskSpace.sizeFolder(StorageFolder folder)
at DiskSpaceLibrary.DiskSpace.<>c__DisplayClass5_0.<infoTask>b__0()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.Ex",
message: "The system cannot find the file specified.
System.IO.FileNotFoundException: Could not load file or assembly 'System.IO.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
at DiskSpaceLibrary.DiskSpace.sizeFolder(StorageFolder folder)
at DiskSpaceLibrary.DiskSpace.<>c__DisplayClass5_0.<infoTask>b__0()
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.Ex",
name: "WinRTError",
number: -2147024894
}
I have also tried another module for unzipping files in a cordova windows 10 project (I do not have the source for this one however it comes from https://github.com/Culture22/cordova-windows10-zip) and it comes up with exactly the same error messages when I try to run it within the app.
I have googled and looked for this issue for the last 4 days and I am unable to progress, the methods being used are all support by the framework apparently looking at (msdn.microsoft.com/en-us/library/windows/apps/mt185496.aspx) - does anyone have any insight?
It seems like the library you're referencing references the System.IO.FileSystem.dll, however for whatever reason its not getting deployed with your application. I suggest try adding a nuget reference to System.IO.FileSystem.dll to your application.
Related
I have a Framework 4.8 C# app that uses ClearScript to allow JavaScript to be used as an extension language. I am able to write plugins as DLLs and attach them at runtime, viz
JSE.Script.attach = (Func<string, bool>)Attach;
...
private static bool Attach(string dllPath, string name = "")
{
var status = false;
var htc = new HostTypeCollection();
try
{
var assem = Assembly.Load(AssemblyName.GetAssemblyName(dllPath));
htc.AddAssembly(assem);
if (name.Length == 0)
{
name = assem.FullName.Split(',')[0];
}
JSE.AddHostObject(name, htc); //FIXME checkout the hosttypes
Console.Error.WriteLine($"Attached {dllPath} as {name}");
status = true;
}
catch (ReflectionTypeLoadException rtle)
{
foreach (var item in rtle.LoaderExceptions)
{
Console.Error.WriteLine(item.Message);
T.Fail(item.Message);
}
}
catch (FileNotFoundException fnfe)
{
Console.Error.WriteLine(fnfe.Message);
T.Fail(fnfe.Message);
}
catch (Exception e)
{
Console.Error.WriteLine(e.Message);
T.Fail(e.Message);
}
return status;
}
This permits my scripts to have lines like
attach(".\\Plugin_GoogleAds_Metrics.dll");
H = Plugin_GoogleAds_Metrics.GoogleAds_Metrics.Historical;
H.EnableTrace("GAM");
...
I've made a public repo of the plugin for those interested.
What's not working in this situation is that when I try to execute the plugin's GetAccountInformation method, and execution reaches the GoogleAdsServiceClient googleAdsService = client.GetService(Services.V11.GoogleAdsService); line, an error is thrown complaining about Google.Protobuf, viz
Exception has been thrown by the target of an invocation.
at JScript global code (Script [23] [temp]:5:0) -> acc = H.GetAccountInformation(auths.Item1, 7273576109, true)
at Microsoft.ClearScript.ScriptEngine.ThrowScriptError(IScriptEngineException scriptError)
at Microsoft.ClearScript.Windows.WindowsScriptEngine.ThrowScriptError(Exception exception)
at Microsoft.ClearScript.Windows.WindowsScriptEngine.<>c__DisplayClass57_0`1.<ScriptInvoke>b__0()
at Microsoft.ClearScript.ScriptEngine.ScriptInvokeInternal[T](Func`1 func)
at Microsoft.ClearScript.ScriptEngine.ScriptInvoke[T](Func`1 func)
at Microsoft.ClearScript.Windows.WindowsScriptEngine.ScriptInvoke[T](Func`1 func)
at Microsoft.ClearScript.Windows.WindowsScriptEngine.Execute(UniqueDocumentInfo documentInfo, String code, Boolean evaluate)
at Microsoft.ClearScript.Windows.JScriptEngine.Execute(UniqueDocumentInfo documentInfo, String code, Boolean evaluate)
at Microsoft.ClearScript.ScriptEngine.Evaluate(UniqueDocumentInfo documentInfo, String code, Boolean marshalResult)
at Microsoft.ClearScript.ScriptEngine.Evaluate(DocumentInfo documentInfo, String code)
at Microsoft.ClearScript.ScriptEngine.Evaluate(String documentName, Boolean discard, String code)
at Microsoft.ClearScript.ScriptEngine.Evaluate(String documentName, String code)
at Microsoft.ClearScript.ScriptEngine.Evaluate(String code)
at RulesetRunner.Program.Run(JScriptEngine& jSE, String scriptText, Config cfg, Dictionary`2 settings) in C:\Users\bugma\Source\Repos\Present\BORR\RulesetRunner\RunManagementPartials.cs:line 72
Exception has been thrown by the target of an invocation.
Exception has been thrown by the target of an invocation.
Could not load file or assembly 'Google.Protobuf, Version=3.15.8.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604' or one of its dependencies. The system cannot find the file specified.
So
I am using the latest Google.Ads.GoogleAds library
AutoGenerateBindingRedirects has been set to true in the csproj file
Add-BindingRedirect has been executed in the context of the Plugin's project
The Plugin_GoogleAds_Metrics.dll is in the same folder as the Google.Protobuf.dll
Where to from here?
What fixed this was including Google.Ads.GoogleAds in the calling app. I didn't have to explicitly mention the symbols in the main binary, just have the library in the build. What I expect this did was to include all the relevant DLLs next to the main EXE.
This is definitely not what I wanted. I wanted to be able to hive off all the DLLs into a separate plugin folder and only have them connected when I attached the plugin. Sadly, this does not seem to be achievable at this point. And now I'm wondering about the other plugins I've written that use Google technologies.
I'm writing a WinForms program that uses MEF to load assemblies. Those assemblies are not located in the same folder than the executable.
As I need to perform some file maintenance, I implemented some code in the file Program.cs, before loading the actual WinForm, so the files (even if assemblies) are not loaded (or shouldn't if they are) by the program.
I'm performing two operations:
- Moving a folder from one location to an other one
- Unzipping files from an archive and overwrite dll files from the folder moved (if file from the archive is newer than the one moved)
The problem is that after moving the folder, files in it are locked and cannot be overwritten. I also tried to move files one by one by disposing them when the move is finished.
Can someone explain me why the files are blocked and how I could avoid that
Thanks
private static void InitializePluginsFolder()
{
if (!Directory.Exists(Paths.PluginsPath))
{
Directory.CreateDirectory(Paths.PluginsPath);
}
// Find archive that contains plugins to deploy
var assembly = Assembly.GetExecutingAssembly();
if (assembly.Location == null)
{
throw new NullReferenceException("Executing assembly is null!");
}
var currentDirectory = new FileInfo(assembly.Location).DirectoryName;
if (currentDirectory == null)
{
throw new NullReferenceException("Current folder is null!");
}
// Check if previous installation contains a "Plugins" folder
var currentPluginsPath = Path.Combine(currentDirectory, "Plugins");
if (Directory.Exists(currentPluginsPath))
{
foreach (FileInfo fi in new DirectoryInfo(currentPluginsPath).GetFiles())
{
using (FileStream sourceStream = new FileStream(fi.FullName, FileMode.Open))
{
using (FileStream destStream = new FileStream(Path.Combine(Paths.PluginsPath, fi.Name), FileMode.Create))
{
destStream.Lock(0, sourceStream.Length);
sourceStream.CopyTo(destStream);
}
}
}
Directory.Delete(currentPluginsPath, true);
}
// Then updates plugins with latest version of plugins (zipped)
var pluginsZipFilePath = Path.Combine(currentDirectory, "Plugins.zip");
// Extract content of plugins archive to a temporary folder
var tempPath = string.Format("{0}_Temp", Paths.PluginsPath);
if (Directory.Exists(tempPath))
{
Directory.Delete(tempPath, true);
}
ZipFile.ExtractToDirectory(pluginsZipFilePath, tempPath);
// Moves all plugins to appropriate folder if version is greater
// to the version in place
foreach (var fi in new DirectoryInfo(tempPath).GetFiles())
{
if (fi.Extension.ToLower() != ".dll")
{
continue;
}
var targetFile = Path.Combine(Paths.PluginsPath, fi.Name);
if (File.Exists(targetFile))
{
if (fi.GetAssemblyVersion() > new FileInfo(targetFile).GetAssemblyVersion())
{
// If version to deploy is newer than current version
// Delete current version and copy the new one
// FAILS HERE
File.Copy(fi.FullName, targetFile, true);
}
}
else
{
File.Move(fi.FullName, targetFile);
}
}
// Delete temporary folder
Directory.Delete(tempPath, true);
}
Check the implementation of the GetAssemblyVersion() method used in this part of code:
if (File.Exists(targetFile))
{
if (fi.GetAssemblyVersion() > new FileInfo(targetFile).GetAssemblyVersion())
{
// If version to deploy is newer than current version
// Delete current version and copy the new one
// FAILS HERE
File.Copy(fi.FullName, targetFile, true);
}
}
fi variable has type FileInfo, GetAssemblyVersion() looks like an extension method. You should check how assembly version is retrieved from the file. If this method loads an assembly it should also unload it to release the file.
The separate AppDomain is helpful if you need to load the assembly, do the job and after that unload it. Here is the GetAssemblyVersion method implementation:
public static Version GetAssemblyVersion(this FileInfo fi)
{
AppDomain checkFileDomain = AppDomain.CreateDomain("DomainToCheckFileVersion");
Assembly assembly = checkFileDomain.Load(new AssemblyName {CodeBase = fi.FullName});
Version fileVersion = assembly.GetName().Version;
AppDomain.Unload(checkFileDomain);
return fileVersion;
}
The following implementation of the GetAssemblyVersion() could retrieve the assembly version without loading assembly into your AppDomain. Thnx #usterdev for the hint. It also allows you to get the version without assembly references resolve:
public static Version GetAssemblyVersion(this FileInfo fi)
{
return AssemblyName.GetAssemblyName(fi.FullName).Version;
}
You have to make sure that you are not loading the Assembly into your domain to get the Version from it, otherwise the file gets locked.
By using the AssemblyName.GetAssemblyName() static method (see MSDN), the assembly file is loaded, version is read and then unloaded but not added to your domain.
Here an extension for FileInfo doing so:
public static Version GetAssemblyVersion(this FileInfo fi)
{
AssemblyName an = AssemblyName.GetAssemblyName(fi.FullName);
return an.Version;
}
The below statement locks the file
destStream.Lock(0, sourceStream.Length);
but after that you havent unlocked the file. Perhaps that is the cause of your problem.
I would start checking if you program has actually already loaded the assembly.
two suggestions:
1 - Call a method like this before calling your InitializePluginsFolder
static void DumpLoadedAssemblies()
{
var ads = AppDomain.CurrentDomain.GetAssemblies();
Console.WriteLine(ads.Length);
foreach (var ad in ads)
{
Console.WriteLine(ad.FullName);
// maybe this can be helpful as well
foreach (var f in ad.GetFiles())
Console.WriteLine(f.Name);
Console.WriteLine("*******");
}
}
2 - In the first line of Main, register for AssemblyLoad Event and dump Loaded Assembly in the event handler
public static void Main()
{
AppDomain.CurrentDomain.AssemblyLoad += OnAssemlyLoad;
...
}
static void OnAssemlyLoad(object sender, AssemblyLoadEventArgs args)
{
Console.WriteLine("Assembly Loaded: " + args.LoadedAssembly.FullName);
}
You definitely load assembly using AssemblyName.GetAssemblyName, unfortunately .NET has no conventional ways of checking assembly metadata without loading assembly. To avoid this you can:
Load assembly in separated AppDomain as Nikita suggested, I can add: load it with ReflectionOnlyLoad
Or get assembly version using Mono.Cecil library as Reflector does
Just for completeness: actually you can load assembly into same AppDomain without locking assembly file in two stage: read file contents into byte[] and using Assembly.Load(byte[] rawAssembly) but this way has serious "Loading Context" issues and what will you do with several loaded assemblies :)
I am attempting to create a PCL assembly using Roslyn (Microsoft.CodeAnalysis).
I'm referencing PCL assemblies located at "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETPortable\v4.5\Profile\Profile259". Here is my code that compiles the actual assembly.
var assemblyName = string.Concat("ODataHQ.SDK.", accountKey, ".dll");
var source = GenerateAccountSource(accountKey, workspace);
var assemblyInfoSource = GetAssemblyInfo(assemblyName);
var assemblyTree = CSharpSyntaxTree.ParseText(assemblyInfoSource);
var tree = CSharpSyntaxTree.ParseText(source);
// Lets add PCL framework assemblies.
var frameworkFiles = new[] {"mscorlib.dll", "Microsoft.CSharp.dll", "System.dll", "System.Core.dll", "System.Runtime.dll"};
var references = frameworkFiles
.Select(file => Path.Combine(Settings.PCLProfilePath, file))
.Select(fullPath => MetadataReference.CreateFromFile(fullPath))
.Cast<MetadataReference>()
.ToList();
// Lets add third-party dependent assemblies.
references.AddRange(Directory.GetFiles(Settings.SDKDependencyPath, "*.dll")
.Select(file => MetadataReference.CreateFromFile(file)));
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var compilation = CSharpCompilation.Create(assemblyName, new [] { assemblyTree, tree }, references, options);
var ms = new MemoryStream();
var result = compilation.Emit(ms);
if (result.Success)
{
// Reset stream position to read from beginning.
ms.Position = 0;
return ms;
}
// Destroy memory stream since it didn't compile successfully.
ms.Dispose();
var firstError = result.Diagnostics
.Where(d => d.Severity == DiagnosticSeverity.Error)
.Select(d => d.GetMessage())
.FirstOrDefault();
throw new CompilationException(firstError);
Here is my GetAssemblyInfo method:
private string GetAssemblyInfo(string assemblyName)
{
return #"using System.Reflection;
using System.Runtime.Versioning;
[assembly: AssemblyTitle(""" + assemblyName + #""")]
[assembly: AssemblyVersion(""1.0.*"")]
[assembly: AssemblyFileVersion(""1.0.*"")]
[assembly: TargetFramework("".NETPortable,Version=v4.5,Profile=Profile259"", FrameworkDisplayName="".NET Portable Subset"")]";
}
I take the assembly that is generated and save it to disk. Then reference it in another console app project. However, when I run the console app and try to use a type from the dynamically generated PCL assembly, I get the following error.
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll
Additional information: Could not load file or assembly 'ODataHQ.SDK.dvester.dll, Version=1.0.5635.36199, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Can someone help me figure out what's going wrong?
Check the FusionLog property of the exception (you may need to enable that in the registry).
This will tell you why it failed.
This is code thai word segmentation by use ICU4NET:
using ICU4NET;
using ICU4NETExtension;
static void Main(string[] args)
{
var sb = new StringBuilder();
var col = new List<string>();
using (BreakIterator bi = BreakIterator.CreateWordInstance(Locale.GetUS()))
{
bi.SetText(Content2);
int start = bi.First(), end = bi.Next();
while (end != BreakIterator.DONE)
{
col.Add(Content2.Substring(start, end - start));
start = end; end = bi.Next();
}
}
}
I write by use program Visual studio 2008
but it error because "Could not load file or assembly 'ICU4NET, Version=1.0.3891.39017, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format". I do not know what it is.
How to use ICU4NET
Add references to ICU4NET.dll and ICU4NETExtension.dll.
Make sure that ICU4C's DLLs, including icudt42.dll, icuin42.dll, icuio42.dll, icule42.dll, iculx42.dll, icutu41.dll, and icuuc42.dll, are in the %PATH% or in the working directory of your exe program.
I am still getting System.IO.FileNotFound Exception when I even try to use NRefactory.
I tried many ways to get it working:
- Used NuGet package, which istalled Mono.Cecil automatically
- downloaded NRefactory and Mono.Cecil, and compiled all DLL's from VS2010.
What am I doing wrong?
Here is error dump:
[System.IO.FileNotFoundException]
{"Could not load file or assembly 'ICSharpCode.NRefactory, Version=4.2.0.8783,
Culture=neutral, PublicKeyToken=efe927acf176eea2' or one of its dependencies.
The system cannot find the file specified.":"ICSharpCode.NRefactory,
Version=4.2.0.8783, Culture=neutral, PublicKeyToken=efe927acf176eea2"}
System.IO.FileNotFoundException
EDIT:
This is code which causes problems:
List<CodeElement> methodsInvokedByGivenMethod = GetInvokedMethods(methodName, fileName);
And this is a body of method:
private List<CodeElement> GetInvokedMethods(string methodName, string itemWhereMethodIs)
{
MessageBox.Show("I am here");
try
{
using (var fs = File.OpenRead(itemWhereMethodIs))
{
using (var parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, new StreamReader(fs)))
{
parser.Parse();
}
}
}
catch (System.IO.FileNotFoundException fnf)
{
// This exception arises in Nrefactory...WTF? 0_0
SetToolStripText("There is exception :(");
return null;
}
}
What is more important, Exception is not being catched by try-catch block within this method, but occurs outside this method -> when it is called, but before any line of code within it.