Integrating into Windows Explorer context menu - c#

I want to write a small tool, that does the following:
When you right click on a file with a certain file-extension the Windows Explorer context menu shows an additional entry.
When you click this entry a certain EXE is launched with this file as one of its parameters.
I would like to use C#/.NET 2.0 for this. If it's not possible I could also do it with C++/Win32.
My questions are:
Is it possible with C# .NET 2.0?
What are the necessary functions for integrating into the Windows Explorer context menu?
How can I make this permanent? (I don't want to relaunch this tool after every boot)
What do I have to take special care of? (different OS, security permissions, etc.)

You will need to access the registry and add a key under root\\File\\shell or root\Folder\\shell, depending on which items you want the menu item visible on.
Try this article at CodeProject, it's quite useful.
Edit: There's another article here which may be of help.

It is, incidentally, not supported to use .NET for shell extensions, due to the current inability to host multiple runtime versions in the same process (.NET 4 will lift this restriction).
Consider the case where you have two shell extensions; one for .NET 3.5, one for .NET 1. Which runtime will get loaded into your process? Well, it's more or less random--it depends which shell extension gets loaded first. Sometimes it might be the 2.0 runtime, sometimes it might be the 1.1 runtime.
This is also an issue if a .NET program creates common file dialogs; your shell extension may or may not load, and may or may not run with the correct runtime version.
As such, if you go down the Shell extension route you should use native C++/COM/Win32.

Related

Setup project with custom form

I’m currently working on a Visual Studio 2010 setup Project and would like to know if the following is possible:
1) Run the setup project in a way that the default forms don’t show, instead I’d show my own custom form that subscribes to setup project events. This way I'd show install messages and increase my own progress bar.
2) If 1 is possible, I would need a way to specify the default location.
3) I have a separate library project, where I have a custom install class (inherits from “System.Configuration.Install.Installer”) from within the install handler I’d like to be able to show custom windows forms, and control choices made by the user. I guess this is possible by adding a reference to system.windows.forms, but would this be the correct way to go about this? If I couldn't hide the default install form, these custom forms would appear over the default install one and I think it would look too great.
Suggestions, links etc appreciated
Thanks!
*UPDATE 1 *
Could I launch an .msi from c# code but also passing in a value.?
Just what this guy does here:
link
But passing in a value... then from my custom install class I take actions depending on this value.
UPDATE 2
Seems like I can:
link code project
UPDATE 3
I'm considering in doing the following, I'll start testing with a winforms app.
1) Launch winforms application.
2) Make a few webService calls, display data, user makes selection.
3) As per link in update 1, launch process(silent mode) and per update 2, pass in selected values.
4) Use some cross process events mechanism (WCF) so that my custom install class can notify my form of the different steps its running and update progress bar and messages.
You can create custom forms but the declaration needs to be done inside MSI. You can show a custom dialog via a custom action but that will not help you much since msi does this:
Load custom action dll
If it is managed the CLR is started and your maanged code executed
When the custom action is left the dll is unloaded and the clr is shut down
This is done every time a custom action is called. This is one of the main reasons why custom actions are normally written in C++.
To be more flexible you should use the WIX toolkit which allows .NET integration as good as it can be with MSI. MSI itself knows nothing about .NET and is a world of its own.
MSI itself defines dialogs and controls inside the msi via tables like the Dialog and Control table.
You could create a dialog and store your state in a msi property between each several msi actions which need to happen e.g. to calculate the disc space for the selected features and so on. But I doubt that this solution will be performant and I fear that starting and shutting down the CLR so often inside one process will expose you to CLR bugs that no one has encountered before.
To set the target location you only need to call the MSI method MsiSetTargetPath which you can PInvoke very easy.
To disable the normal UI you can override it completely or partially vis MsiSetExternalUI but I have not tried to disable only specific dialogs. If you want to hide specific dialogs you should check the msi tables of your current MSI to check if you can set a msi property to make the dialog think it has already been shown.
Yours,
Alois Kraus
As far as I know the setup projects made by Visual Studio are very limited unless you use custom actions. These Custom Actions can take a lot of time to create and debug so it might be wiser to use a more mature/featured tools such as Installshield
EDIT As for showing windows using winforms: that is ok but: a nice setup allows a silent/scripted install, make sure you allow this. Another thing to look out for is machines not having .NET and thus not being able to show the Forms... IMHO that is a no-no unless you are sure .NET (correct version) is present.
EDIT 2 In response to some comments: There are some scenarios that can't be implemented with VISUAL STUDIO Setup and Deployment projects. I am not saying that Windows Installer is bad. E.g., Try to make a custom installer to decide where an application will be installed and skipping the standard window that the project generates. I am not saying that custom actions are limited but they are IMHO not easy either.
Also, when you want use custom WinForms instead of Installer forms you have to make sure that the bootstrap of the .NET framework is done BEFORE showing any (WinForm) windows. It might be possible but if you want such customisation you might be better of with a more flexible tool.

Prevent C# Dll from being loaded for certain apps

Greetings all,
I have a shell toolbar extension written in C#. It's only meant to be used in Windows Explorer, so I want to prevent the DLL from being loaded in Internet Explorer. Windows provides tons of ways to load extensions in IE only, but seemingly no way to do Explorer only. I know there are various checks I could perform in different places after the DLL is loaded, but the ideal would be to prevent the DLL from loading at all.
Now, if it were written C++, I would call GetModuleFileName in DllMain, check if the executable was iexplore.exe, and return false on attach if so. But there is no DllMain in C#; Microsoft doesn't trust us to play nice with loader lock. Is there any other way I can selectively prevent a C# DLL from loading?
Don't do Shell Extension Handlers in .NET
http://blogs.msdn.com/b/junfeng/archive/2005/11/18/494572.aspx
Section 3: Registering our AppBar
http://www.codeproject.com/KB/shell/csdoesshell3.aspx?print=true
I had to send this one in a separate post as a new user is not allowed to send more than one link in 1 post.

Make an auto updatable VB.NET application

I have an application that is running fine.
I just want to add the auto update feature in that application so that the application can automatically download the updates and install it on the computer.
The easiest way to do this is to make your application a ClickOnce application. It is a method of application deployment which has a very simple process for deploying new versions and having the client check for and install updates. Here is a CodeProject articles which has a full overview
http://www.codeproject.com/KB/install/QuickClickOnceArticle.aspx
It depends on how your application is structured and what kind of files you want to update.
But, basically, what you'll need is a "place" (like a WebService, for example), where your application will get the necessary info to update. Then it's downloading the necessary files and placing them in the correct folders.
I'd also advice you to write a new program, "updater", whose whole purpose it's to update your "main" program.
It's difficult to give you code on how to do this, as it it's more like a pattern that you'll have to implement.
Edit Also, as said by JaredPar, some platforms may provide tools to do this.

Shell Icon Overlay (C#)

I need a method to create Icon Overlay's for Folders and Files in Windows XP/Vista, using C# or C++? Any examples?
Thanks,
-Sean!
Do not do this! Please, please don't.
You will break a lot of applications. Shell extensions must not use the .net framework (or any other similar framework), ever.
Here's an explanation why you must not do this.
Write your extension in C/C++, but not C#.
Update:
Even though as of .NET4 it's possible to have multiple framework versions in one process, it is still not recommended and not supported by Microsoft!
See this post about why:
[...] These problems led us to officially recommend against—and not support—the development of in-process shell extensions using managed code.
Tigris' TortoiseSVN product heavily uses icon overlays provided by library shared by several Tortoise products, the overlays themselves are written in C++ rather than C#.
The documentation for the TortoiseOverlays project explains how they use it and the problems they have encountered (username: guest, empty password), and the GPL'ed sourcecode is in the Subversion repository (same username/password as above).
Snippit from documentation:
TortoiseOverlays registers itself with the explorer to handle the nine
states mentioned above, i.e. it registers nine overlay handlers. The
explorer process initializes the TortoiseOverlays handler, calling its
IShellIconOverlayIdentifier::GetOverlayInfo(). TortoiseOverlays looks
for the registered overlay handlers under
HKLM\Software\TortoiseOverlays\Statusname and calls their
GetOverlayInfo() method so they can initialize too (Note that any
change to the icon name, index, ... your handler does are overwritten
later and won't be used - it's TortoiseOverlays that handles the icons
now). After the initialization, TortoiseOverlays relays every call to
its IShellIconOverlayIdentifier::IsMemberOf() method to the other
handlers. The first handler that returns S_OK determines whether the
icon is shown or not.

Detect and re-activate my app if running - compact framework

Usually a mobile dev would not have to do this because the smart-minimise feature handles it.
But I need to do it myself because my mobile app is kicked off by a bootstrapper app.
The start menu icon kicks off the bottstrapper which downloads a target version from a web service, kicks it off and then closes. If the app gets minimised for whatever reason, the user would normally activate it again using the start menu icon. However, this kicks off the bootstrapper and results in a second copy of the client.
This question comes up everywhere on the net for desktop apps (and is in fact on this site). The usually cited solution is to use a combination of Process.GetProcessesByName combined with API calls to re-activate the process once found. Another solution is to create a controller class that inherits from some VisualBasic dll that I forget the name of. None of the solutions I have come across today are supported by the comapct framework.
So the actual question is a combination of:
Is there a compact framework alternative to Process.GetProcessesByName?
If not, what API call do I have to do instead?
I'm not sure if you found this yet or not, but MSDN has an article on creating a process manager application that has the info that I think you need.
The article reccomends using toolhelp.dll and has a pretty detailed looking walk-through for getting a list of running processes. It's for Visual Studio 2003, so you should probably be good with whatever version of VS.NET you're running.

Categories