3

I've made a new proyect on Visual Studio 2010. It's a Windows Forms one, and done with .NET Framework 4 Client Profile.

I've put on it a embeded WAV sound file.

The only thing that I want to is to copy it to some path, let's say desktop as example. How can I achieve this?

I've already tried these:

How to copy file From Resources?

Read a file from a resource and write it to disk in C#

Write file from assembly resource stream to disk

However, I'm always facing troubles. For example:

If I add a audio resource that's named Take Over Control.wav, it's added with the name of Take_Over_Control. Then, I just add a button to my main form that says "Copy". Then, the click event of that button has this:

private void ButtonCopyClick(object sender, EventArgs e)
{
    Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("Take_Over_Control");
    if (resource == null)
    {
        throw new ArgumentException();
    }
    Stream output = File.OpenWrite(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)+"\\Sound.wav");
    resource.CopyTo(output);
}

The thing is... with no matter if I put Take_Over_Control or Resources.Take_Over_Control or Properties.Resources.Take_Over_Control, etc, in the GetManifestResourceStream part, I'm always stuck on throw new ArgumentException();, so, it means that resource is null, and it isn't well-asigned on Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("Take_Over_Control"); line.

And there are troubles with others methods that I've tried. What's wrong in here? How to copy this embeded audio file by the right way!?

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
mishamosher
  • 1,003
  • 1
  • 13
  • 28
  • You won't believe me... I didn't realized that I can answer my owns questions! On my way to the answer! – mishamosher Apr 19 '12 at 04:50
  • Whoa, got this: Oops! Your answer couldn't be submitted because: •Users with less than 100 reputation can't answer their own question for 8 hours after asking. You may self-answer in 4 hours. Until then please use comments, or edit your question instead. – mishamosher Apr 19 '12 at 04:53
  • I'll make sure that when I get pass the 8 hour limit to add these answers on here. – mishamosher Apr 19 '12 at 04:55
  • cool, well my +1 will help you on your way to 100pts:) – Jeremy Thompson Apr 19 '12 at 04:55
  • Sorry for late editing, and thanks for the +1! I misunderstood the error message. I MUST wait 8 hours to answer because I don't have 100+ rep... I'll answer when that time gets pased! – mishamosher Apr 19 '12 at 04:58
  • ...now guess what, I can't accept my own answer untill tomorrow...! Why it's so hard to just answer myself here on StackOverflow!? – mishamosher Apr 19 '12 at 15:13

4 Answers4

2

First of all have you made sure your WAV file is an Embedded Resource under the "Build Action" property? If so, it looks like your path to the WAV file might be wrong. The line...

Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("Take_Over_Control");

Should be

Stream resource = Assembly.GetExecutingAssembly().GetManifestResourceStream("myProject.resources.Take_Over_Control.wav");

Where myProject is the name out your project, and resources is the folder where the WAV file is kept. So the code above would apply if this were the path to your wav file... "c:\myProject\resources\Take_Over_Control.wav

Hope that helps

JimDel
  • 4,309
  • 11
  • 54
  • 99
  • Aja, got it. My project name is `FilesOnResources`, I've tried the `FilesOnResources.Resources.Take_Over_Control` and also `FilesOnResources.Properties.Resources.Take_Over_Control` and it DOESN'T work. – mishamosher Apr 19 '12 at 03:11
  • And please note something more, I want that my code to work even in the case that the Resources folder doesn't exist and I only have the EXE file, and, as I can notice, you observation will not work in cases that the Resources folder is not present. Remeber that the WAV file is embeded on the EXE resources, so, there must be a way to pull it without the need of the resources folder...! – mishamosher Apr 19 '12 at 03:14
  • Also, I've done some tests to check if the resource is accessible, and it is. I've done a System.Media.SoundPlayer going to the resource via `System.Media.SoundPlayer sp=new SoundPlayer(Properties.Resources.Take_Over_Control);`, and then, `sp.Play();`, guess what... it plays! – mishamosher Apr 19 '12 at 03:17
1

Seeking into the Resources.Designer.cs file, I saw a ResourceManager.GetStream... so, I use this now on my click event:

Stream resource = Properties.Resources.ResourceManager.GetStream("Take_Over_Control");
if (resource == null)
{
    throw new ArgumentException();
}
Stream output = File.OpenWrite(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)+"\\Sound.wav");

And it just does the right job of copy the WAV file to the desktop. And also... now I'm free of reflection!

Important to notice that when WAV files are added to a Visual Studio 2010 C# .NET Framework 4 Client Profile project, it isn't saved as byte[], it's saved as UnmanagedMemoryStream. Because of this, the need of convert it to byte[] or just put it in a Stream via ResourceManager, and, ResourceManager way is shorter!

mishamosher
  • 1,003
  • 1
  • 13
  • 28
0

You shouldn't need to do: Properties.Resources.ResourceManager.GetStream

If you're using the Resources Editor in VS.NET, just drag your wav file in there. You'll then get a Resources class generated.

From there, you just need to do copy the Resources.MySound stream to a FileStream

var path = "c:\\temp\\MySound.wav";
using (var fs = new FileStream("c:\\temp\\sound.wav", FileMode.Create))
{
   Resources.MySound.CopyTo(fs);
}
Process.Start(path);
Steven P
  • 1,956
  • 1
  • 16
  • 17
  • And you've tried it with sound files? Sure? Because it isn't saved as `byte[]`, it's saved as a `UnmanagedMemoryStream`... I've tried to convert it to a `byte[]`, but finally, `ResourceManager` is shorter – mishamosher Apr 19 '12 at 15:04
  • OK, so it's a stream - that makes it even easier. I still think you're better off using the generated class, as you get compile time checking. Update answer with full working sample code. – Steven P Apr 19 '12 at 23:38
  • Still liking more my 2 line code :P. `Stream resource = Properties.Resources.ResourceManager.GetStream("Take_Over_Control"); ` and `Stream output = File.OpenWrite(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)+"\\Sound.wav");` – mishamosher Apr 20 '12 at 00:33
  • Well, you have to do what you feel is right, of course :p Just be aware that if you change the name of the resource, you have to change your code and you won't find out until runtime. If you use the generated Resources class, you get compile time checks. You can still do it in 2 lines. – Steven P Apr 20 '12 at 01:20
  • Mmm... not sure what's your case, but on my Visual Studio 2010 Ultimate it reports me that kind of error, and gives very specific reports, even with my code...! – mishamosher Apr 20 '12 at 02:34
0

some times this code get null for resource:

Stream resource = Properties.Resources.ResourceManager.GetStream("ResourceFileName");

but we can use this code instead of that to grantee to return your resource to a stream variable

Stream resource = Properties.Resources.ResourceManager.GetStream("ResourceFileName") 
Ahad aghapour
  • 2,453
  • 1
  • 24
  • 33