How to pass arguments to an application that is already running? - vb.net

I have an application written in VB.NET and I have a file association that will trigger a specific function if opened from that file type.
The only thing is that If the application is already open and a user clicks on an associated file, it opens another instance of the application.
Basically, I would like to have the currently running instance of the application handle any incoming arguments from a double click on an associated file. Here is some pseudo-code to help understand.
if(application.isAlreadyRunning){
application.doSomething(filePath);
}
else{
proceed normally...
}
I've looked into mutexes, and they allow me to ensure that only one instance of the app is running, but then I need to pass the filename to the currently running instance.
Thanks!
P.S. I forgot to mention that I am using ClickOnce to deploy the app and AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData to retrieve the "arguments"

Related

Execute method of an object on application crash in VB.Net

I want to execute a function of an object when my application crashes. I have this third party library TMCTL which I am using in one of my form Main. This library is used to communicate with another windows application. Whenever my application is closed, its .Finish(CommID) method has to be executed. I have put this method in form's closing event. But sometimes, my application crashes due to unknown reasons. At that time this function doesn't get executed. This creates problem, when application is restarted.
I want to know is there any other way to execute this function apart from closing event. I tried using UnhandledException event in ApplicationEvents.vb. But I am not sure how to call TMCTL object in ApplicationEvents.vb from my form. I have declared it as Public in my form's code (Public cTmctl As TMCTL). It gives error if I try to call using Main.cTmctl in ApplicationEvents.vb
I don't think can be done this way, and if someone does come up with something I wouldn't trust it.
There are a couple of ways you could do this.
remember when you've started your 3rd party session (setting file, database, JSON file . . .), when the application closes properly you close the session and mark it as closed.
When your app starts again it can check was the last session closed. If yes, it starts another session, if no, it could (if possible) re-use the last session, or close the last session and create another.
or
Have a second service that mediates between your app and the 3rd party service. The new service (lets call it Middle Man), is called by your app to open the session on the 3rd party and to close it. The MM service monitors your app, if it has stopped running - or isn't responding - and there's an open session then it closes that session.
The second approach is helpful if you want the session to time out after some period of inactivity.

Open file with VB.NET application (How does my project know which file is being opened?)

I am in the process of making a simple image viewer in VB.NET. I want to be able to open an image with my application. How does VB.NET receive the URL of the file that the user is trying to open?
Seems simple but without knowing key terms, my Google searches are returning completely the wrong things!
You want to inspect the Environment.CommandLine Property
This property provides access to the program name and any arguments specified on the command line when the current process was started.
The program name can include path information, but is not required to do so. Use the GetCommandLineArgs method to retrieve the command-line information parsed and stored in an array of strings.

Write to file as Different User

I am trying to write to a file that my local user account does not have access to, how can I open and write to the file as an administrator?
You need to launch another process that has admin rights. To do that call ShellExecute with 'runas' as the second parameter (this will open a User Account Control dialog). That executable may be separate or may be the same one that is calling ShellExecute.
You might want to look at PSEXEC from Microsoft, it allows you to execute files in elevated mode, and as a different user if desired.
You didn't say how the file is opened for writing, but PSEXEC can be used in conjunction in batch/vbs file to execute another batch/vbs/exe.
A good wrapper class for impersonation in a using block is what I have used with success before:
using (new Impersonation(domain, username, password))
{
// <code that executes under different user context>
}
The Using statement is great for code readability as seen in this example and to ensure that the object used is properly disposed when the final } character is reached (running out of scope). Apparently there is no guarantee of garbage collection though (see first answer).
Two different sources for such a wrapper class:
This stackoverflow solution features good readability and usability.
Here is similar code from CodeProject: A small C# Class for impersonating a User.
See MSDN for more on the Using statement.

SharePoint feature event receiver not firing

I want to add a custom RoleDefinition to my sharepoint site, in VS2010 I added a new feature receiver and under the Activated Event I added this code:
using (SPSite site = new SPSite("http://localhost:8280"))
{
using (SPWeb web = site.OpenWeb())
{
web.RoleDefinitions.Add(AdminRole);
web.Close();
}
site.Close();
}
Using the package designer I added the feature and from VS I deploy the solution to the "Web" scope. when I go to site features I do see my feature being Active but the Role Definition is not there. I suspect the Event receiver code not being fired so I added some code that writes to a log file and there the file was empty so the code is never reached. knowing that the solution is deployed as a sandbox solution on SharePoint 2010.
any ideas?
Many thanks
The Event receiver did not fire because it was not linked to the feature...doh!
here is the thing, in the feature template file these two attributes must be added:
ReceiverAssembly="Full name, version, neutral,publikeytoken"
ReceiverClass="*Namesapace.classname"
hth
You created some code that got deployed within a feature. But you never do something to make that code run. I assume you have a business reason to do this in code in a feature, as the UI would let you do this sort of thing. Your code should actually be within a feature receiver if it is something you want to execute upon activating the feature. You would add this code to the override routine for the feature activating class.
Search for Feature receiver for detailed instruction.

Replacing a .NET dll

I have a dll which is installed with the initial installation of my app (via an msi file). The dll contains a user key and this is 'demo' for the initial installation. When a user buys a licence he is provided with another dll which contains his name. The second dll is simply the first, rebuilt with a different name so it is the same GUID and file name.
This works fine on my win7 test machine, I can replace the dll in my apps dir and it runs correctly. I have recently provided a user dll to a new client but the replace method doesn't seem to work. He is quite IT literate so I think he is following the emailed instruction (replace the userdata.dll in your app directory with the attached) it does not seem to change the dll. He is using Win8(pro).
I had thought of sending him an Inno setup to copy the user dll into the app dir, Flags:ignorereversion regserver sharedfile
Can anyone suggest a solution or an explanation?
Later...
I have now sent him an Inno setup for the updated dll and this works. If I used the second dll method (a good idea) I would still need to have the user install it.
Rather than replacing the original .dll, why not provide a second .dll with the customer's specific info? The 2nd .dll will unlock features in the original .dll.
For instance, in your original .dll you might check for Customer.dll:
if(TryLoadAssembly("Customer.dll", out assembly)) {
if(Validate(assembly)){
IsUnlocked = true;
}
}
Further recommendations (and untested samples) - have Customer.dll contain a single object implementing an interface:
class Customer : IToken {
GUID Guid {get;}
// other fields
}
To validate:
bool Validate(Assembly assembly){
Type type = assembly.GetType("Customer");
IToken customerToken = (IToken)Activator.CreateInstance(type);
// check some properties
return customerToken.Guid == application.Guid;
}
You say it doesn't appear to be replacing the DLL. Is it UAC redirecting his filecopy into local storage?
If this is the case then the easiest way to deal with it would be to either
1) supply a batch file that can do the file copy, along with instructions to launch the batch file by right clicking on it anc choosing "run as administrator".
2) supply an executable that can do the file copy. You can either include instructions to run the exe as an administrator like the batch file, or you can include a manifest with the application to instruct windows that the file needs to execute as an administrator.
A last option, which might be worth while for troubleshooting would be to get the user to turn off UAC and try the file copy again. If that works then this user will be happy and you know what the problem is and can find an elegant solution for future customers.
I've just looked on my Win 8 laptop and the option for UAC is in Control Panel - User Accounts - User Accounts - Change user account control settings. This will give a slider which can be slid all the way to the bottom to turn off UAC.
(User Accounts really is listed twice.)