How to create a .RC file to include version information & icons? - c#

Im a bit new to this stuff. I Want to generate a .rc file that would include Version Information & Also contain Icons in it..
Version Information:
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
{
BLOCK "StringFileInfo"
{
BLOCK "040904b0"
{
VALUE "CompanyName", "JACK Inc.\0"
VALUE "FileDescription", "MyApp\0"
VALUE "FileVersion", "1.0.0.0\0"
VALUE "LegalCopyright", "© 2017 JACK Inc. All Rights Reserved\0"
VALUE "OriginalFilename", "MyApp\0"
VALUE "ProductName", "MyApp\0"
VALUE "ProductVersion", "1.0.0.0\0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1200
}
}
The icons Portion:
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_MYAPP_ICON ICON "icon1.ico"
IDI_MYAPP_ICON_SMALL ICON "icon2.ico"
I already have windows sdk wherein i will use the rc.exe to compile it to a .res file to be used as a Win32Resource in a csproj file . Im only confused on how to correctly script the .rc file to include both of the above contents.. Please Help...

Probably you can generate this.
-------VB6-------
"%ProgramFiles%\Microsoft Visual Studio\VB98\Wizards\rc.exe" /r /fo "Resources.res" "Resources.rc"
-------project.vbp-------
ResFile32="Resources.res"

Related

Long path \\?\ workaround not working on some installs

The app I'm working on needs to handle files with very long file/path names. It's a .Net 4.6 application so I've implemented the pre-4.6.2 workaround to allow the \\?\ syntax as outlined here and here.
This is the code I'm using to enable the feature (I can't modify the app.config so this has to be set in code):
var type = Type.GetType("System.AppContext");
if (type != null)
{
AppContext.SetSwitch("Switch.System.IO.UseLegacyPathHandling", false);
AppContext.SetSwitch("Switch.System.IO.BlockLongPaths", false);
var switchType = Type.GetType("System.AppContextSwitches");
if (switchType != null)
{
// We also have to reach into System.AppContextSwitches and manually update the cached private versions of these properties (don't ask me why):
var legacyField = switchType.GetField("_useLegacyPathHandling", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
legacyField?.SetValue(null, (Int32)(-1)); // <- caching uses 0 to indicate no value, -1 for false, 1 for true.
var blockingField = switchType.GetField("_blockLongPaths", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
blockingField?.SetValue(null, (Int32)(-1)); // <- caching uses 0 to indicate no value, -1 for false, 1 for true.
}
}
This works (yay!) on all the machines we've tested on, except one (boo!). The machine in question is a Windows 10 Pro installation, like the others, and has the same registry settings in the [Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem] namespace.
The error message on this particular machine is:
The given path format is not supported
The one difference we can see on that machine is that when looking at a very long file in Windows File Explorer, the 'Location' field uses the \\?\ syntax in the r-click > Properties menu.
I'm guessing that there's some registry key that is causing both that difference in File Explorer, and the failure of my fix, but somewhere other than the FileSystem namespace mentioned above.
Has anyone encountered a similar issue, or have an idea of other registry areas that might be relevant?
You can set those AppContext switches on a machine-wide basis via the registry if you don't want to set them in each App.config file individually:
These settings will affect all .NET apps that don't specify a different value in their App.config file. That is, the registry setting only changes the default value, which can still be overridden with app-specific values by specifying <AppContextSwitchOverrides value="..." />
EnableLongPath.reg :
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AppContext]
"Switch.System.IO.BlockLongPaths"="false"
"Switch.System.IO.UseLegacyPathHandling"="false"
C:\>regedit.exe EnableLongPath.reg

C# Open Registry Key when only a prefix portion of the name is known

I am working with these two registry keys.
64 bit Firefox version:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Mozilla Firefox (????)
32 bit Firefox version:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Mozilla Firefox xx.xx.xx (x86 en-US)
What I want is to read the key called InstallLocation inside that path. The issue is in the path. The path has Firefox version which has version number in it.
I can hard code the path, but when Firefox is updated, the the path is also updated, so it won't work after the update.
Is there a way to dynamically just read the part of the path and parse out the version to reach to the key?
In other words, is there a way to read the path up to Mozilla Fireox and ignore the rest, because I just want see if it this path exist, if it does, go inside the path to get the key-value.
Update
Thanks to konkked
var has32bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla Firefox"));
var has64bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla FireFox"));
How can I get a key-value inside the Mozilla Firefox folder?? Because the above code only returning true of false.
Try using below and it will have the install path
var path = Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe", "", null);
You could get all of the subkeys of an entry using RegistryKey.GetSubKeyNames Method () and then do a where to see if any are FireFox
var has32bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla Firefox"));
var has64bit =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall")
.GetSubKeyNames()
.Any(a=>a.StartsWith("Mozilla FireFox"));
Also notice in a comment you said
There should be a better way to do this rather than collecting alllll (sic)
of the keys inside uninstall, as it can grow pretty big. #MarcB thank
you tho.
I don't think there is a better way to partially match against a subkey
And to answer comment :
Thank you! it's working. Is there a away (sic) to get values inside that
full path afte (sic) like InstallLocation
You can get the actual subkey when you decide which version you want, but I am not sure how you are going to decide that, but here is an example of how to access the values:
var subkey32BitBase =
Registry.LocalMachine
.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
var fireFoxKeys = subkey32BitBase.GetSubKeyNames(subkey32base);
foreach(var fireFoxSubKey in fireFoxSubKeys)
{
Console.WriteLine(
subkey32BitBase
.GetSubKey(fireFoxSubKey)
.GetValue("InstallLocation")
);
}
If Firefox is installed it will register itself to the "Open With..." list of HTML files.
The application names to open html files with are stored under the file type's registry key, under the OpenWithList subkey. The path to applications themselves are stored under HKCR\Applications.

How can I open a file location or open a folder location in MonoDevelop Gtk#?

I want to open a file's location and select the file in explorer on Mac, Ubuntu from MonoDevelop.
This code is working on Windows (but it is not working on Mac and Ubuntu):
System.Diagnostics.Process.Start("explorer.exe", "/select, " + fileaddress);
Dim dir_path As String = "/media/os/test"
' Windows path example: dir_path = "C:\test"
Process.Start("file://" & dir_path)
Tested and worked on Ubuntu and Windows XP.
Source: http://www.stevenbrown.ca/blog/archives/156
By 2020-10, in mono 6.10, the above method didn't work on Ubuntu 20.04. The below approach solved the problem.
System.Diagnostics.Process.Start("mimeopen", "/var/tmp");
You can use 'open' on Mac, like this
System.Diagnostics.Process.Start("open", $"-R \"{File_Path_You_Wanna_Select}\"");
Here -R means reveal, to select in the Finder instead of opening.
To find more usage for open, just type open in terminal.
Using Process.Start() you bypass the .NET framework and move into the platform you're running onto, executing an arbitrary process.
On Windows you want to open the Windows Explorer, on Mac you want to open Finder and on Ubuntu it's simply called File Browser.
There is no Environment.OpenFileBrowser(string path) method in the framework, so you will have to let your program determine which platform it is running on, and open the approperiate file viewer.
See How to check the OS version at runtime e.g. windows or linux without using a conditional compilation statement to perform the former.
You are calling an OS specific (Windows) method. That won't work cross-platform.
Try the following inside a function/method:
Example - inside click event:
protected void OnOpen (object sender, EventArgs e)
{
using(FileChooserDialog chooser =
new FileChooserDialog(null,
"Select document to open...",
null,
FileChooserAction.Open,
"Open Selected File",
ResponseType.Accept,
"Discard & Return to Main Page",
ResponseType.Cancel))
{
if (chooser.Run () == (int)ResponseType.Accept)
{
System.IO.StreamReader file = System.IO.File.OpenText (chooser.Filename);
/* Copy the contents to editableTxtView <- This is the Widget Name */
editableTxtView.Buffer.Text = file.ReadToEnd ();
/* If you want to read the file into explorer, thunar, Notepad, etc.,
* you'll have to research that yourself. */
//Close file - - KEEP IT CLEAN - - & deAllocated memory!!
file.Close ();
}
}
}
The file has now been copied into an editable (Default) or read only (set in properties pad) textviewer Gtk widget. From there you should be able to manipulate it as you so choose.

How to get the (.lnk) shortcut filepath in a program which started by the shortcut?

I have a c# program which open *.postfix file.
If a user runs a (.lnk)shortcut which points to my type of file, my program will open the target.
So, how could my program know it is started by a (.lnk)shortcut (and get it's file path)?
In some circumstances,i need to replace the .lnk file.
Thanks!
Edited
First, thanks to guys who answered my question.
By following #Anders answer, i find out my problem lays here.
I made some changes to windows registry, so browser knows to throw customized protocol string to certain program.
some thing like this..
[InternetShortcut]
URL=myProtocol://abcdefg.....
That's maybe why i lost lpTitle. :(
I'm going to try this way:
Whenever my program invoked, of course fed with %1, program checks current opened explorer(Window), and try to get it's current path with IWebBrowserApp. With that path and desktop of course, scan and analyze *.lnk to determine which one to replace.
I think this will probably work, but not be sure. I will try.
continued
In native code you can call GetStartupInfo, if the STARTF_TITLEISLINKNAME bit is set in STARTUPINFO.dwFlags then the path to the .lnk is in STARTUPINFO.lpTitle. I don't know if there is a .NET way to get this info, you probably have to P/Invoke...
You don't. There's no way to do it. End of story.
So this has been brought to my attention due to a recent downvote. There's an accepted answer showing an idea that gets the path to the launching shortcut most of the time. However my answer is to the whole. OP wants the link to the shortcut so he can change it. That is what can't be done most of the time.
Most likely case is the shortcut file exists in the start menu but is unwritable. However other cases involve the shortcut coming from another launching application that didn't even read it from a disk but from a database (I've seen a lot of corporate level restricted application launch tools). I also have a program that launches programs from shortcuts not via IShellLink but by parsing the .lnk file (because it must not start COM for reasons) and launching the program contained. It doesn't pass STARTF_TITLEISLINKNAME because it's passing an actual title.
If you're using Visual Studio Setup Project to build an installer and do the file type association, you should follow these instructions http://www.dreamincode.net/forums/topic/58005-file-associations-in-visual-studio/
Open up your solution in Visual studio.
Add a Setup Project to your solution by file , add project,New project, Setup & Deployment projects,Setup project
Right-click on your setup project in the "Solution Explorer" window,Select view,then select file types.
you'll see the "file types" window displayed in Visual studio.At the top of the window will be "File types on target machine"
Right-click on "File types on target machine".the menu will pop up with Add "file type" Click on this.
you'll see "New document Type#1" added,and "&open"underneath it.
The "new document type#1" can be anything you want - change it to something descriptive.although the user never sees this,never use something common- be as unique as possible,Because you can overlay current file associations without even realizing it.For example,you might think"pngfile" might be a useful name- but using that will now send all"*.png" files to your application,instead of to an image viewer.A good practice maybe "YourCompantName.Filetype",where your company name is your name of your company's name, and "Filetype" is a descriptive text of your file.
In the "properties" window for your new type,you will need to change a few properties.:
Command:Change to the application that you want to run.If you click on the "..." and you will proberly want to locate and use the "primary Output..." File
Description: This is the description of the file type(if it doesn't describe it's self"
Extensions:This your list of extensions for you chosen Program.Separate each one with a ","
Icon:This will associate the icon with your file type,This shows up in the window explorer.
Now we move to that "&open ".This is an action that is available if your right-click on the file.The default action("&Open" is currently set as the default) is what happens when you double click on the file.Right click on your "New document type#1" to add actions,but for the moment,lets define our "&open" action
Click on "&Open".You will see in the properties window "Name","Arguments","Verbs". Verb is hidden from the user,but is the key that is stored in the registry.Leave it same as the name,But without the "&".The default for"Arguments" is "%1",Which means to pass the full path and filename to your application.You can add other stuff here as well,if you need to pass flags to your application to do special stuff.All this infomaton is getting passed to your application on the command line,so you'll need to be familiar with the "Environment.CommandLine" object.
If you need to set a different action as your default,just right click on the action and "set as default"
Basically, you'll pass the file path as an argument to your program. Then if it's a console application or Windows Forms , you should check the arguments in Program.Main
static void Main(string[] args)
{
//if file association done with Arguments %1 as per forum post above
//you file path should be in args[0]
string filePath = null;
if(args != null && args.Length > 0)
filePath = args[0];
}
For a WPF application you'll need to handle that in the StartUp event for your Application
void App_Startup(object sender, StartupEventArgs e)
{
string filePath = null;
if ((e.Args != null) && (e.Args.Length > 0))
{
filePath = e.Args[0];
}
}

changing the assembly title

I changed the assembly title of WPF-application from "Name1" to "Name2".
Files with extension ".sct" associate with this application.
I use RegistryKey. I associate file extension with application each time the application runs:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
...
RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Classes", true);
key.CreateSubKey("." + extension).SetValue(string.Empty, extension + "_auto_file");
key = key.CreateSubKey(extension + "_auto_file");
key.CreateSubKey("DefaultIcon").SetValue(string.Empty, icon);
key = key.CreateSubKey("Shell");
key.SetValue(string.Empty, "Open");
key = key.CreateSubKey("Open");
key.CreateSubKey("Command").SetValue("", "" + applicationExecutablePath + " %1");
...
}
Now when I install application in default directory and open .sct file properties I see old application name "Name1" instead of "Name2".
But if I install the application in another directory then application name in file properties changes to "Name2".
Why does it happen?
I changed the assembly title of WPF-application from "Name1" to "Name2".
That is an assembly TITLE? Name?
I use RegistryKey. I associate file extension with application each time the application runs:
Here we go, beginner mistakes and worst practices. Your prgoram may not have the rights for that. This should be done ONLY by an installer level, not by a user executing pgogram.
Now when I install application in default directory and open .sct file properties I see old
application name "Name1" instead of "Name2".
Also after a restart? See, the registry is likely cached and you dont run it from an installer. Ergo you see outdated values. Try restarting the compuer.

Categories

Resources