问题
Purpose: Associate a new progid to an extension so that file will open with new associated program.
Programming Language: C#
Description:
I want to create a program to associate another program with an extension from my recommended program list. My program is working in windows-xp and windows-7 but it is not working in windows-8. when i searched for the issue, i found that in Windows-8 there is an additional key called "Hash".
I am not able to find the hash for my new progid.
Steps Being Followed:
Created a class say "MyTest.txt" in HKEY_CLASSES_ROOT eg: HKEY_CLASSES_ROOT MyTest.txt Shell Open Command (Default) "[PATH TO NOTEPAD] "%1""
I noticed that same key is also created in LOCAL_MACHINE folder
Now I want to assign this "MyTest.txt" ProgID to
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts.txt\UserChoice]
"Hash"="????"
"ProgId"="MyTest.txt"
But I am unable to find the Hash for my newly created ProgId "MyTest.txt" in C#.
Code Using C#:
public void changeExtensionDefaultProgram(string fileext,string operationmode, string oldkeyname, string fileopenerpath)
{
try
{
if (!string.IsNullOrEmpty(fileext))
{
//Global declaration for new custom key
string sCustomkeyName = string.Format("MYTest.{0}", fileext);
RegistryKey OurKey = Registry.LocalMachine;
RegistryKey ParentKey = Registry.LocalMachine;
RegistryKey GlobalLocalMachineKey = Registry.LocalMachine;
RegistryKey GlobalRootKey = Registry.ClassesRoot;
string keyToCopy = @"SOFTWARE\Classes";
ParentKey = ParentKey.OpenSubKey(keyToCopy, true);
string programopencommand = string.Format(@"SOFTWARE\Classes\{0}\Shell\{1}\Command", oldkeyname, operationmode);
OurKey = OurKey.OpenSubKey(programopencommand, true);
if (OurKey != null)
{
//check if backup exists then do not take backup, along with source key
string backupkeyName = string.Format("MyBKP{0}", fileext);
RegistryKey rBackupKeyName = GlobalRootKey.OpenSubKey(backupkeyName, true);
if (rBackupKeyName==null)
{
//backup the keys with a new name MyBKP{ext}
FileAssoc.CopyKey(GlobalRootKey, oldkeyname, backupkeyName);
MessageBox.Show(string.Format("Backup Done -- GlobalRootKey=> oldkeyname:{0} as newbackupname:{1}", oldkeyname, backupkeyName));
}
//check if MyTest.{ext} Custom Class for extension exists
RegistryKey rCustomkeyName = GlobalRootKey.OpenSubKey(sCustomkeyName, true);
if (rCustomkeyName == null)
{
//copy the keys with a new name MyTest.{ext}
FileAssoc.CopyKey(GlobalRootKey, oldkeyname, sCustomkeyName);
}
if (rBackupKeyName != null)
{
rBackupKeyName.Close();
}
if (rCustomkeyName != null)
{
rCustomkeyName.Close();
}
//Perform in localmachine
bool isFlagSet = setMicrosoftDefaultProgID(fileext, sCustomkeyName, fileopenerpath);
if (isFlagSet)
{
string newopencommand = string.Format(@"SOFTWARE\Classes\{0}\Shell\{1}\Command", sCustomkeyName, operationmode);
rCustomkeyName = GlobalLocalMachineKey.OpenSubKey(newopencommand, true);
if (rCustomkeyName != null)
{
rCustomkeyName.SetValue("", "\"" + fileopenerpath + "\"" + " \"%1\"");
MessageBox.Show(string.Format("going to set GlobalRootKey\\{0} with fileopenerpath:{1}", programopencommand, fileopenerpath));
rCustomkeyName.Close();
}
else
{
MessageBox.Show(string.Format("Failed to modify GlobalRootKey\\{0} with fileopenerpath:{1}", programopencommand, fileopenerpath));
}
}
}
};
}
catch (Exception ex)
{
MessageBox.Show("changeExtensionDefaultProgram()::Exception raised" + ex.ToString());
}
}
public bool setMicrosoftDefaultProgID(string fileextension, string keyname, string fileopenerpath)
{
try
{
RegistryKey OurKey = Registry.CurrentUser;
//HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice = MyTest.txt
string programopencommand = string.Format(@"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\UserChoice", fileextension);
try
{
cSecurityOwnerShip sec = new cSecurityOwnerShip();
string name = sec.UserName(cSecurity.EXTENDED_NAME_FORMAT.NameSamCompatible);
if (name == null)
{
name = sec.UserName();
}
string sKey = OurKey.ToString()+@"\" + programopencommand;
try
{
sec.ChangeMYKeyOwnership(sKey, cSecurityOwnerShip.SE_OBJECT_TYPE.SE_REGISTRY_KEY);
}
catch (Exception ex)
{
sec.ChangeMyKeyPermissions(cSecurityOwnerShip.ROOT_KEY.HKEY_CURRENT_USER, programopencommand, name, cSecurityOwnerShip.eRegAccess.Full_Control, cSecurityOwnerShip.eAccsType.Access_Allowed, cSecurityOwnerShip.eFlags.Inherit_Child);
}
RegistryKey NewSubKey = OurKey.CreateSubKey(programopencommand);
if (NewSubKey != null)
{
try
{
if (NewSubKey != null)
{
NewSubKey.SetValue("ProgID", keyname);
//NewSubKey.SetValue("Hash", "v8gh4ng+Pro=");
return true;
}
else
return false;
}
catch (Exception ex)
{
MessageBox.Show("setMicrosoftDefaultProgID()::SetValue() Exception raised" + ex.ToString());
return false;
}
}
else
{
MessageBox.Show(string.Format("setMicrosoftDefaultProgID()::programopencommand:{0} not exist", programopencommand));
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("setMicrosoftDefaultProgID()::Exception raised :{0}", ex.ToString()));
return false;
}
}
catch (Exception ex)
{
MessageBox.Show("setMicrosoftDefaultProgID()::Exception raised" + ex.ToString());
return false;
}
finally
{
}
}
Issue i am facing is in this commented line to find and change "Hash"
//NewSubKey.SetValue("Hash", "v8gh4ng+Pro=");
回答1:
Windows 8 does not want random apps tampering with default application associations. Users and only users get to decide what application they choose for a file extension.
Don't do this. Let the user choose default application by opening "Default Programs" dialog from Control Panel.
If you're in a corporate environment and want to copy settings, you can export associations using group policies. See Windows 8: Associate a file Type or protocol with a specific app using GPO.
来源:https://stackoverflow.com/questions/26031054/c-sharp-code-to-change-the-default-program-attached-with-an-extension-using-a-cu