How to Make Multiple Program Files within Same Project in Visual Studio - c#

I am making a simple program that:
Automatically Runs on Startup (Invisibly)
Finishes task within 5-10 seconds (Invisibly)
Exits
I am a beginner and have one challenge here. There are two programs. One which user can open to change settings (Windows Forms) and another that runs on startup, finishes task & exit. How can I make two programs in a single project?
Also, where to save configuration so that both the programs can read/write it?
Thanks for help in advance.
Update: The program is basically to clean the desktop on startup. Please check attached design of my software as well for better idea.

There are two answers:
You can make a program that reads the arguments in the Main method to decide in which mode it should run. If run without arguments (such as when double clicked), it presents the user interface, and if run with some specific argument, like say /run, it does not present the user interface and instead performs the task you want. You don't specify how you get the task to happen at startup, but it will have to run this program with that argument (/run).
The easier way to do this is to just make a new project for the program performing the task - that also lets you start and debug the task directly in Visual Studio.
If you're making a conventional Windows application, you're free to save the settings wherever you'd like. Saving them under a subfolder of the AppData folder in the user's home folder/"profile" is the recommended way. You can use Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) to get the path to the AppData folder and then make your own folder and files within it.
You can also use the registry.

Related

How to execute an event of already launched application with file association?

After playing around with a new Windows Form project, I discovered that when you associate a file type with an executable in Windows, you can find the file path of the file that launched the application using args[0] from static void Main(string[] args)
Is it possible to launch an event on your application when you double click a file if your application is already open? (As obviously Main(string[] args) won't be triggered).
Example of an application with behavior I am attempting to replicate:
User Opens GIMP(in Windows)
User opens explorer and right clicks a .png file
User selects open with GIMP
Instead of creating a new application instance of GIMP, GIMP opens the picture in a new window within the instance of GIMP that was already opened.
In this case is GIMP employing multiple applications to accept files "opened" with file association? Or is it possible to do it with a single application "instance".
I'm having trouble with this as most of my searches tend to lead me towards file association as a Windows user (i.e. "How to associate .xls files with excel" articles).
There are a variety of options, but none of them come for free.
Your program's Main() can detect that there is another copy already running and hand the file name off to the already-running copy by some means you determine.
Your program can register as a DDE server and request that subsequent opens be performed via DDE. This is an old-fashioned technique from the 1990's that is generally not recommended for new programs.
You can register a custom drop target for your application, and have the drop target hand the file name to the already-running copy. This mechanism takes the form of a shell extension, and therefore is not suitable for C# due to CLR injection issues.
Given your constraints, option (1) appears to be the best option.
Raymond is right of course, but if you're looking for help with the implmentation of option (1) you should probably look at What is the correct way to create a single instance application? and .NET 4 single application instance and Switch to other instance of same application
You'll notice that detecting the application is pretty easy (use a mutex). Bringing the other application and sending it a filename can be more challenging.
There are three basic solutions presented in the answers to the previously linked questions
Use PostMessage to send a message to 1st instance. This uses HWND_BROADCAST which can have untended consequences.
Use Microsoft.VisualBasic.ApplicationServices.ApplicationBase Of course a reference to VisualBasic gives some C# devs the willies.
Use FindWindow which relies on a Windows Name.
Its also worth noting that if you want the existing application to be in the front you'll need to take special care because setting the foreground can only be given away not taken. See Foreground activation permission is like love: You can't steal it, it has to be given to you and AllowSetForegroundWindow and SetForegroundWindow
Microsoft created this functionality for Visual Basic .Net, and it can be used by C# too.
See the following post for a simple example in C#:
http://www.openwinforms.com/single_instance_application.html
This approach worked best for me: Enforcing Single Instance WPF Applications.
Especially, its solution for passing arguments also works in notify-icon only applications.

Running Windows Forms Application (C# .NET 4.0) from batch file with Command Line Arguments

I'm a Silverlight/ASP.NET developer trying to write my first Windows Forms application to run in the background on a server, populating our database. Eventually would like this to be a Windows service, but it's not required initially.
I need to create a batch file to execute 5 instances of this application, passing in the URL to 5 RESTful endpoints. So I published my app, which created a setup.exe. After installing it, I have an item that points to
C:\Users\mi2dev\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Microsoft\, with a .appref-ms file.
I'm not sure at this point what to do. Running:
"C:\Users\mi2dev\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Microsoft\StreamingApp.appref-ms" -"http://www.myURL.com" throws up a command window briefly, but the app doesn't run, data doesn't populate in DB.
What am I missing here?
since your application is in .exe format. And make your winform accepts command line arguments (check the main method) also make your Form ctor accepts params too. Then just launch it via cmd line just as you would other command, but here only to navigate to that dir where file exists.
In case of batch, use start command followed by program name and then arguments
It's hard to understand what is happening inside your application. You need to debug to understand what is going on there when it receives given parameters.
So I would suggest to debug an EXE. For this go to your EXE project properties, select DEBUG tab in CommandLineArguments insert your parameter string.
Run it in DEBUG and hopefully you will figure out a problem.
If after debugging it's not yet clear why it behaves in that way, come back to SO :)
Silvi if you plan to use your windows forms application from a batch file and you imagine the applicationm will behave differently in such mode than when opened witha double click, the usual approach is to parse the command line (arguments, also available in the main method as parameter) and to avoid loading the UI at all.
in fact if you have written your application properly the UI only managed the UI and does not contain the whole logic of database manipulation and data transformation.
what you could do is check inside the Main method if there are command line parameters and if you detect any of the special ones you have definded you really avoid to even call Application.Run(new Form1(...)); and start working in batch mode without user interface.
the same logic you want to use in batch mode or in UI mode can be wrapped in helper classes (often also called business managers or business logic... it depends), so that you do not have code duplication but simply UI or batch will call those classes nicely.

autoupdate c# program

Suppose i have a program.. how can i accomplish this?
i want the program to have an update feature. so its like,, when i posted a new version in the ftp server, the old program searches the ftp server and if theres a new version, it will download the new program and delete the old ones.
thank you
PS: it can be the user presses the update button, then the program will download the contents to one temp directory, then deletes itself and transferring the new files to the current folder
or it can be an auto update, like the program checks every 12 hours.
You can achieve this using ClickOnce.
You could end up using a pre-executable that performs the update. Starting the application not with the main exe, but with one that performs the update and then launches the main app. The main app checks for update and downloads it, but actually is not doing anything more than that.
Your options are either ClickOnce, which is the superior option of the two, or create a windows service that does the updating for you. The service runs all the time and pols for updates, downloads any and installs them. The reason this is superior to a preloader as suggested by Sascha is that in an environment where users log on with low level privileges the service will have admin privileges and be able to update the application.
Having said this, ClickOnce is the way to go.

single exe with changeable settings

I am trying to make a simple application which will be used to point a web browser control to some of our web applications at my work. I would like to have only one exe file but also have an admin window to change some of the settings and have them persist when the application is closed. Is that possible? I have looked at the application settings resources part but as I understand that makes a file that loads the settings.
I don't want to have to parse a file or have anything but ONE file so please don't suggest doing that if it is possible.
Just use application settings - that will create a single file, you won't have to do any parsing, it'll all be fine.
It'll be separate to the exe file, but unless you meant that "ONE file" to include the executable and rewrite that on the fly, it should fit your description easily.
For example, let's build a console app that just remembers how many times it's been launched:
Create a new console application project
Go to the properties page, and click into the Settings tab.
Click on the link to create a settings file
Type in the table to create a setting called "LaunchCount" of type int. Make it either user scope or application scope, depending on whether you want it to be persisted per user or system-wide.
Hit Ctrl-S to save.
In the Main method in Program.cs, write this code:
Settings settings = Settings.Default;
settings.LaunchCount++;
Console.WriteLine("Launch count: {0}", settings.LaunchCount);
settings.Save();
Add the appropriate using directive for Settings (put the cursor in Settings and hit Ctrl-.)
Run the app several times, and observe the number increasing.
You can't have persisted settings without having a separate file...safely. You must either have a separate file, which is the standard and suggested approach approach, like the one created with Application settings, or you must use something like the registry to save settings.
Keep in mind, though, that using the registry is highly discouraged due to security reasons. Plus most companies don't allow access to registries anyway which means that anyone without this access could not use the settings feature.
There are several ways to do this. You can use a command-line argument to do that. Launch the app from the shell and put in your command line argument and change how it launches.
A UNIX-y approach is to look at the name of the exe and change behavior based on that. If I recall correctly, rsh and rlogin are the same executable - they just look at argv[0] to decide how to run. In windows, this is straight forward - look at System.Environment.GetCommandLineArgs - if there is a non-empty string in the 0th element of that, it will be your executable name.
For persisting settings, see Jon Skeet's answer.
I have to say that this is generally a bad idea, but I've done this before a long time ago in VB6. I created a Resource within the exe and then (somehow) directly manipulated it.
The problem is, is that this is usually not possible within the .NET framework due to it being memory resident. These guys tryed it out in .net and they ended up creating an program in IL to do the heavy lifting... Modify Emdeded String in C# compiled exe
Go with a settings file as Jon suggested!

Forcing Winforms install to make application to start when windows starts

How do I force a windows application, with a setup project being added to it, to install so that it will start everytime someone logs into windows?
Edit: I'm aware of the registry settings, but specifically, I am looking for a solution which will allow for the installer to set the registry values.
Open your registry and find the key
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run].
For each program you want to start automatically create a new string value using a descriptive name, and set the value of the string to the program executable.
For example, to automatically start Notepad, add a new entry of
"Notepad"="c:\windows\notepad.exe".
Remove a startup application
If you're trying to remove a program and can not find it in the StartUp folder (usually C:\WINDOWS\Start Menu\Programs\StartUp), then it may be launching from one of the registry keys below. To remove it, delete the value associated with the program you want to remove.
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run]
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce]
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices]
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce]
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices]
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce]
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows]
Source: http://www.pctools.com/guides/registry/detail/109/
If you really need your application to start when Windows is started as opposed to when someone logs in you need to create it as service and on install set the service to "Automatic".
There are many places on the web that will give you information about this:
Microsoft Support Knowledge Base
Developer.com
C# Corner
are the first three I found, but do some research and find the resource that works for you.
UPDATE
I see from the updated question that the requirement is for the program to run when someone logs in so this answer is (to a certain degree) redundant. However, I will leave it here in case someone wants to go the service root.
You can add a shortcut to your winforms program in the Startup Folder. The setup project's File System is where you need to look.
Technically you can't make a WinForms app start when "windows is started"; however, you can start it when someone logs into Windows. To perform that you do one of the three:
Place a shortcut in the current user's startup folder.
Place a shortcut in the the "All Users" startup folder.
Write a registry key to HKLM/Software/Microsoft/Windows/CurrentVersion/Run
Update: as Chris points out I missed the HKCU path.
To run everytime Windows starts you should build your program as a Windows Service (or perhaps lauch it from a Service).

Categories

Resources