C# Console Application - Shortcut not apears in the "Sent to" menu - c#

I build a C# Console application that takes a file in parameter, format it and save the result in an other file. I've built the application successfully using ClickOnce. Now I want to be able to click right on a given file and "Send To" my application. As for other application, I've sent the shortcut to the C:\Users\MyUser\AppData\Roaming\Microsoft\Windows\SendTo repository but unlike other shortcut, my application is hidden from the menu. I've tested on few other PC (also running under Windows 7) and I always get the same behavior.
Do you know if it's caused by ClickOnce? Is there a way to solve this issue?

FYI, I finally bypass the ClickOnce solution and use the plain .exe instead. The post below describe how to achieve it:
Why are my binaries not placed in the /bin/release folder when I build a Windows Service in C#?

Related

What runs my C# application?

When developing a C# project in Visual Studio, I have three options for output type. Console Application, Windows Application, and Class Library. AFAIK, the only difference between a DLL and an EXE, is the EXE should have an entry point defined, and that is called when the file is double clicked. However, when I launch an EXE built from a Console Application, a console window is created. So obviously something is happening other than the CLR getting launched and then calling my Main method. What launches the console window? When I launch an EXE built from a Windows Application, is some other code run also, or is it just my main method?
Your portable executable file(exe) will contain the information about what kind of application it is.
Subsystem flag of the IMAGE_OPTIONAL_HEADER defines what kind of user interface the application is built with.
IMAGE_SUBSYSTEM_WINDOWS_CUI defines the console application, IMAGE_SUBSYSTEM_WINDOWS_GUI defines the windows application and so on.
For more information Peering Inside the PE: A Tour of the Win32 Portable Executable File Format
The output type is a configuration parameter for your project which tells Visual Studio what to do when you compiled. If set to Console Application, it will generate an exe file with the code to launch the console window.
The different between a dll and an exe is more than the main method. Visual Studio generated additional codes in the exe file that creates the console and invoke the main method. For details of how the exe file performs this, refer to http://en.wikipedia.org/wiki/Portable_Executable.
In this link the inquisitor added some notes which mentioned the blog post (2nd link).
Is it possible to build a Console app that does not display a console Window when double-clicked?
http://blogs.msdn.com/b/oldnewthing/archive/2009/01/01/9259142.aspx
The same content as Siram's answer https://stackoverflow.com/a/30084790/2005526 but to assist you with future searches these were the keywords used on google to locate the mentioned resources. "double click exe launches console"

How do I publish an Access database with my C# application using Visual Studio?

I'm trying to figure out how to publish an application I wrote. We didn't get to publishing in class, and my programming teacher is having some health issues and isn't available right now.
I found the "Publish" option, and can get it to create a folder with an install program... but I open it, and it just opens the program, and spams me infinitely, complaining that my Access database (located in the bin > debug in the build stage) can't be accessed (from some weird path I don't recognize). I tried using WiX, but it gave me an error when I tried to install, saying it doesn't have access to the install folder (running as admin). I've been googling for a few hours, poking at it, exploring, and I'm not getting too far. Can anyone ELI5?
When you use the "publish" option for desktop apps, VS creates a click-once installer that will place all the files it knows about in the appropriate locations.
Unfortunately, it can't guess which other files your application needs so you need to tell it explicitly.
If you right-click the Project->Properties, go to the Publish tab and click the "Application Files" button, you'll see all files that will be added to the installer.
Next, click "Show all files" at the bottom. Find your database, and change the Publish Status to "Data File".
Note that I've only ever used the Click Once installer to install static files (like images/documentation) that are never modified, only replaced in later releases. I'm not sure whether your (modified) db will be preserved during an update but I suspect not.
If the Click Once install process is too simple for your needs, VS2010 has "Setup Projects" which create more complex installers that support logic/code. For VS2012, the commonly suggested option is Wix. Unfortunately, it's got a steep learning curve but it can do pretty much anything you need.
I believe VS2013 and later have setup projects again through an extension but I haven't tried it myself.
Edit:
The easiest way around this is likely to set the connection string programatically based on where the application is executing from.
Note that as per this answer clickonce apps are usually executed from deep inside the user profile directory (also read the answer below about data directories). It's a side-effect of how ClickOnce works (it wants to install somewhere the user is guaranteed to have write access).
Check if there really is an .mdb in that folder. If not, you need to tweak the installer or the properties for the .mdb. Assuming it's in the same location as the executable, you can tell your application where to find it...
string dbPath = IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"access.mdb");
string connectionString = String.Format(
"Provider=Microsoft.Jet.OLEDB.4.0; Data Source={0}",
dbPath);
I'm not sure why you think the database file added by the installer is in a directory directly under C:\. It's possible you're not looking at the file created by the installer.
To avoid confusion, try changing the name from access.mdb to something else (temp.mdb?), build the installer, rename back to access.mdb. Now, when you've installed the application, make sure the file you're looking at is now called temp.mdb. If not, you're looking at the wrong file.
This Link Has Full demonstration of Database Connectivity And Publish a C# application with database. The application is also running on another machines.
How to Publish C# Application with access database

How does the InstallAllUsers option work?

I have a C# application, and a Visual Studio (2010) Setup Project with it. In my Setup Project, I am using InstallAllUsers = True. Additionally, my application needs to launch at Startup, so a shortcut is being added to the User's Startup Folder.
So I install my application as user Bob (from a share), and then I log off and log on as user Alice. Alice gets a dialogue that says:
The feature you are trying to use is on a network resource that is unavailable.
It provides the network path from which the MSI was installed. So, basically, it's looking for the MSI on a share that Alice doesn't have access to. This is repeatedly reproducible if Alice tries to manually launch the Startup link. However, Alice can directly launch the exe from the installation location, which works fine.
I don't fully understand why it is looking for an MSI, but I guess it makes sense that an application can not be completely installed by one user for another user, so the MSI is needed to complete the installation.
But if that is the case, then I don't understand why the MSI only seems to be required when launching from the Startup link, and not from the exe directly.
My question has several parts:
Is what I am experiencing expected behaviour for the InstallAllUsers option?
If so, how can I ensure that my application is fully installed for all users?
Is it necessary to copy the msi locally, and ensure that it does not get deleted before each user has had a chance to log on?
This is happening because the shortcuts are "advertised shortcuts" hence the greyed out target box.
More info here...
http://www.advancedinstaller.com/user-guide/advertised-shortcuts.html
When an advertised shortcut is launched it validates the checks
associated with the key resources. If any is missing it will fix it by
running the installation package and installing again all information
from the .msi file.
This is why its trying to run the msi.
You can turn off advertised shortcuts by reading this article...
DISABLEADVTSHORTCUTS=1 disables all shortcuts
If its an all users install, then the shortcut will probably want to reside in the all users start menu. Win 7: C:\ProgramData\Microsoft\Windows\Start Menu.
Eric, I would recommend taking a look at the shortcut file contents. You can do this by using Powershell, and there is a SO link to help you on your way:
Editing shortcut (.lnk) properties with Powershell

Launching a ClickOnce application from another ClickOnce application

My goal is to actually achieve launching my ClickOnce application in one click (or two I guess). The application has some prerequisites which need to be installed. The normal way of ensuring they are installed that Microsoft provides involves having the user decide whether he has the prerequisites or not and downloading and installing a "setup.exe" which installs them and runs the ClickOnce application. This involves downloading the EXE file (one click), running it (two clicks), then after prerequisites are installed, clicking again to run the ClickOnce application.
I'm trying to reduce this process to one or two clicks:
- Click a link on my website to the ClickOnce .application file.
- Click again to run it.
I have made ANOTHER ClickOnce application, which includes a setup.exe. It checks if the prerequisites are installed, and if they are it runs the other ClickOnce application automatically. If not, it runs the included setup.exe and then runs the other ClickOnce application.
My problem is that when I try to run the other ClickOnce application from this one, it simply opens my web browser and downloads the .application file without running it.
I'm trying to use the following to start the ClickOnce application from inside my C# code:
Process.Start(ApplicationURL);
I just want this to automatically launch the application at ApplicationURL. Is there a way to skip the browser involvement that I'm seeing?
(My question is very similar to Stack Overflow question Run a ClickOnce application from a webpage without user action).
As pointed out in the comments, you can start the iexplore.exe process to launch a ClickOnce application without any dependency on the default browser. You can also launch the ClickOnce application the same way Windows Explorer launches it, using dfshim.dll.
Process.Start("rundll32.exe", "dfshim.dll,ShOpenVerbApplication " + ApplicationURL);
There are a few other articles online that discuss using this strategy, but I did not find any official documenation of dfshim.dll,ShOpenVerbApplication.
Another Stack Overflow question mentions using a custom .exe to install the .NET Framework and then launch a ClickOnce application via ShOpenVerbApplication.
Scott Hanselman discusses ShOpenVerbApplication as the default file mapping for files with the application/x-ms-application MIME type in a post about Firefox and ClickOnce.
Update
As the other Stack Overflow question mentions, you can also use dfshim.dll's LaunchApplication command, which is documented on Microsoft's site. However, that command is not available in some older versions of the .NET Framework.
Have a look at the Microsoft walkthrough for installing manually via InPlaceHostingManager. You have the ability to customize programmatically.
There are at least 2 other methods for launching ClickOnce applications.
One simple method is Process.Start("PresentationHost.exe", "-launchApplication " + ApplicationURL); as documented by Microsoft here.
A more sophisticated method is calling ShellExecuteEx() Win32 API with code like this:
SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);
info.lpFile = ApplicationURL;
info.nShow = SW_SHOWNORMAL;
info.fMask = SEE_MASK_CLASSNAME;
info.lpClass = "Application.Manifest";
ShellExecuteEx(ref info);
Required Win32 API import and structure definitions can be found here. This method will query registry and run "rundll32.exe dfshim.dll,ShOpenVerbApplication" (or anything else that is configured under HKEY_CLASSES_ROOT\Application.Manifest).
Following are the ways to launch clickonce.application
Approach 1: Launch from URL
Method 1:
string app = "http://domain.xyz/ClickOnce.application";
Process.Start("rundll32.exe", "dfshim.dll,ShOpenVerbApplication " + app);
Method 2:
string app = "http://domain.xyz/ClickOnce.application";
Process.Start("IExplore.exe", app);
Approach 2: Directly launch ClickOnce.application from .application file
string app = "file://C:/ClickOnce.application";
Process.Start("rundll32.exe", "dfshim.dll,ShOpenVerbApplication " + app);
And another option is using Launcher::LaunchUriAsync with LauncherOptions.ContentType = "application/x-ms-application". This is known a "uri direct invoke"

How can I add items to Windows Shell (rightclick)?

I'm going to make a desktop application that will run in the background, meaning no visible window, and I'd like an option called: "Upload Text" to appear when a user right clicks a file.
Can someone point me in the right direction? I also have to make sure that if someone wants to uninstall the program at any point, that the shell modification is also cleanly eliminated.
The app will run Windows XP, Windows Vista and Windows 7. How different are these OS's in handling my shell dilemma?
This is a shell extension. You've tagged this question with the C# tag; you should know that writing shell extensions in a managed language is strongly discouraged:
Unfortunately unmanaged C++ is really
the only way to go here.
Writing in-process shell extensions
in managed code is actually a very
dangerous thing to do because it has
the effect of injecting your managed
code (and the .NET Framework) into
every application on the machine that
has a file open dialog.
The problems occur because only one
version of the .NET Framework can be
loaded in a process at any given time
(other shared components such as java
and msxml have the same property and
thus the same restriction).
If you write your shell extension
using the 2.0 .NET Framework and an
application built with the 1.1 .NET
Framework uses a file open dialog,
your shell extension will fail because
it can not run on an earlier version.
Things can get even worse if your
shell-extension manages to get loaded
in a process before another
applications managed code does: your
extension may force an existing
application onto a different runtime
version than the one it was expecting
and cause it to fail.
Because of these problems we strongly
recomend against using any
single-instance-per-process runtime or
library (such as the .NET Framework,
java, or msxml) in an in-process shell
extension.
That said, people have done it.
Here's a guide to creating shell extensions, using C++.
You could add your app to the SendTo folder.
What about a stand-alone program using SendTo?
Install the exe to "Program Files\mycompany\myprogram" and a shortcut to the exe into the SendTo folder. Then when a user right clicks on a file, selects SendTo, and then selects your program, your exe will be executed by Windows and the full path to the filename will be passed in via argv[1]. If they select n files they will be in argv[1]..argv[n].
If you want your program to be invisible then do not make the default form visible. You could optionally place an icon in the tray so the user could double click on it to see the upload progress. When the upload of argv[1] is complete, process argv[2]...argv[n] if they exists and exit. To cleanly uninstall, remove your program and the shortcut from the SendTo folder.

Categories