Find the directory of a file in C# - c#

I'm new to C# and I have been trying to play a sound using SoundPlayer class. So in my solution in visual studio (2015 community), I created a folder called Music and drag'n'dropped a wav file there. In properties, I found the file path and then used in the SoundPlayer constructor. Right now, it's on the desktop.
My problem is that I'll be moving the actual program (it's just console app) to another computer (with different user name...which I don't know). So is there a way C# can determine the new location (directory) for the file so that I don't get an error?
SoundPlayer spPlayer = new SoundPlayer (#"C:\Users\tvavr\Desktop\Dango\mr_sandman.wav");
spPlayer.Play();
This is the code that works. Now, how am I supposed to change that path?
Thx for your answers.

use dynamic path as following :
SoundPlayer spPlayer = new SoundPlayer (Application.ExecutablePath +#"\mr_sandman.wav");
where Application.ExecutablePath will get your application folder dynamically

This is a design decision that only you can answer. When you write console applications that require you to load a file, you have several options
Option #1: Have the path specified in the argument list of the program when it is executed
Assume the name of your program is playsong, you run it like this:
playsong C:/path-to-music-file/song.wav
You get the name of the song file from the argument list of Main. The first item in args is the filename:
static void Main(string[] args) {
SoundPlayer spPlayer = new SoundPlayer(args[1]);
spPlayer.Play();
}
Option #2: Access the song file by hard coded path
static void Main() {
SoundPlayer spPlayer = new SoundPlayer("C:/playsong/songs/song.wav");
spPlayer.Play();
}
Option #3: Access the song file relative to the program location
static void Main() {
SoundPlayer spPlayer = new SoundPlayer(Application.ExecutablePath + "/songs/song.wav");
spPlayer.Play();
}
If you later want to change this into a Graphical User Interface (GUI) program, you would bring up the OpenFileDialog box which lets the user choose the file.

.NET has built-in tools to access locations like current user's desktop:
System.Environment.SpecialFolder.Desktop

Related

Is this the proper way to obtain a drag and drop file for the exe application created in C#?

Pretty much exactly what the title says. I created an exe windows form program in C# and i found how to obtain the file name and path that was dragged and dropped onto the exe. Well is this the proper way to obtain the file?
public partial class Form1 : Form
{
public static String file;
public Form1()
{
foreach (String arg in Environment.GetCommandLineArgs())
{
file = arg;
}
InitializeComponent();
label1.Text = file;
}
}
}
It does work and if i run the program itself, it gives me the file path and name of the exe itself. But when dragging and dropping to the exe, it gives me the file that i dropped. Is this the proper way to do it?
In general, GetCommandLineArgs may or may not contain path to executable as first argument. But in most cases - first argument will be your exe.
So, second, third and so on arguments will contains dropped files.
Hm, thought command line passed to the main method of main class in C#, no?

C# winform opens with right-click context menu, but how do I get the selected item to show up?

I have a C# WinForm App that I created to store files in a seperate secure location on the hard drive. I am trying to add functionality to the program by adding a right-click context menu so when a user right-clicks a file (or group of files) in windows, my program is there in the context for them to select. No problem there, I have that part worked out. What I need is to programmatically get that list of files and send it to the program so they are listed in the listbox already.
I am already doing something similar with a multiselect in an OFD, but I dont want them to have to open the program, select browse, find the files and select them when they already have them selected in windows.
There are a ton of programs out that have this functionality (like properties plus, textpad, etc...) I just need a shove in the right direction to help me figure this out.
Thanks in advance,
Dave
If I'm correctly understanding what you've already implemented, then all the files should appear as arguments on the program's command line. You just need a way of extracting each of those file paths and displaying them in your list view.
In C#, the following code will display a message box containing each argument on the command line:
static void Main(string[] args)
{
foreach(string arg in args)
{
MessageBox.Show(arg);
}
}
But in case you don't want to access these in the Main method, you can also use the Environment class, which provides the static GetCommandLineArgs method. It returns the same array of strings containing the arguments, and you can loop through it the same way.
Here is an article on how to customise Right-Click Menu Options in Windows
Then just as #CodyGray says use the string[] args in your Main method of you program to get the filenames
I am gathering all the arguments and sending them to an ArrayList.
static void Main(string[] args)
{
ArrayList myAL = new ArrayList();
foreach (string arg in args)
{
myAL.Add(arg);
}
ALRec nalr = new ALRec();
nalr.getArrList(myAL);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
sending it to ALRec Class
class ALRec
{
ArrayList MyArrLst = new ArrayList();
public void getArrList(ArrayList AL)
{
MyArrLst = AL;
}
}
Why is it starting multiple instances of my App?

Adding "Open With..." Functionality c#

I am working on a program that can read, write, and export files, these functions all work fine and are almost perfected. What I would like to do now is to be able to choose a file and tell it to "Open With" (In the Right-Click Context Menu on Windows XP) and have my application be able to handle the file given. I have no idea on where to start or where to look so I thought I'd ask here. Thanks.
You might take a look at this Windows KB article:
"How To Associate a File Extension with Your Application (Win32)"
http://support.microsoft.com/kb/185453
It looks like it gives example code for how to do this in VBScript (?), but it looks like it goes through the Registry paths you need to look at.
Hey, I believe this is defined in the registry. E.g. MSAccess is defined as:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Access.Application.11\shell\Edit]
#="&Edit"
[HKEY_CLASSES_ROOT\Access.Application.11\shell\Edit\command]
#="\"C:\\Programmer\\Microsoft Office\\OFFICE11\\MSACCESS.EXE\" /NOSTARTUP \"%1\""
[HKEY_CLASSES_ROOT\Access.Application.11\shell\Edit\ddeexec]
#="[SetForeground][ShellOpenDatabase \"%1\"]"
[HKEY_CLASSES_ROOT\Access.Application.11\shell\Edit\ddeexec\Application]
#="Msaccess"
[HKEY_CLASSES_ROOT\Access.Application.11\shell\Edit\ddeexec\IfExec]
#="[SHELLNOOP]"
[HKEY_CLASSES_ROOT\Access.Application.11\shell\Edit\ddeexec\Topic]
#="ShellSystem"
A GUI also exists in Folder settings -> File types.
Br. Morten
Bring up the run dialog box, and enter: regedit (Registry Editor)
Go to: HKEY_CLASSES_ROOT\*\shell and create a subkey named: "Open With YourApp", create another subkey under the newly created one named "command". On its Default value, enter the path to your exe, then add "%1" at the end for the parameter.
In program.cs, add the indicated lines below:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var mainForm = new MainForm();
// Add these lines:
// ----------------------------------------------
string[] args = Environment.GetCommandLineArgs();
if (args.Count() >= 2)
mainForm.LoadFile(args[1]);
// ----------------------------------------------
Application.Run(mainForm);
}
}
Where LoadFile(string filePath) is your method that handles the file that is passed in from outside.

Starting an .exe from the same folder of my C# program

I made a small program in c# with a button that is supposed to open another .exe file.
It works fine if I use:
private void start_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start(#"path to file");
}
But not if I want it to run an .exe from the same folder, i basically wanted something like:
private void start_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start(#"program.exe");
}
What am I missing, I've tried a solution from this website:
var startIngo = new ProcessStartInfo();
startIngo.WorkingDirectory = // working directory
// set additional properties
Process proc = Process.Start(startIngo);
But Visual c# doesn't recognize "ProcessStartInfo" at all...
What your looking for is:
Application.StartupPath
It will return the startup path that your executable was started in.
If you are using WPF, try this instead:
String appStartPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
You can do:
var startupPath = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetEntryAssembly().Location);
var programPath = System.IO.Path.Combine(startupPath, "program.exe");
System.Diagnostics.Process.Start(programPath);
ProcessStartInfo is in the System.Diagnostics namespace - you need to import that namespace at the top of your cs file using a using System.Diagnostics; statement for the compiler to recognise ProcessStartInfo without specifying the namespace explicitly where you use the class.
You could also try System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
To get your local path. For example
//in your imports/using section
using System.IO
using System.Reflection
using System.Diagnostics;
//in your code to execute
Process.start(Path.GetDirectoryName(Aseembly.GetExecutingAssembly().GetName().CodeBase) + "\\program.exe")
There are two cases:
The application was started directly - start up path can be extracted from the command-line.
The application was started indirectly - e.g. from a unit-test, start up path can not be extracted from the command-line, however you can read it from the current directory into a static variable during the start-up (before the user has a chance to change it (e.g. using a file open/save dialog)).

Playing embedded wav files using SoundPlayer

I have a Compact Framework 3.5 application that is responsible for scanning barcodes. There are 3 different sounds it should play depending on the situation, so I created a wrapper class around the SoundPlayer object and call the Play method on that.
public static class SoundEffectsPlayer
{
private static readonly SoundEffect _alert;
static SoundEffectsPlayer()
{
// This will cause the SoundEffect class to throw an error that the Uri
// Format is not supported, when new SoundPlayer(location) is called.
_alert = new SoundEffect("SoundEffects/alert.wav");
}
public static SoundEffect Alert
{
get { return _alert; }
}
}
public class SoundEffect
{
private readonly SoundPlayer _sound;
public SoundEffect(string location)
{
_sound = new SoundPlayer(location);
_sound.Load();
}
public bool IsLoaded
{
get { return _sound.IsLoadCompleted; }
}
public void Play()
{
_sound.Play();
}
}
The idea was to not create a SoundPlayer each time a barcode needed to be scanned (which would be a few hundred times an hour). So I can just call Play on the already loaded file.
The alert.wav file is in a SoundEffects folder that is on the root of the library project that the application references, and it is set to be an Embedded Resource. What would I need to pass in to the SoundEffects class to load the wav file? Should the wav file even be embedded into the library project?
Also does anyone notice anything wrong with the way I'm handling the playing of the wav files? This is my first attempt at something like this, so I'm open to suggestions for improvement.
Hmmm. I haven't used SoundPlayer before, i'm guessing it is just a wrapper around the coredll function PlaySound. But anyhow, I would expect that it demands a file path as the argument.
Therefore to make it work with an embedded resource you would probably have to save the file to disk and then play it. It would probably be simpler to scrap the embedded resource idea and deploy it as a separate item. Include the .wav in your main project set it to: "Content" and "Copy if newer" and then reference it as a file in the sound player call.
Remember that in WindowsCE you always need FULL paths as well. A relative path from the currently running .exe wont work in CE.
If you need to find out "where you are" to create the path to the resource, see the answer to this question.

Categories