I'm trying to associate midi files with my c# application
And I got the following exception , can anyone tell me why?
My code:
public static void Associate()
{
RegistryKey FileReg = Registry.CurrentUser.CreateSubKey("Software\\Classes\\.mid");
RegistryKey AppReg = Registry.CurrentUser.CreateSubKey("Software\\Classes\\Applications\\MyApp.exe");
RegistryKey AppAssoc = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.mid");
//FileReg.CreateSubKey("DefaultIcon").SetValue("", "image_path");
FileReg.CreateSubKey("PerceivedType").SetValue("", "Bytes");
AppReg.CreateSubKey("shell\\open\\command").SetValue("", "\"" + System.Reflection.Assembly.GetExecutingAssembly().Location + "\" %1");
AppReg.CreateSubKey("shell\\edit\\command").SetValue("", "\"" + System.Reflection.Assembly.GetExecutingAssembly().Location + "\" %1");
//AppReg.CreateSubKey("DefaultIcon").SetValue("", "image_path");
AppAssoc.CreateSubKey("UserChoice").SetValue("Progid", "Applications\\MyApp.exe");
SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
}
Exception come from the call:
AppAssoc.CreateSubKey("UserChoice").SetValue("Progid", "Applications\\MyApp.exe");
Additional information: Access to the registry key
'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts.mid\UserChoice'
is denied.
Anyone can tell me what do to ?
Related
So, I made a speech recognizer and it was working fine, I'm not sure why is it giving me this error right now. Any ideas?
String res = e.Result.Text;
string yol = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
string settings = ("#" + yol + "\\" + "settings" + "\\");
if (res == "Hi Bot")
{
pictureBox1.Image = Image.FromFile(settings + "mybot.png"); -->That's where i get the error
say(greetings_random());
}
string yol = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
string settings = ("#" + yol + "\\" + "settings" + "\\");
This means that settings has the value "#C:\Path\To\Executable\settings\".
That's probably not what you want -- I'm not sure what the # is trying to achieve, but it's not valid at the beginning of a path like that.
For future, debugging this code and inspecting the settings variable would quickly have shown the problem.
That said, it's recommended to use Path.Join (.NET Core 2.1+) or Path.Combine instead of string concatenation to create paths like this.
I am using regasm.exe to install my Outlook plugin on the end users' machines. However, I noticed that in a terminal server environment, my addin wouldn't load for all users. I found out that the addin registry keys were being created under the current user hive and not the local machine hive.
Is there something i can add to my plugin which will enable regasm to create/delete the keys under HKLM as well as current user when a user installs or uninstalls the plugin?
I had other, but similar issues with regasm.exe, as I wanted to avoid the UAC in windows when registering the AddIn, so I wrote a com registrar by myself, which does the proper registry keys to register the com addin.
You would have to change this code accordingly to have the registry keys in those places were you want them, and obviously have similar code to rollback those changes on uninstalling your add-in
class ComAddinRegistrar
{
private static string CLSID = "{CLSID}";
private static string ASSEMBLY_NAME = "Outlook.Addin";
private static string ASSEMBLY_DLL = "Outlook.Addin.dll";
private static string VERSION = "1.0.0.0";
private static string IMPLEMENTED_CATEGORY = "{CATEGORY_ID}";
public static void RegisterAddin(bool is64Bit)
{
// Get path of dll:
var apPpath = System.Reflection.Assembly.GetExecutingAssembly().Location;
apPpath = Path.GetDirectoryName(apPpath);
var path = ASSEMBLY_DLL;
var dllPath = Path.Combine(apPpath, path);
// Com registration
RegistryKey rkey;
if (is64Bit)
rkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)
.OpenSubKey("Software").OpenSubKey("Classes", true);
else
rkey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32)
.OpenSubKey("Software").OpenSubKey("Classes", true);
var comAssemblyNameKey = rkey.CreateSubKey(ASSEMBLY_NAME); //HKCU/Software/Classes/Outlook.Addin
comAssemblyNameKey.SetValue("", ASSEMBLY_NAME); // default value
var clsidAssemblyNameComKey = comAssemblyNameKey.CreateSubKey("CLSID"); //HKCU/Software/Classes/Outlook.Addin/{CLSID}
clsidAssemblyNameComKey.SetValue("", CLSID); // default value
RegistryKey clsidComKey;
if (is64Bit)
clsidComKey = rkey.CreateSubKey("CLSID").CreateSubKey(CLSID); //HKCU\Software\Classes\CLSID\{CLSID}
else
clsidComKey = rkey.CreateSubKey("Wow6432Node").CreateSubKey("CLSID").CreateSubKey(CLSID); //HKCU\Software\Classes\CLSID\{CLSID}
clsidComKey.SetValue("", ASSEMBLY_NAME); // default value
var inProcServerKey = clsidComKey.CreateSubKey("InprocServer32"); //HKCU\Software\Classes\CLSID\{CLSID}\InProcServer32
inProcServerKey.SetValue("", "mscoree.dll");
inProcServerKey.SetValue("ThreadingModel", "Both");
inProcServerKey.SetValue("Class", "Outlook.Addin.Addin");
inProcServerKey.SetValue("Assembly", $"Outlook.Addin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
inProcServerKey.SetValue("RuntimeVersion", "v4.0.30319");
inProcServerKey.SetValue("CodeBase", dllPath);
var versionKey = inProcServerKey.CreateSubKey(VERSION); //HKCU\Software\Classes\CLSID\{CLSID}\InProcServer32\1.0.0.0
versionKey.SetValue("Class", "Outlook.Addin.Addin");
versionKey.SetValue("Assembly", $"Outlook.Addin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
versionKey.SetValue("RuntimeVersion", "v4.0.30319");
versionKey.SetValue("CodeBase", dllPath);
var progIdKey = clsidComKey.CreateSubKey("ProgId"); //HKCU\Software\Classes\CLSID\{CLSID}\ ProgId
progIdKey.SetValue("", ASSEMBLY_NAME);
var implementedCategoryKey = clsidComKey.CreateSubKey("ImplementedCategories"); //HKCU\Software\Classes\CLSID\{CLSID}\ImplementedCategories
implementedCategoryKey.CreateSubKey(IMPLEMENTED_CATEGORY);
//AddIn registration
//HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\Outlook\Addins\Outlook.Addin
var okey = Registry.CurrentUser.OpenSubKey("SOFTWARE")
.OpenSubKey("Microsoft")
.OpenSubKey("Office")
.OpenSubKey("Outlook")
.OpenSubKey("Addins", true);
var addinKey = okey.CreateSubKey(ASSEMBLY_NAME);
addinKey.SetValue("FileName", dllPath);
addinKey.SetValue("FriendlyName", "My addin");
addinKey.SetValue("Description", "some addin description");
addinKey.SetValue("LoadBehavior", 3, RegistryValueKind.DWord);
}
}
Found the answer by digging through my sample NetOffice Outlook addin project!
All you need are a couple of public static methods with the ComRegisterFunctionAttribute and ComUnregisterFunctionAttribute attributes. Regasm.exe will automatically execute the code in these methods when your plugin is installed or uninstalled.
See below for the code I am using which is slightly modified from the template to support the HKLM registry key. Add these methods to your Outlook addin class.
Alek's answer can be used if you wish to handle these manually.
[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type type)
{
try
{
// add codebase value
Assembly thisAssembly = Assembly.GetAssembly(typeof(OutlookPlugin));
RegistryKey key = Registry.ClassesRoot.CreateSubKey("CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\InprocServer32\\1.0.0.0");
key.SetValue("CodeBase", thisAssembly.CodeBase);
key.Close();
key = Registry.ClassesRoot.CreateSubKey("CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\InprocServer32");
key.SetValue("CodeBase", thisAssembly.CodeBase);
key.Close();
// add bypass key
// http://support.microsoft.com/kb/948461
key = Registry.ClassesRoot.CreateSubKey("Interface\\{000C0601-0000-0000-C000-000000000046}");
string defaultValue = key.GetValue("") as string;
if (null == defaultValue)
key.SetValue("", "Office .NET Framework Lockback Bypass Key");
key.Close();
// add outlook addin key
Registry.ClassesRoot.CreateSubKey(#"CLSID\{" + type.GUID.ToString().ToUpper() + #"}\Programmable");
Registry.CurrentUser.CreateSubKey(_addinOfficeRegistryKey + _prodId);
RegistryKey rk = Registry.CurrentUser.OpenSubKey(_addinOfficeRegistryKey + _prodId, true);
rk.SetValue("LoadBehavior", Convert.ToInt32(3));
rk.SetValue("FriendlyName", _addinFriendlyName);
rk.SetValue("Description", _addinDescription);
rk.Close();
//Add registry key under HKLM
RegistryKey regHKLM = Registry.LocalMachine;
regHKLM = regHKLM.CreateSubKey(#"SOFTWARE\Microsoft\Office\Outlook\Addins\" + _prodId);
regHKLM.SetValue("Friendly Name", _addinFriendlyName);
regHKLM.SetValue("Description", _addinDescription);
regHKLM.SetValue("LoadBehavior", 3, RegistryValueKind.DWord);
}
catch (System.Exception ex)
{
string details = string.Format("{1}{1}Details:{1}{1}{0}", ex.Message, Environment.NewLine);
MessageBox.Show("An error occured." + details, "Register " + _prodId, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
[ComUnregisterFunctionAttribute]
public static void UnregisterFunction(Type type)
{
try
{
Registry.ClassesRoot.DeleteSubKey(#"CLSID\{" + type.GUID.ToString().ToUpper() + #"}\Programmable", false);
Registry.CurrentUser.DeleteSubKey(_addinOfficeRegistryKey + _prodId, false);
Registry.LocalMachine.DeleteSubKey(#"SOFTWARE\Microsoft\Office\Outlook\Addins\" + _prodId);
}
catch (System.Exception throwedException)
{
string details = string.Format("{1}{1}Details:{1}{1}{0}", throwedException.Message, Environment.NewLine);
MessageBox.Show("An error occured." + details, "Unregister " + _prodId, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I am trying to make to create a .cmd file with this code into it: call .\CopyToTarget.cmd w60 glb "C:\Users\oma\me\trunk-r664\USB-map". I am creating this code ~5 times.
But since \trunk-r664\ is already in use it seems like I cannot write: #"\trunk-r664\USB-map" into the .cmd file for some reason. Does anyone know how to fix it? It keeps getting me the error: UnauthorizedAccesExpection was unhandled, ccess to the path 'C:\Users\me\Desktop\trunk-r664\USB-map' is denied.
using (StreamWriter sw = File.CreateText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
+ "\\trunk-r664\\trunk\\cmd\\custom\\RunAll.cmd"))
{
for (int j=0;j<installeerlijst64.Count;j++)
{
sw.WriteLine("call .\\CopyToTarget.cmd " + installeerlijst64[j] + " glb" +
File.CreateText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\trunk-r664\USB-map"));
}
}
I tried this too, but it tells me I am using an illegal character:
"\""+File.CreateText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
+ #"\trunk-r664\USB-map" + "\""));
File.CreateText will create a new file. First time when for loop execute, it will create and open the file USB-map and hold the handle of that file. During second iteration of for loop, it will try to do the same thing. Hence, already in use error.
Remove File.CreateText and you will get the desired result.
sw.WriteLine("call .\\CopyToTarget.cmd " + installeerlijst64[j] + " glb " + "\"" +
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\trunk-r664\USB-map" + "\"");
I am trying to make a file extension associated to my application like make any file with .ztr work directly with my app when user double clicks that file.
I am using VS2012 , C# , Windows 7
I did simulate this example here.
Sure with some modification like fix Import Dll put also failed.
public static void Register (string Ext,string Program,string Ico)
{
string prog = Path.GetFileName(Program);
RegistryKey file = Registry.CurrentUser.CreateSubKey("Software\\Classes\\"+Ext);//.osa
RegistryKey App = Registry.CurrentUser.CreateSubKey("Software\\Classes\\Applications\\" + prog);//osama.exe
RegistryKey Link = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + Ext);//.osa
file.CreateSubKey("DefultIcon").SetValue("", Ico);
file.CreateSubKey("PerceivedType").SetValue("","Text");
App.CreateSubKey("shell\\open\\command").SetValue("", "\"" + Application.ExecutablePath + "\"%1");
App.CreateSubKey("shell\\edit\\command").SetValue("", "\"" + Application.ExecutablePath + "\"%1");
App.CreateSubKey("DefultIcon").SetValue("", Ico);
//There is Change here you
Link.CreateSubKey("UserChoice").SetValue("Progid", Program);
Invoke.SHChangeNotify(0x08000000, 0x0000, IntPtr.Zero, IntPtr.Zero);
}
I'm developing an windows application and i want to set this application as windows start-up application for that i use this code:-
Code
public static void SetStartup(string AppName,
bool enable)
{
try
{
string runKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\Run";
Microsoft.Win32.RegistryKey startupKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(runKey);
if (enable)
{
if (startupKey.GetValue(AppName) == null)
{
startupKey.Close();
startupKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(runKey, true);
startupKey.SetValue(AppName, Assembly.GetExecutingAssembly().Location + " /StartMinimized");
startupKey.Close();
}
}
else
{
startupKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(runKey, true);
startupKey.DeleteValue(AppName, false);
startupKey.Close();
}
}
catch
{
}
}
Calling code on application load
SetStartup(Application.ExecutablePath, true);
And this code works fine.It sets application as a start-up application.
I check that executing msconfig command in run window.It shows this application checked in start-up tab.But when i restarts the system it doesn't start application.
Can any one tell me what is the problem and how can i solve that problem.
If everything points to it being in startup then I can only assume that that part of it is correct, but the application is failing to start for some reason.
When you start an application on run, it's working directory is set to C:\Windows\System32
I have had issues with applications that may be looking for files in its home directory such as config files but are unable to find them.
Normally files referenced the normal way will be found anyway, but if you are manually specifying a path in your code you can use:
string pathToDLL = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "LibraryFile.dll");
Using AppDomain.CurrentDomain.BaseDirectory should give the path of the your application exe, rather than the working directory.
Could this be the cause of the problem?
Also, I'm going to assume Vista upwards is the OS, and if that's the case then your application would have to be running as elevated to write to that registry. So, if UAC is off and the machine is restarted then your application, if it's set in the manifest to run as requireAdministrator, would fail silently.
Martyn
Finally i got a answer for this problem.Use StreamWriter for creating a URL link of application instead of creating a LNK into start-up folder.
Create shortcut
private void appShortcutToStartup()
{
string linkName ="MytestLink";
string startDir = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
if (!System.IO.File.Exists(startDir + "\\" + linkName + ".url"))
{
using (StreamWriter writer = new StreamWriter(startDir + "\\" + linkName + ".url"))
{
string app = System.Reflection.Assembly.GetExecutingAssembly().Location;
writer.WriteLine("[InternetShortcut]");
writer.WriteLine("URL=file:///" + app);
writer.WriteLine("IconIndex=0");
string icon = Application.StartupPath + "\\backup (3).ico";
writer.WriteLine("IconFile=" + icon);
writer.Flush();
}
}
}
Delete Shortcut
private void delappShortcutFromStartup()
{
string linkName ="MytestLink";
string startDir = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
if (System.IO.File.Exists(startDir + "\\" + linkName + ".url"))
{
System.IO.File.Delete(startDir + "\\" + linkName + ".url");
}
}
This code works very fine.
I believe the most simplest way would be by following the below steps
1.) Build your application
2.) Navigate to your debug folder
3) Copy the exe and place it at your Startup location
**C:\Documents and Settings\user\Start Menu\Programs\Startup**
OR
Simply drag your exe over start menu--> Program-->Startup and Paste it there (i.e
releasing the mouse button)
I guess that would do your work
Hope it helps