When attempting to download and write a file as a local user (ie, not run as admin), the following code is throwing an UnauthorizedAccessException(Access to the path is denied.). Originally, I assumed that this was due to the application attempting to write files directly to the C drive. However, I get the same error when attempting to save files to the local user's documents drive, as gotten by this:
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
This seems to be a windows 10 specific issue, as the application runs fine in previous versions of windows (even writing directly to C:// as a local user, which I had thought would be blocked).
private bool DownloadFile(Stream srcStream, string dstFile)
{
bool success = false;
byte[] buffer = new byte[16384];
int byteCount;
FileStream destStream = null;
try
{
destStream = File.Create(dstFile);
while ((byteCount = srcStream.Read(buffer, 0, 16384)) != 0)
{
destStream.Write(buffer, 0, byteCount);
}
success = true;
}
catch(Exception)
{
return success;
}
finally
{
try { destStream.Close(); }
catch (Exception) { }
}
return success;
}
I have checked, and the local user account has full access to their Documents folder, so I'm stumped as to why this isn't working.
Ok I just did a unit test with your code.
The problem is
destStream = File.Create(dstFile);
This is a folder not a file!
try this:
destStream = File.Create(dstFile + "\Test.txt");
And tadaaaaa. No more exception ;)
You can not write into a folder. only inside file.
and please use using() when needed :)
Unit test:
[TestMethod]
public void TestMethod1()
{
var path = Environment.GetFold`enter code here`erPath(Environment.SpecialFolder.Personal);
// path = "C:\Users\pix\Documents"
using (var memoryStream = new MemoryStream())
{
var result = DownloadFile(memoryStream, path);
Assert.IsFalse(result);
result = DownloadFile(memoryStream, Path.Combine("FILE.txt"));
Assert.IsTrue(result);
}
}
private bool DownloadFile(Stream srcStream, string dstFile)
{
bool success = false;
byte[] buffer = new byte[16384];
int byteCount;
FileStream destStream = null;
try
{
destStream = File.Create(dstFile);
while ((byteCount = srcStream.Read(buffer, 0, 16384)) != 0)
{
destStream.Write(buffer, 0, byteCount);
}
success = true;
}
catch (Exception ex)
{
return success;
}
finally
{
try { destStream.Close(); }
catch (Exception) { }
}
return success;
}
Related
I've created a service, which "locks" the desktop background, so you can't change it. In general, the service compares the current wallpaper with the one I want to be the new wallpaper. If it's not the same, it gets overwritten. This is my OnTimer()-Method, which gets executed every 2 seconds:
private void OnTimer(object sender, ElapsedEventArgs e)
{
if (!File.Exists("C:/Program Files/image.jpg"))
{
Assembly myAssembly = Assembly.GetExecutingAssembly();
Stream s = myAssembly.GetManifestResourceStream("MsService.Gandalf.jpg"); ;
byte[] b;
using (BinaryReader br = new BinaryReader(s))
{
b = br.ReadBytes((int)s.Length);
}
while (true)
{
try
{
File.WriteAllBytes("C:/Program Files/image.jpg", b);
break;
}
catch (Exception)
{
//stuff
}
}
}
//{path} is %Appdata%
if (!FileEquals($"{path}\\Microsoft\\Windows\\Themes\\TranscodedWallpaper", "C:/Program Files/image.jpg"))
{
byte[] file = File.ReadAllBytes("C:/Program Files/image.jpg");
while (true)
{
try
{
File.WriteAllBytes($"{path}\\Microsoft\\Windows\\Themes\\TranscodedWallpaper", file);
break;
}
catch (Exception)
{
//stuff
}
}
}
}
That's the FileEquals Method:
static bool FileEquals(string path1, string path2)
{
byte[] file1 = File.ReadAllBytes(path1);
byte[] file2 = File.ReadAllBytes(path2);
if (file1.Length == file2.Length)
{
for (int i = 0; i < file1.Length; i++)
{
if (file1[i] != file2[i])
{
return false;
}
}
return true;
}
return false;
}
When I start the service, It only changes the wallpaper if I change it actively, even if it already is another one that the one I want it to be, and only once. The service outputs no error when debugging, and the service doesn't crash. Also when I change the wallpaper, the breakpoints in the if(!File.Equals(...)) gets triggered. Virus scanner isn't alerting anything too. Why doesn't it work anyway?
I am trying to use Microsoft Cognitive Face API for the first time. Documentation gives quite a simple method to detect face from memory stream. I am trying to detect faces from images located inside a folder. Right now there is only one image inside the folder. The issue is whenever the control reaches the following line:
var faces = await faceServiceClient.DetectAsync(memStream, true, true);
it terminates without any exception or error. Here is the complete code I have written.
using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Common;
using Microsoft.ProjectOxford.Face.Contract;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace FaceDetection.FaceDetect
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Face Detect";
Start();
}
static async Task Stop()
{
await Close();
}
private static Task Close()
{
return Task.Run(() =>
{
Environment.Exit(0);
});
}
static async Task ReStart(string _reason = "")
{
Console.WriteLine(_reason + "To restart the process press 'R'. To exit press 'X'");
var _response = Console.ReadLine();
if (_response == "r" || _response == "R")
await Start();
else
await Stop();
}
static async Task Start()
{
Console.Clear();
Console.WriteLine("Enter Folder Path");
string imageFolderPath = Console.ReadLine();
if (!Directory.Exists(imageFolderPath))
{
await ReStart("Folder does not exist! ");
}
else
{
await SaveFiles(imageFolderPath);
}
}
static async Task SaveFiles(string imageFolderPath)
{
try
{
DirectoryInfo dInfo = new DirectoryInfo(imageFolderPath);
string[] extensions = new[] { ".jpg", ".jpeg" };
FileInfo[] files = dInfo.GetFiles()
.Where(f => extensions.Contains(f.Extension.ToLower()))
.ToArray();
if (files.Length == 0)
await ReStart("No files found in the specified folder! ");
else
{
string subscriptionKey = "ADSFASDFASDFASDFASDFASDFASDF";
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["subscriptionKey"]))
subscriptionKey = ConfigurationManager.AppSettings["subscriptionKey"].ToString();
//var stringFaceAttributeType = new List<FaceAttributeType> { FaceAttributeType.Smile, FaceAttributeType.Glasses, FaceAttributeType.Gender, FaceAttributeType.Age };
//IEnumerable<FaceAttributeType> returnFaceAttributes = stringFaceAttributeType;
IFaceServiceClient faceServiceClient = new FaceServiceClient(subscriptionKey);
foreach (FileInfo file in files)
{
try
{
using (FileStream fileStream = File.OpenRead(imageFolderPath + "\\" + file.Name))
{
MemoryStream memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
//Used following commented code to make sure MemoryStream is not corrupted.
//FileStream _file = new FileStream(imageFolderPath + "\\test.jpg", FileMode.Create, FileAccess.Write);
//memStream.WriteTo(_file);
//_file.Close();
//memStream.Close();
try
{
//This line never returns a result. The execution terminates without any exception/error.
var faces = await faceServiceClient.DetectAsync(memStream, true, true);
if (faces != null)
{
foreach (var face in faces)
{
var rect = face.FaceRectangle;
var landmarks = face.FaceLandmarks;
}
}
else
Console.WriteLine("No face found in image: " + file.FullName);
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
}
catch (Exception ex)
{
Console.WriteLine("There was an error!");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("There was an error!");
}
await ReStart();
}
}
}
Can someone point out what am I missing. Why is this code not working?
When you read the file in to the MemoryStream, your read pointer is advanced to the end. So memStream passed in to DetectAsync() appears empty. The fact is you need not copy your file to memory. You could simply pass in the FileStream after opening.
using (FileStream fileStream = File.OpenRead(imageFolderPath + "\\" + file.Name))
{
try
{
var faces = await faceServiceClient.DetectAsync(fileStream, true, true);
if (faces != null)
{
foreach (var face in faces)
{
var rect = face.FaceRectangle;
var landmarks = face.FaceLandmarks;
}
}
else
{
Console.WriteLine("No face found in image: " + file.FullName);
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
Alternatively, you can rewind the memory stream by setting memStream.Position = 0 before calling DetectAsync.
I would like to unzip a zip file from sd card to /internal_Storage. It works very well without problem, proccess finished successfully.
The problem occurs when I suddenly unplug the card, then I got this exception:
Unhandled Exception:
System.IO.IOException: Invalid handle to path "/mnt/sdcard/Sounds.zip"
After application crashs.
string zipFile = #"/mnt/Sounds.zip";
string unZipSoundsFolderPath = #"/data/internal_Storage/Sounds/";
using (var zipInputStream = new ZipInputStream(System.IO.File.OpenRead(zipFile)))
{
ZipEntry ze = null;
try
{
while ((ze = zipInputStream.NextEntry) != null)
{
if (ze.IsDirectory)
{
if (!Directory.Exists(unZipSoundsFolderPath + ze.Name))
{
Directory.CreateDirectory(unZipSoundsFolderPath + ze.Name);
}
continue;
}
FileStream fout = new FileStream(unZipSoundsFolderPath + ze.Name, FileMode.Create);
BufferedStream bfout = new BufferedStream(fout);
try
{
byte[] buffer = new byte[2048];
int read = 0;
while ((read = zipInputStream.Read(buffer)) != -1) //THIS ROW DROPS EXCEPTION
{
bfout.Write(buffer, 0, read);
}
}
catch (System.IO.IOException exs)//HERE NOT CAUGHT EXCEPTION
{
break;
}
catch (Java.IO.IOException jex)//HERE NOT CAUGHT EXCEPTION
{
break;
}
zipInputStream.CloseEntry();
bfout.Close();
fout.Close();
}
}
catch (System.IO.IOException exs)
{
System.Diagnostics.Debug.WriteLine(exs.Message);
importIsSuccessful = false;
}
catch (Java.IO.IOException)
{
importIsSuccessful = false;
}
catch(Exception ex)
{
importIsSuccessful = false;
}
zipInputStream.Close();
}
I have done many things, but everytime when sd card is unplugged, application will crush. Thanks for your help!
When a using block exits, it calls the Dispose() on the instance it is 'controlling'. Your using block is around zipInputStream, so when the using blocks shuts down, the Dispose() method on zipInputStream will be called. It is possible that this exception is being thrown from within zipInputStream's Dispose method. Add a try block around the using block to test this hypothesis.
I have A C# Visual Studio 2012 Solution that relies on a native dll that I use PInvoke to access. When I deploy the app I will have to ensure that this Dll is in the app folder.
Is there anyway I can merge this Dll into the executable?
perhaps as a resource?
I have heard of ILMerge but I am told it cant cope with native code.
Any help would be appreciated.
You can create a Setup package project with Visual Studio that deploys all your files to the correct location or use other third party packaging software (like full InstallShield or alternatives)
However, your question reminds me on the Open Hardware Monitor project where they include drivers as embedded resource and extract them when the user starts the application. It works like this: they've added WinRing0.sys and WinRing0x64.sys to the project and set their Build Action to Embedded Resource, then they have a method that extracts the driver from the resource:
private static bool ExtractDriver(string fileName) {
string resourceName = "OpenHardwareMonitor.Hardware." +
(OperatingSystem.Is64BitOperatingSystem() ? "WinRing0x64.sys" :
"WinRing0.sys");
string[] names =
Assembly.GetExecutingAssembly().GetManifestResourceNames();
byte[] buffer = null;
for (int i = 0; i < names.Length; i++) {
if (names[i].Replace('\\', '.') == resourceName) {
using (Stream stream = Assembly.GetExecutingAssembly().
GetManifestResourceStream(names[i]))
{
buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
}
}
}
if (buffer == null)
return false;
try {
using (FileStream target = new FileStream(fileName, FileMode.Create)) {
target.Write(buffer, 0, buffer.Length);
target.Flush();
}
} catch (IOException) {
// for example there is not enough space on the disk
return false;
}
// make sure the file is actually writen to the file system
for (int i = 0; i < 20; i++) {
try {
if (File.Exists(fileName) &&
new FileInfo(fileName).Length == buffer.Length)
{
return true;
}
Thread.Sleep(100);
} catch (IOException) {
Thread.Sleep(10);
}
}
// file still has not the right size, something is wrong
return false;
}
They're reading the resource into a buffer, write that buffer to disk and wait until the file has been flushed to disk.
My solution is conceptually similar to the one presented by Wouter.
It's what we use in our own app, and we can use native/mixed-mode and c# dlls all embedded in the same .exe.
It extracts the dlls into a temp dir everytime the application is run. Obviously you might not want to do this in the production version, where the dlls will be stable; you might choose a different directory there (probably somewhere in %AppData%). It will use an existing dll with the same version number, though (e.g. it's only done the first time when opening the app multiple times between booting the computer).
Since we're doing
AppDomain.CurrentDomain.AssemblyResolve += (sender, args)
this function is getting called wherever the system tries to resolve a dll. And since it's initalised in the static Program class, it all works automagically.
Program.cs:
namespace MyApp
{
internal class Program
{
static Program()
{
LoadAssemblyResource.Initialize("MyApp");
}
//....
}
}
LoadAssemblyResource.cs
namespace MyAppStartup
{
public static class LoadAssemblyResource
{
private readonly static String _version_string =
Assembly.GetExecutingAssembly().GetName().Version.ToString();
private readonly static String _dll_path = Path.GetTempPath()
+ "\\MyApp\\" + _version_string;
static public String last_error_msg = null;
public static bool WriteBytesToFile(string filename, byte[] bytes)
{
try
{
var fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
return true;
}
catch (Exception e)
{
Console.WriteLine("Writing file failed. Exception: {0}", e.ToString());
}
return false;
}
public static Assembly LoadUnsafe(String assembly_name, Byte[] assembly)
{
if (!Directory.Exists(_dll_path))
{
Directory.CreateDirectory(_dll_path);
Console.WriteLine("Created tmp path '" + _dll_path + "'.");
}
String fullpath = _dll_path + "\\" + assembly_name;
if (!File.Exists(fullpath))
{
Console.WriteLine("Assembly location: " + fullpath + ".");
if (!WriteBytesToFile(fullpath, assembly))
return null;
}
return Assembly.UnsafeLoadFrom(fullpath);
}
public static void Initialize(String exe_name)
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
String assembly_name = new AssemblyName(args.Name).Name + ".dll";
String resource_name = exe_name + "." + assembly_name;
using (var stream =
Assembly.GetExecutingAssembly().GetManifestResourceStream(resource_name))
{
if (stream == null)
return null;
Byte[] assembly_data = new Byte[stream.Length];
stream.Read(assembly_data, 0, assembly_data.Length);
try
{
Assembly il_assembly = Assembly.Load(assembly_data);
return il_assembly;
}
catch (System.IO.FileLoadException ex)
{
// might have failed because it's an mixed-mode dll.
last_error_msg = ex.Message;
}
Assembly mixed_mode_assembly = LoadUnsafe(assembly_name, assembly_data);
return mixed_mode_assembly;
}
};
}
}
}
I am having a strange problem.I am using the Windows API Code Pack for Microsoft .NET Framework for displaying custom thumbnails for my custom file extensions.I have used the Microsoft.WindowsAPICodePack.ShellExtensions namespace methods as mentioned in the documentation and I can successfully show a thumbnail.But i am encountering a strange problem.While the shell thumbnail handler is registered, I cannot delete the file for which the thumbnail is shown.The file gets deleted alright for normal delete but while using Shift+del the file disappears form explorer without errors but will return when i refresh the folder.The file will stay there until I restart explorer.exe process or if I focus the window and wait for 60secs the file disappears on its own.The returned file doesn't allow to get deleted again giving an access denied error message.I tried using LockHunter and it shows that explorer.exe is locking the file.I am confused guys.What am I doing wrong ?. How can I fix this?.
I am using Windows 7 64 bit,visual studio 2010
My code is as follows
namespace CustomThumbnail
{
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CustomThumbnail.XYZThumbnailer")]
[Guid("439a0bd3-8a44-401d-931c-3021ad8b1ad6")]
[ThumbnailProvider("XYZThumbnailer", ".xyz", ThumbnailAdornment = ThumbnailAdornment.VideoSprockets)]
public class MyThumbnailProvider : ThumbnailProvider, IThumbnailFromStream
{
public Bitmap ConstructBitmap(System.IO.Stream stream, int sideSize)
{
try
{
LogMessageToFile("Hello Stream");
XyzFileDefinition file = new XyzFileDefinition(stream);
using (MemoryStream mstream = new MemoryStream(Convert.FromBase64String(file.EncodedImage)))
{
LogMessageToFile("using Stream");
Bitmap bmp = new Bitmap(mstream);
LogMessageToFile(bmp.ToString());
return bmp;
}
}
catch (Exception ex)
{
LogMessageToFile(ex.ToString());
throw;
}
}
public void LogMessageToFile(string msg)
{
System.IO.StreamWriter sw = System.IO.File.AppendText(#"D:\test\testdoc.txt");
try
{
string logLine = System.String.Format(
"{0:G}: {1}.", System.DateTime.Now, msg);
sw.WriteLine(logLine);
}
finally
{
sw.Close();
}
}
}
}
New Code
public Bitmap ConstructBitmap(Stream stream, int sideSize)
{
try
{
Assembly assembly = Assembly.LoadFile(#"C:\Users\xxxx\Documents\Visual Studio 2010\Projects\MyThumbnailTest\Bin\Data\Data.dll");
Type type = assembly.GetType("Data.ThumbnailData");
MethodInfo foo = type.GetMethod("GetThumbnail");
var c= foo.Invoke(Activator.CreateInstance(type), new object[] { stream });
return (Bitmap)c;
}
catch (Exception ex)
{
LogMessageToFile("error "+ex.Message.ToString());
throw ex;
}
finally
{
stream.Close();
stream.Dispose();
}
}
And my GetThumbnail Method goes like this
public class ThumbnailData
{
public Bitmap GetThumbnail(Stream stream)
{
using (ZipFile zip = ZipFile.Read(stream))
{
ZipEntry image = zip.Entries.Where(p => p.FileName.ToLower().IndexOf(".png") > 0).FirstOrDefault();
if (image != null)
{
using (MemoryStream ms = new MemoryStream())
{
image.Extract(ms);
Bitmap bmp = new Bitmap(ms);
return bmp;
}
}
return new Bitmap(150, 150);
}
}
}
Without seeing the code, this is all I can think of:
Is your custom thumbnail code not closing the Stream for the file after it produces the thumbnail?
As my comment suggested try this:
public Bitmap ConstructBitmap(System.IO.Stream stream, int sideSize)
{
try
{
LogMessageToFile("Hello Stream");
XyzFileDefinition file = new XyzFileDefinition(stream);
using (MemoryStream mstream = new MemoryStream(Convert.FromBase64String(file.EncodedImage)))
{
LogMessageToFile("using Stream");
Bitmap bmp = new Bitmap(mstream);
LogMessageToFile(bmp.ToString());
return bmp;
}
}
catch (Exception ex)
{
LogMessageToFile(ex.ToString());
throw;
}
finally
{
stream.Close();
}
}