I am using the following code to open flash:
private Process flash = new Process();
flash.StartInfo.FileName = ("Flash.exe");
flash.Start();
The target machine has many version of flash like flash cs5,4,3. I want to open the newest version or let the user choose, how can I possibly do that?
Typically speaking, all other flash installations would be in different program folders, so you would just need to make sure you're running Flash.exe from the right folder. For instance, my current installation lies here: C:\Program Files (x86)\Adobe\Adobe Flash CS5\Flash.exe, but an alternate one could very well be in C:\Program Files (x86)\Adobe\Adobe Flash CS4\Flash.exe`.
An important thing to notice is that you can't assume the user installed flash CS* in its default directory! You should always query the Windows registry to find the list of installed products.
Also, another notice would be that you don't need parentheses around string literals. So you can just write:
string foo = "Hello!";
instead of
string foo = ("Hello!");
Edit 1:
Hey, I found a similar problem being treated in a forum thread here! I downloaded the code sample and ran it through a vb.net -> C# converter (like this one) and got it to work after a few minor syntax tweaks. Now it's able to output a list of the installed programs with their appropriate version numbers.
There will be a bunch of methods that get programs form e.g. certain users. All of these will then be placed in a common list, returned to the user. Now, this seems perfect, but there is just one flaw - no path is available... so far!
You can just query the UninstallString, and get a path to the uninstaller (which is IIRC in the same folder as Flash.exe). For instance, in GetUninstallKeyPrograms, after the
try
{
IsSystemComponent = Convert.ToInt32(CurrentSubKey.GetValue("SystemComponent", 0));
}
snippet, you can try to get the UninstallString value in order to obtain the path. Hope it helps!
Related
I'm trying to create certain functionality within my C# winforms application.
I want to be able to replicate what programs like Discord, NVidia GeForce Experience, and Steam have created in their apps. Which is the ability to display a list of your installed applications while linking them to their respectable executable files.
Discord scans your system so it knows about every application you have installed and displays which game you are currently playing in its interface without any input from the user.
(This is the most relevant functionality to what I'm after)
I know how to check through the registry in C# to return a list of installed applications. I've seen many Stackoverflow questions asked about that, it is not what I need help with.
What I'm having trouble with is trying to extract information from that list to tell me where each one is installed or has its .exe file which runs the game.
Through my research into this, I've found that there isn't really a reliable way to do that through those registry keys. Even though some subkeys have a value named 'InstallLocation', half of them don't have an actual path filled in.
This is the code I have so far. (I know this isn't the only place programs could be installed, I just want a to create a working demo and then look through currentUser and the other paths where apps can be installed.) :
static void Main(string[] args)
{
getPrograms();
}
private static void getPrograms()
{
string registry_key = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (RegistryKey subkey = key.OpenSubKey(subkey_name))
{
Console.WriteLine(subkey.GetValue("DisplayName"));
Console.WriteLine("-------------------------");
}
}
}
}
This works to display installed programs, yet half of the subkeys dont even have their DisplayName value set.
Would scanning for every .exe on the system be a better way to approach this, even though I would probably have to weed through installers and the like?
TL;DR: I'm trying to display a list of installed applications. When one is selected by the user, it's placed on a watch list so *my* application knows when the selected application is running and when it has closed down.
Thank you in advance for any and all help or advice given.
EDIT: Just to add, I have the code needed to watch for when a selected application is running and when it closes down. That all works fine.
I just want to allow for the option to select from a list instead of filling in input fields for the application name and .exe location.
EDIT2: I know the code I have provided is for a console app. I am trying to build the functionality in isolation by itself and then integrate it with my existing winforms app.
Usually a program of such kind provides a link for user to click (to start) - it doesn't expect user to start it by using CMD - so it puts an entry in the Start Menu (C:\ProgramData\Microsoft\Windows\Start Menu\Programs). I think this covers most programs you are interested in.
Each entry is a .lnk file with which you can check its Target, which is usually the full path to an executable. Here is some code example. Hope this helps.
I need to remove Application launch and "Pin this application to taskbar" from the taskbar context menu for an application. Reason is that the application cannot start standalone, it must be fed with information from another application.
Does anyone know how?
According to this post, you can use the Windows API Code Pack but the required classes are internal. The OP said that they copied 50k lines of code to get it working. I'm not sure if it's improved since that post but here's a workaround I just thought of. Since you can only pin EXE files (and shortcuts as per comment) to the taskbar, you could rename your application to a non-exe extension (most non-exe extensions cannot be pinned).
When you want to call it from your other app, rename it to .exe, launch it, then rename it back again. For example:
Process p = new Process();
//fake extension so it can't be drag/dropped to taskbar
string fakeExtensionName = #"C:\MyFile\myProgram.test";
//what it's actually called
string exeExtensionName = #"C:\MyFile\myProgram.exe";
//rename the fake one to the real one
File.Move(fakeExtensionName, exeExtensionName);
p.StartInfo.FileName = exeExtensionName;
//launch the real one
p.Start();
//rename it back to the fake extension
File.Move(exeExtensionName, fakeExtensionName);
Anyone can rename it to an exe if they really wanted to, so your program should assume that a user can launch it directly and handle that scenario, but any file can be pinned to the taskbar by renaming it to an exe so there's no protection around that.
Ok, i found a ugly but easy solution here https://stackoverflow.com/a/3872503/1323570
apparantly the registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileAssociation\AddRemoveNames contains some words that may not exist in an executable if pinning should be possible.
you can also read more here: http://www.west-wind.com/weblog/posts/2009/Oct/08/Application-that-wont-Pin-to-Taskbar-in-Windows-7
Edit:
Found the way to do it properly:
Add the key:
HKEY_CLASSES_ROOT\Applications\Example.exe\NoStartPage
ref: http://msdn.microsoft.com/en-us/library/windows/desktop/hh127439(v=vs.85).aspx
Just as the title states, is there an Adobe equivalent to the Java deployment.properties file?
I am writing a c# application to test installations of application in our network. The top three on my boss's list are java, flash, and reader. I need to be able to find out what versions of each application are installed on a machine for the reports im going to generate (force the user to update/etc).
I know i can check version number and confirm the ability of IE to access my JRE by checking "\Sun\Java\Deployment\deployment.properties". What file would I check to confirm the same for adobe reader and flash?
Thanks in advance for any help given or links provided to more info.
edit: I need to do this from the browser.
This is not a very clean solution, but since the only "official" way seems to be to check it from the Windows registries perhaps this will help:
We know that the flash files are located are in the (windows directory)\system32\Macromed\Flash (or SysWow64\Macromed\Flash on 64 bit systems).
Each time a flash updates it keeps the track of the progress in the log files. Depending on the flash version you will either have a) install.log (very old versions of flash) or b) FlashInstall.log
a) If you browse through the file you see various entires and one type goes like this:WriteRegStr: "HKEY_CURRENT_USER\SOFTWARE\Macromedia\FlashPlayer" "FlashPlayerVersion"="10.0.45.2".
Now you can just go through that file bottom-top and match the "FlashPlayerVersion"= string to get the most recent version.
However, this is for a really old versions of flash and the install.log file never got deleted from this directory, so make sure you check for the FlashInstall.log too!
b) Use a similar approach, except the new install logs don't keep the "WriteRegStr" information. Now you can instead look for the dll file name itself, for example my last update created an install log 0009 [I] 00000014 C:\WINDOWS\system32\Macromed\Flash\NPSWF32_11_5_502_146.dll, meaning my flash version is 11.5.502.146
another options are to
check the plugin core files creation date and compare with the versions release dates (quite unreliable in case someone somehow manages to install an older version)
check the actual property of the NPSWF[..version..].dll file. You can see all the complete and precise version details in the "Version" tab. however, I don't know how to access the rightclick->properties from inside a script, so you'll have to find out by yourself if you decide to go for this option
ask the unicorns
I am trying to use R(D)Com interface. I have R 2.12.1 installed on machine. For using this interface in C#, I loaded rscproxy_1.3-1 package and then installed R_Scilab_DCOM3.0-1B5 on my machine. Also, I copied sciproxy.dll from Program Files\R(D)COM Server\Scilab to Program Files\R(D)COM Server\bin, as informed while installing the interface.
My Problem:
As a part of testing, I tried the code from blog post http://vvella.blogspot.com/2010/08/integrate-c-net-and-r-taking-best-of.html. But my form application failed due to exception raised by statement rconn.Init(“R”). The exception text was Exception from HRESULT: 0x80040013 I tried to run samples from Programs->R->R(D)COM Server->Server 01 Basic Test. On launched form, I clicked button “Start R” but it failed with error printed in text box as “Initializing R...Function call failed Code: -2147221485 Text: installation problem: unable to load connector”
I tried this:
I tried to troubleshoot it with the help of Index html page, and there under installation section, I found that there must be rproxy.dll under installed R/Bin folder. Also, HKEY_LOCAL_MACHINE\Software\R-core\R\InstallPath should point to installation folder.
Things lacking on my machine are
the installed R/bin folder doesn’t
contain rproxy.dll. Where can I get
this dll? Or is it sciproxy.dll
instead?
HKEY_LOCAL_MACHINE\Software\R-core\R\InstallPath
points to installation folder, but
there is no entry under
HKEY_CURRENT_USER\Software.
I can guess there is something fishy about installation, or registering COM server. But I am not successful in figuring it out.
Could you please tell me where am I going wrong?
thanks,
Kapil
Oh god I remember this being a huge pain in the arse. Lets see if I can remember... And before I start, I warn you that I just "got this working" and never cared to work out if I could remove parts from the process.
Downloads are available from http://rcom.univie.ac.at/download.html . If I remember correctly, the RandFriends package is all you need, it installs a crapload (just install it all) but is simple. Alternatively, I think if you install the 'rscproxy' package in R you can just download the 'statconnDCOM' and install that. Memory is hazy, but I know one of these methods results in an annoying splash screen everytime you run your C# executable, and one doesn't. Although that could have just been some setting I played with.
Now, I can't remember how you verify that stuff has installed successfully. Pretty sure it comes with examples though. Once that is started, get your C# project open. Reference the following projects,
StatConnectorCommonLib
STATCONNECTORSRVLib
In your code, you will probably want to implement a IStatConnectorCharacterDevice so you get the R output coming back out in C#. Your code to initialise will then look something like,
private StatConnector _StatConn;
private IStatConnectorCharacterDevice _CharDevice;
private Whatever()
{
// declare
_StatConn = new StatConnectorClass();
_CharDevice = new MyCharDevice();
// init R, wire up char device
_StatConn.Init("R");
_StatConn.SetCharacterOutputDevice(_CharDevice);
}
Then you should be able to just use the functions as needed
_StatConn.EvaluateNoReturn("x <- 3");
var returnObj = _StatConn.Evalute("1 + 1");
Hope that helps.
tl;dr download RAndFriends, do fresh install with that
I had a similar problem calling R.Init(), I found R.GetErrorText() returns the actual error message
I am building a C# windows application.
I want it so whenever I click the update button in my form the application will Start looking for whether there is a new version avaliable on my Server.
If there is then proceed to update the Software.
How is this usually handled?
Take a look at Click Once. This thread might also make an interesting read.
Let me start by saying we offer a complete updating solution which includes:
An open source updater, wyUpdate, written in C#
The free AutomaticUpdater control that you can just add to your .NET app's form
wyBuild is used to build patches and manage your versions
wyUpdate handles all of the Vista/Windows 7 UAC problems and all the file permission problems that inevitably pop up when you're trying to update complex software.
That being said, if you want to build your own updater here are some tips:
Building your own updater
A good place to start is the wyUpdate C# source code I mentioned above. You can cannibalize it and use it for your own purposes. Some of the algorithms it contains:
Full Windows Vista / Windows 7 UAC support
Ability for limited users to check and then update if they have credentials
Support for wonky corporate inernet. (If you've ever worked with a corporation this is a real problem).
Quick extracting, patching, and installing of files.
Registry support.
Roll back files & registry on error or cancellation by the user
Self-update (no files left behind)
We also have the file specifications here.
Automatic updating
Since being automatic is a requirement let me tell you how we do it with our AutomaticUpdater control.
We use named pipes to communicate between the standalone updater (wyUpdate) and the Automatic Updater control sitting on your program's form. wyUpdate reports progress to the Automatic Updater, and the Automatic Updater can tell wyUpdate to cancel progress, to start downloading, start extracting, etc.
This keeps the updater separate from your application.
In fact, the exact named pipes C# code we use is included in an article I wrote a little while back: Multi-process C# app like Google Chrome.
If you want your app to be updated automatically from a website and handle the code by yourself do the following steps:
Create an XML file with a unique name for example help.xml and build a structure to specify the list of files to be updated in specific directories and version and etc. Then upload them on your website.
App after connecting to website downloads this help.xml file and reads the content to make sure there are any
new files (update files) on the website...
If a new version of files was existed so start downloading from URL specified in help.xml file!
Other answers look great.
However, if you're looking to hand-roll your own for whatever reason, simply put an XML file with information you need for your update process (e.g. description and version number of currently available version) somewhere on a webserver and use an HttpWebRequest (or HttpWebClient?) to download this file and process like you would any XML.
I use this simple method in peSHIr Tweets and it works great. Just update this file after you put a new version online for download and your update check will find it. Anything about this process is changeable the way you like, as you wrote it yourself.
Unless this is a private project for your own amusement/use/learning - like in my case - do look if anything already available suits your needs though!
Take a look: Update Checker, I have wrote it to show the easy way to implement this feature in C#.
This XML file manages the updates:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myCoolApp>
<currentVersion>
<major>9</major>
<minor>1</minor>
<build>5</build>
</currentVersion>
<path>http://TestApp.exe</path>
</myCoolApp>
The main funtion Check4Update() reads the XML file and parse it:
XmlDocument oDom = new XmlDocument();
oDom.Load(_sXmlConfig);
string str = oDom.SelectSingleNode("//currentVersion/major").InnerText;
Int32.TryParse(str, out _nMajor);
str = oDom.SelectSingleNode("//currentVersion/minor").InnerText;
Int32.TryParse(str, out _nMinor);
str = oDom.SelectSingleNode("//currentVersion/build").InnerText;
Int32.TryParse(str, out _nBuild);
_sNewVersionPath = oDom.SelectSingleNode("//path").InnerText;