I am trying to create a shortcut to a folder that my program creates when the user adds a profile to the device. The shortcut link to the folder and is supposed to appear in the users Favorites (the library to the side in Windows 7 Explorer) and have the logo.ico from our project. I thought I had to use the IWshRuntimeLibrary, but the code randomly stops on me and does not return any errors... any help?
Note: The profilePath, profileName, and executablePath all return the correct data and point to the correct locations for the items I am trying to access and modify.
public static bool CreateProfileShortcut(string profilePath, string profileName, string executablePath)
{
bool success = false;
string favoritesPath = "";
IWshRuntimeLibrary.IWshShell wsh;
IWshRuntimeLibrary.IWshShortcut shortcut;
try
{
if (!String.IsNullOrWhiteSpace(profilePath) && Directory.Exists(profile.Path))
{
favoritesPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
if (!File.Exists(favoritesPath + "\\Links\\" + profileName + ".lnk"))
{
wsh = new IWshRuntimeLibrary.WshShell();
shortcut = (IWshRuntimeLibrary.IWshShortcut)wsh.CreateShortcut(favoritesPath + "\\Links\\" + profileName + ".lnk");
shortcut.TargetPath = profilePath;
shortcut.IconLocation = executablePath + "\\Icons\\logo.ico";
shortcut.Save();
}
}
}
catch (Exception e)
{
MessageBox.Show(MessageBoxError(new string[] { e.TargetSite.Name, e.Message, "MinorError" }));
success = false;
}
return success;
}
Try looking at both this question and this question. If I'm understanding, I think you want to be able to create a shortcut in the "favorite" area of Windows 7.
Related
I am working in a project that's already built and functional at the moment. But there is an issue when I try to insert finger print from device to database table. Let me write it was working fine earlier. But when I setup a new computer or moved the project in a new environment, it throws an exception:
Retrieving the COM class factory for component with CLSID {00853A19-BD51-419B-9269-2DABE57EB61F}
failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
This is a fingerprint attendance system that uses ZkemKeeper and the dll file is attached with the project. Here is the code snippet:
/**This is a list of the users from database that uses fingerprint system - Starts**/
List<AttMachineBO> lstfrom = new List<AttMachineBO>();
for (int i = 0; i < dgv_Machine.Rows.Count; i++)
{
if (dgv_Machine.Rows[i].Cells[0].Value == null)
{
dgv_Machine.Rows[i].Cells[0].Value = false;
}
if ((bool)dgv_Machine.Rows[i].Cells[0].Value == true)
{
AttMachineBO obj = new AttMachineBO();
obj.Mechine_No = dgv_Machine.Rows[i].Cells[1].Value.ToString();
obj.Machine_Name = dgv_Machine.Rows[i].Cells[2].Value.ToString();
obj.IP_Address = dgv_Machine.Rows[i].Cells[3].Value.ToString().Trim();
lstfrom.Add(obj);
}
}
/**This is a list of the users from database that uses fingerprint system - Ends**/
Basically the above code is to load user details from table assigned with an IP address and on click, the fingerprint data will be inserted into database table from attendance device (ZKTeco i-clock 580). For inserting data, the below is code is used:
if (lstfrom.Count > 0)
{
for (int x = 0; x < lstfrom.Count; x++)
{
/Here the exception starts/
**zkemkeeper.CZKEMClass fromM = new zkemkeeper.CZKEMClass();**
lblStatus.Text = "Connect To Device " + lstfrom[x].Machine_Name + " , IP=" + lstfrom[x].IP_Address + ".....";
lblStatus.Refresh();
if (fromM.Connect_Net(lstfrom[x].IP_Address, 4370))
{
lblStatus.Text = "Register The Device To PC";
lblStatus.Refresh();
if (fromM.RegEvent(fromM.MachineNumber, 65535))
{
lblStatus.Text = "Reading All Data From Machine";
lblStatus.Refresh();
fromM.ReadAllTemplate(fromM.MachineNumber);
List<AttMachineBO> datalst = new List<AttMachineBO>();
string empId = "", name = "", fingerprintData = "", fingerprintData2 = "", password = ""; ;
int prev = 0, TmpLength = 0;
bool isEnable = false;
int k = 0;
while (fromM.SSR_GetAllUserInfo(fromM.MachineNumber, out empId, out name, out password, out prev, out isEnable))
{
lblStatus.Text = "Processing Employee with ID=" + empId + ", Name =" + name;
lblStatus.Refresh();
AttMachineBO bo = new AttMachineBO();
bo.EMP_ID = empId;
bo.EMP_Name = name;
bo.IsfingerSaa = true;
bo.IP_Address = lstfrom[x].IP_Address;
bo.Com_Id = HRMS.MAIN.HRMS.Company;
bool f = fromM.SSR_GetUserTmpStr(fromM.MachineNumber, empId, 0, out fingerprintData, out TmpLength);
bo.finger1 = fingerprintData != null ? fingerprintData : "";
f = fromM.SSR_GetUserTmpStr(fromM.MachineNumber, empId, 1, out fingerprintData, out TmpLength);
bo.finger2 = fingerprintData != null ? fingerprintData : "";
datalst.Add(bo);
}
bool flag = Facede.Attendance.InserDatabase(datalst);
if (flag)
{
MessageBox.Show("Insert Successfully.");
return;
}
else
{
MessageBox.Show("Error In Insert.");
return;
}
}
else
{
lblStatus.Text = "Device registration failed.";
lblStatus.Refresh();
}
}
else
{
lblStatus.Text = "Failed to stablish connecting to device =" + lstfrom[x].Machine_Name + ", IP =" + lstfrom[x].IP_Address + "...."; ;
lblStatus.Refresh();
}
}
}
I've highlighted in the code (Second code section) from the exception starts and bit confused how to resolve it.
The error that you are receiving is clear, zkemkeeper.dll needs to be registered on the windows system.
I don´t know if you already have all the dll files... In case that you don´t have all the dll files you should download the latest SDK version from the following link https://www.zkteco.eu/uploads/ftp/SDK/Standalone%20SDK-Ver6.3.1.34.rar
To avoid troubleshooting, you should register the 32-bit version instead of the 64-bit and compile your application for the x86 architecture.
For registering the dll, copy the contents of the 32-bit folder into c:\windows\system (or c:\windows\syswow64 if your computer is x64) and after that, open the console with admin privileges, position in the folder in which you have just copied the dll and run the following command:
regsvr32 zkemkeeper.dll
After registering the files, you need to adjust the reference to this dll.
In visual studio, delete your current reference and Add a new one in the affected project. You will find the new registered dll at the bottom of the COM tab.
After adding the reference, you need to adjust one parameter. Select the reference and right-click -> properties, it will open the properties window.. Set "Embed interop types" to false.
That should work.
I am using the following code to successfully open the requested URL in the system default browser on Windows 8.1:
public static void OpenUrlInDefaultBrowser(string url)
{
var httpKey = Registry.ClassesRoot.OpenSubKey(#"http\shell\open\command");
if (httpKey == null || httpKey.GetValue(string.Empty) == null)
return;
var cmd = httpKey.GetValue(string.Empty) as string;
if (cmd != null)
{
try
{
if (cmd.Length > 0)
{
string[] splitStr;
string fileName;
string args;
if (cmd.Substring(0, 1) == "\"")
{
splitStr = cmd.Split(new[] { "\" " }, StringSplitOptions.None);
fileName = splitStr[0] + "\"";
args = cmd.Substring(splitStr[0].Length + 2);
}
else
{
splitStr = cmd.Split(new[] { " " }, StringSplitOptions.None);
fileName = splitStr[0];
args = cmd.Substring(splitStr[0].Length + 1);
}
System.Diagnostics.Process.Start(fileName, args.Replace("%1", url));
}
}
catch (Exception)
{
// handle exception
}
}
httpKey.Close();
}
However, on my Windows Server 2008 R2 VM, this same code opens Internet Explorer (the default on that machine), but will only load the URL res://iesetup.dll/SoftAdmin.htm. IE is set to Enhanced Security Mode OFF. Chrome works as expected on this machine.
Simply invoking Process.Start(url) also fails to open the requested URL.
When I execute the following from the "Run..." menu, it works as expected: "C:\Program Files\Internet Explorer\iexplore.exe" http://example.com. The same goes for start-process http://example.com in PowerShell.
Did you try simply calling Process.Start("http://your_website_here"); ? It's not like you need to specify browser, if you want to run hyperlinks on default one.
#davidsbro - yes, i wouldn't have made it as answer otherwise :)
#mark - try http://blog.blksthl.com/2012/11/28/how-to-disable-ie-enhanced-security-in-windows-server-2012/ - that has something to do with server security settings and not application.
I wrote a modified version of your above method to start ie with command line options and is a little more detailed in figuring out which process to start.
Also, try changing the Process.Start calls in the code I'm posting to use a specific user and password.
class Program
{
static void Main(string[] args)
{
OpenUrlInBrowser("http://www.stackoverflow.com");
}
public static string GetDefaultBrowserCommand()
{
string command = null;
var httpKey = Registry.ClassesRoot.OpenSubKey(#"http\shell\open\command");
if (httpKey == null)
throw new Exception("No default browser is configured!");
else
{
command = (string)httpKey.GetValue("", "iexplore.exe");
int exeIndex = command.ToLower().IndexOf(".exe");
if (exeIndex > -1)
{
int endOfCommand = command.IndexOf('"', exeIndex);
int startOfCommand = command.LastIndexOf('"', exeIndex - 1);
if (startOfCommand > -1 && endOfCommand > -1)
{
command = command.Substring(startOfCommand + 1, endOfCommand - 1);
return command;
}
else
throw new Exception("Error: Default browser is not set in the registry correctly!");
}
else
throw new Exception("The default browser registry setting does not specify an executable!");
}
}
public static void OpenUrlInBrowser(string url)
{
string browserCommand = GetDefaultBrowserCommand();
FileInfo fi = new FileInfo(browserCommand);
ProcessStartInfo psi = null;
if (!fi.Exists)
Console.WriteLine("The default browser specified in the registry does not physical exist on disk!");
else
{
string commandFileName = Path.GetFileNameWithoutExtension(fi.FullName).ToLower();
switch (commandFileName)
{
case "iexplore":
psi = new ProcessStartInfo(browserCommand, string.Concat("\"", url, "\"", " ", "-extoff -new"));
break;
default:
psi = new ProcessStartInfo(browserCommand, string.Concat("\"", url, "\""));
break;
}
}
psi.UseShellExecute = true; //<- have to set this to make runas work
psi.Verb = "runas"; //<- instructs the process to runas administrator, which will give the user a UAC prompt if UAC is turned on.
Process.Start(psi);
}
}
I'm trying to remove a Silverlight Out Of Browser app programatically passing the arguments to sllauncher in following this post: http://timheuer.com/blog/archive/2010/03/25/using-sllauncher-for-silent-install-silverlight-application.aspx However it won't uninstall the app when given the origin.
It turns out that when you have an automatically updating Out-Of-Browser application, Silverlight stamps each application Uri with a time stamp that can be found in the application's folder in the C:\Users\Trevor\AppData\Local\Microsoft\Silverlight\OutOfBrowser(AppFolderName) metadata file. So to facilitate the removal of our app in preparation for our new one, I implemented the following:
UninstallExisting(GetInstalledAppUri()); // This is how it's called
//This is the two method's implementation
// TODO: Change to your app name.
const string appName = "YourAppNameHere";
static string silverlightOutOfBrowserFolder =
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
+ #"\Microsoft\Silverlight\OutOfBrowser";
private static string GetInstalledAppUri()
{
string xapFolderPath = Path.Combine(silverlightOutOfBrowserFolder, GetXapFolder());
string[] lines = File.ReadAllLines(Path.Combine(xapFolderPath, "metadata"), Encoding.Unicode);
string finalAppUriLine = lines.First(i => i.Contains("FinalAppUri="));
return "\"" + finalAppUriLine.Replace("FinalAppUri=", "") + "\"";
}
private static string GetXapFolder()
{
string AppXapFolder = "";
foreach (var dir in Directory.GetDirectories(silverlightOutOfBrowserFolder))
{
if (dir.Contains(appName))
{
AppXapFolder = dir;
}
}
return AppXapFolder ;
}
private static string silverlightExe
{
get
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
#"Microsoft Silverlight\sllauncher.exe");
}
}
private static void UninstallExisting(string xapUriToRemove)
{
string installArgs = "/uninstall" + " /origin:" + xapUriToRemove;
ProcessStartInfo pstart = new ProcessStartInfo(silverlightExe, installArgs);
Process p = new Process();
pstart.UseShellExecute = false;
p.StartInfo = pstart;
p.Start();
p.WaitForExit();
}
I hope this serves to save someone else the hours of time it took me to figure out about the metadata file and all the peculiarities of sllauncher.exe
I have this code that will grab the names, but how do i get each program's icon?
string SoftwareKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products";
RegistryKey rk = default(RegistryKey);
rk = Registry.LocalMachine.OpenSubKey(SoftwareKey);
string sname = string.Empty;
foreach (string skname in rk.GetSubKeyNames())
{
try
{
sname = Registry.LocalMachine.OpenSubKey(SoftwareKey).OpenSubKey(skname).OpenSubKey("InstallProperties").GetValue("DisplayName").ToString();
string Inst1 = Registry.LocalMachine.OpenSubKey(SoftwareKey).OpenSubKey(skname).OpenSubKey("InstallProperties").GetValue("InstallLocation").ToString();
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[2].Value = sname;
dataGridView1.Rows[n].Cells[3].Value = Inst1;
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
I'm not aware that InstallProperties will give you the installed executable (as indeed an installer could install multiple executable files).
If you have a means to determine the correct executable (including perhaps enumerating the .exe files in InstallLocation), you could then grab the default icon from that .exe.
For details, see
Get File Icon used by Shell
UPDATE
The following code is untested but should get you pretty close:
string Inst1 = registry.LocalMachine.OpenSubKey(SoftwareKey).OpenSubKey(skname).OpenSubKey("InstallProperties").GetValue("InstallLocation").ToString();
foreach (string file in Directory.GetFiles(Inst1, "*.exe"))
{
string filePath = Path.Combine(Inst1, file);
Icon result = Icon.ExtractAssociatedIcon(filePath);
// If result is not null, you have an icon.
}
Try this:
Icon result = Icon.ExtractAssociatedIcon(filePath);
I'm trying to user Redemption to update a user's Outlook contacts. The user I'm affecting is passed in the exchangeUser, call him "Target User".
This code works when I run it logged in as myself:
public OutlookFolders(string outlookRootFolder, string exchangeUser, string mailServer)
{
var session = new RDOSessionClass();
session.LogonExchangeMailbox(exchangeUser, mailServer);
session.Stores.FindExchangePublicFoldersStore();
var store = session.GetSharedMailbox(exchangeUser);
//...
}
I tried to log in as a 3rd user "Test User" who is not me and is not "Target User". My program brings up a password prompt at runtime when it gets to FindExchangePublicFoldersStore, and if I don't fill in my credentials it fails with the error:
System.Runtime.InteropServices.COMException (0x8004011D): Error in
IMAPISession.OpenMsgStore(pbExchangeProviderPrimaryUserGuid):
MAPI_E_FAILONEPROVIDER
ulVersion: 0
Error: Microsoft Exchange is not available. Either there are network
problems or the Exchange computer is down for maintenance.
Component: Microsoft Exchange Information Store
ulLowLevelError: 2147746069
ulContext: 1318
I tried giving "Test User" owner permission on "Target User's" Mailbox and Contacts folder. Doesn't seem to make a difference. What other permissions need to be set for this to work?
The rule of thumb is to run your code as a user who can access the mailboxes in question, call LogonExchangeMailbox for the current user, then open other users' mailboxes using GetSharedMailbox.
Here's the code for Dmitry's answer.
It also uses a function from Milan's blog.
public OutlookFolders(string exchangeUser, string mailServer)
{
var session = new RDOSessionClass();
var userFullName = GetFullName("DOMAIN-NT\\" + Environment.UserName);
session.LogonExchangeMailbox(userFullName, mailServer);
session.Stores.FindExchangePublicFoldersStore();
var store = session.GetSharedMailbox(exchangeUser);
rootFolder = store.GetDefaultFolder((rdoDefaultFolders)OlDefaultFolders.olFolderContacts);
}
public static string GetFullName(string strLogin)
{
string str = "";
string strDomain;
string strName;
// Parse the string to check if domain name is present.
int idx = strLogin.IndexOf('\\');
if (idx == -1)
{
idx = strLogin.IndexOf('#');
}
if (idx != -1)
{
strDomain = strLogin.Substring(0, idx);
strName = strLogin.Substring(idx + 1);
}
else
{
strDomain = Environment.MachineName;
strName = strLogin;
}
DirectoryEntry obDirEntry = null;
try
{
obDirEntry = new DirectoryEntry("WinNT://" + strDomain + "/" + strName);
PropertyCollection coll = obDirEntry.Properties;
object obVal = coll["FullName"].Value;
str = obVal.ToString();
}
catch (System.Exception ex)
{
str = ex.Message;
}
return str;
}