create a desktop shortcut to AD homedirectory path using C# - c#

This is what i have written so far. I am having an issue creating a desktop shortcut with the home directory path. What is the best way to capture the path and create a shortcut link on the desktop with the homedirectory path? Any help is very much appreciated as i'm a beginner with C#.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices;
using System.Management;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
String username = Environment.UserName;
try
{
DirectoryEntry myLdapConnection = createDirectoryEntry();
DirectorySearcher search = new DirectorySearcher(myLdapConnection);
search.Filter = "(cn=" + username + ")";
// add the objects to search for
string[] requiredProperties = new string[] {"homeDirectory"};
foreach (String property in requiredProperties)
search.PropertiesToLoad.Add(property);
SearchResult result = search.FindOne();
if (result != null)
{
foreach (String property in requiredProperties)
foreach (Object myCollection in result.Properties[property])
Console.WriteLine(String.Format("{0,-20} : {1}",
property, myCollection.ToString()));
}
else Console.WriteLine("User not found!");
}
catch (Exception e)
{
Console.WriteLine("Exception caught:\n\n" + e.ToString());
}
}
static DirectoryEntry createDirectoryEntry()
{
// create and return new LDAP connection
DirectoryEntry ldapConnection = new DirectoryEntry("Domain.com");
ldapConnection.Path = "LDAP://OU=User,DC=test,DC=domain,DC=com";
ldapConnection.AuthenticationType = AuthenticationTypes.Secure;
return ldapConnection;
}
}
}

Your issue can be broken up into 2 problems:
1. How to get the homeDirectory attribute.
You may have this already, but I didn't see it in your code snippet, so here is how to get the homeDirectory property:
Using the current logic you have, you can add this into your foreach loop that loops through requiredProperties:
if (property == "homeDirectory"){
var homeDirectoryPath = result.Properties[property].ToString();
// create desktop shortcut here
}
Or if you want to get it directly out of that loop:
var homeDirectoryPath = result.Properties["homeDirectory"].ToString();
2. Take that path and turn use it to create a desktop shortcut.
This post details how to create a desktop shortcut. Use code this code and place the homeDirectory path in the correct place. It looks to be the TargetPath.
You need to make sure to add a COM reference to Windows Scripting Host when using this: Project > Add Reference > COM > Windows Script Host Object Model.
Here is the code from that post:
using IWshRuntimeLibrary;
object shDesktop = (object)"Desktop";
WshShell shell = new WshShell();
string shortcutAddress = (string)shell.SpecialFolders.Item(ref shDesktop) + homeDirectoryPath;
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutAddress);
shortcut.Description = "New shortcut for a Notepad";
shortcut.Hotkey = "Ctrl+Shift+N";
shortcut.TargetPath = Environment.GetFolderPath(Environment.SpecialFolders.System) + homeDirectoryPath;
shortcut.Save();

Here is the Final code. If home drive is not mapped it checks to see if the user is on the domain by pinging the DC. If user is on the domain it maps the drive and adds a shortcut of the drive to user's desktop.
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.IO;
using IWshRuntimeLibrary;
using System.Reflection;
using Shell32;
using System.Net.NetworkInformation;
using System.Threading;
using System.Management;
using System.Security.Principal;
if (!Directory.Exists(#"H:\"))
{
//ping Hdrive server
try
{ //find current domain controller
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
string controller = context.ConnectedServer;
//ping current domain controller
Ping ping = new Ping();
PingReply pingReply = ping.Send(controller);
if (pingReply.Status == IPStatus.Success)
{
try
{
//get current username
String username = Environment.UserName;
//Lookup current username in AD
DirectoryEntry myLdapConnection = createDirectoryEntry();
DirectorySearcher search = new DirectorySearcher(myLdapConnection);
search.Filter = "(cn=" + username + ")";
//Search for User's Home Directory
string[] requiredProperties = new string[] { "homeDirectory" };
foreach (String property in requiredProperties)
search.PropertiesToLoad.Add(property);
SearchResult result = search.FindOne();
// If home directory info is not blank
if (result != null)
{
//pass the homedirectory path into a variable
string path = "";
foreach (String property in requiredProperties)
foreach (Object myCollection in result.Properties[property])
path = (myCollection.ToString());
//map Hdrive (non persistent map)
System.Diagnostics.Process.Start("net.exe", "use /persistent:NO H: " + path);
//create a desktop shortcut to Hdrive
var wsh = new IWshShell_Class();
IWshRuntimeLibrary.IWshShortcut shortcut = wsh.CreateShortcut(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\H Drive.lnk") as IWshRuntimeLibrary.IWshShortcut;
shortcut.TargetPath = path;
shortcut.Save();
}
}
catch (Exception)
{
//do nothing
}
}
}
}
catch (Exception)
{
//do nothing
}
}
}
public static DirectoryEntry createDirectoryEntry()
{
// create and return new LDAP connection
DirectoryEntry ldapConnection = new DirectoryEntry("mydomain.com");
ldapConnection.Path = "LDAP://mydomain.com/OU=Users,DC=mydomain,DC=Com";
ldapConnection.AuthenticationType = AuthenticationTypes.Secure;
return ldapConnection;
}

Related

Cannot show the content properly in looping

I have write a c# code to retrieve all the file names follow by printing one of the information inside. Example File contains (file1.mht, file2.mht, file3.mht). Maybe the contain inside is (aaaaaa, bbbbbb, cccccc) follow the sequence of the file.
Example out output:
file1.mht aaaaaa
file2.mht bbbbbb
file3.mht cccccc
But I encounter the problem it cannot loop the file name follow by showing the content inside. Anyone can helps? Current result is it show all the directory first and only done the work for the first one in directory.
using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Configuration;
using System.Collections.Specialized;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args)
{
DirectoryInfo mht_file = new DirectoryInfo(#"C:\Users\liewm\Desktop\SampleTest\");
FileInfo[] Files = mht_file.GetFiles("*.mht");
string str = "";
string mht_text = "";
string directory = "";
string listInfo = "";
foreach (FileInfo file in Files)
{
str = file.Name;
directory = mht_file + str;
Console.WriteLine(directory);
}
foreach (char filePath in directory)
{
//Here is my work to retrieve the data in the file
Console.WriteLine("Names:" + str + " " + "Component:" + component);
Console.ReadKey();
}
}
}
}
From your question I understand that you want to print the file name followed by the content of the same, if so you can try:
DirectoryInfo mht_file = new DirectoryInfo(#"C:\Users\liewm\Desktop\SampleTest\");
FileInfo[] Files = mht_file.GetFiles("*.mht");
foreach (FileInfo file in Files)
{
// read the content of the file
var content = File.ReadAllText(file.FullName);
// from your question "Example out output: file1.mht aaaaaa"
Console.WriteLine($"{file.Name} {content}");
}
only done the work for the last one in directory.
Yes, that's cause your directory variable is a string string directory = "" which will get overridden by the last value of loop iteration. You rather want to store in a string[] rather if you want to process all of them.
foreach (FileInfo file in Files)
{
str = file.Name;
directory = mht_file + str;
Console.WriteLine(directory);
}
Please try this.
foreach (FileInfo file in Files)
{
str = file.Name;
directory += mht_file + str;
Console.WriteLine(directory);
}

Additional information: The process cannot access the file 'C:\****** \New Bitmap Image.bmp' because it is being used by another process

I am getting below error message while executing code:
Additional information: The process cannot access the file 'C:\Users\Administrator\Desktop\Project\Source \New Bitmap Image.bmp' because it is being used by another process.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace MoveFiles
{
class Program
{
static void Main(string[] args)
{
string SourceFile = #"C:\Users\Administrator\Desktop\Project\Source ";
string Destination = #"C:\Users\Administrator\Desktop\Project\Destination";
string[] piclist = Directory.GetFiles(SourceFile, "*.bmp");
foreach (string f in piclist)
{
SourceFile.Clone();
Console.WriteLine(f);
File.Copy(Path.Combine(SourceFile, f), Path.Combine(Destination, f), true);
}
}
}
}
Please try using this, this is to copy across one file.
Note: This is a code running on a button click on windows form.
OpenFileDialog obj = new OpenFileDialog();
obj.ShowDialog();
string startLoc = obj.FileName;
string destinationlocation = #"D:\Pictures";
string destinationfile = Path.Combine(destinationlocation, obj.SafeFileName);
if (!Directory.Exists(destinationlocation))
{
Directory.CreateDirectory(destinationlocation);
}
File.Copy(obj.FileName, destinationfile);

ObjectARX read/write .dwg files that are not currently opened in autocad

Im trying to modify a .dwg file and overwrite the .dwg file once done, all that without opening it in autocad. I've read about RealDWG but the goal here is not to be in a standalone mode. the autocad plugin runs from autocad and needs to modify and write to some .dwg files that are not opened in the current project. So far I create a Database object and Read the .dwg file into it but im having errors when I want to rewrite into it. Here is the code its in C#,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace ModifyClosedDWG
{
public class DWGEditor
{
private static string filepath = #"E:\...\DrawingTest.dwg";
[CommandMethod("modifyDWG")]
public void addTextToDWG()
{
Database workingDB = HostApplicationServices.WorkingDatabase;
Editor ed = doc.Editor;
Database db = new Database(false, true);
try
{
db.ReadDwgFile(filepath, System.IO.FileShare.ReadWrite, false, "");
db.CloseInput(true);
HostApplicationServices.WorkingDatabase = db;
}
catch (Autodesk.AutoCAD.Runtime.Exception e)
{
ed.WriteMessage("\nUnable to read drawing file : " + e.StackTrace);
return;
}
using (BlockTable bt = db.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
{
using (BlockTableRecord btr = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite) as BlockTableRecord)
{
MText objText = new MText();
objText.SetDatabaseDefaults();
objText.Location = new Autodesk.AutoCAD.Geometry.Point3d(2, 2, 0);
objText.Contents = "added text in a closed .dwg file!";
objText.TextStyleId = db.Textstyle;
btr.AppendEntity(objText);
}
}
HostApplicationServices.WorkingDatabase = workingDB;
db.SaveAs(filepath, DwgVersion.Current);
}
}
}
the error output :
Autodesk.AutoCAD.Runtime.Exception: eWasOpenForWrite
at Autodesk.AutoCAD.DatabaseServices.Database.SaveAs(String fileName, DwgVersion version)
at ModifyClosedDWG.DWGEditor.addTextToDWG() in E:\PROJETS\ELI017\07 In Works documents\VisualC#Projects\ModifyClosedDWG\ModifyClosedDWG\DWGEditor.cs:line 64
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()
I found the solution so I'll put the new code here...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace ModifyClosedDWG
{
public class DWGEditor
{
private static string filepath = #"E:\PROJETS\ELI017\07 In Works documents\dwg\DrawingTest.dwg";
[CommandMethod("modifyDWG")]
public void addTextToDWG()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database workingDB = HostApplicationServices.WorkingDatabase;
Database db = new Database(false, true);
try
{
db.ReadDwgFile(filepath, System.IO.FileShare.ReadWrite, false, "");
db.CloseInput(true);
HostApplicationServices.WorkingDatabase = db;
}
catch (Autodesk.AutoCAD.Runtime.Exception e)
{
ed.WriteMessage("\nUnable to open .dwg file : " + e.StackTrace);
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
MText objText = new MText();
objText.SetDatabaseDefaults();
objText.Location = new Autodesk.AutoCAD.Geometry.Point3d(2, 2, 0);
objText.Contents = "added text in a closed .dwg file!";
objText.TextStyleId = db.Textstyle;
btr.AppendEntity(objText);
tr.AddNewlyCreatedDBObject(objText, true);
tr.Commit();
}
HostApplicationServices.WorkingDatabase = workingDB;
db.SaveAs(filepath, DwgVersion.Current);
}
}
}

Sending Email through Outlook 2010 via C#

I am trying to send an email from inside my C# console App. I have added the references and using statements but it seems I have not added everything I need. This is the first time I have ever attempted to do this so I figure there is something I have forgotten.
I got this code snippet from the MSDN site http://msdn.microsoft.com/en-us/library/vstudio/ms269113(v=vs.100).aspx
Here is the code that I am getting issues with in VS 2010
using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
namespace FileOrganizer
{
class Program
{
private void CreateMailItem()
{
//Outlook.MailItem mailItem = (Outlook.MailItem)
// this.Application.CreateItem(Outlook.OlItemType.olMailItem);
Outlook.Application app = new Outlook.Application();
Outlook.MailItem mailItem = app.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = "This is the subject";
mailItem.To = "someone#example.com";
mailItem.Body = "This is the message.";
mailItem.Attachments.Add(logPath);//logPath is a string holding path to the log.txt file
mailItem.Importance = Outlook.OlImportance.olImportanceHigh;
mailItem.Display(false);
}
}
}
replace the line
Outlook.MailItem mailItem = (Outlook.MailItem)
this.Application.CreateItem(Outlook.OlItemType.olMailItem);
with
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem mailItem = app.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
Hope this helps,
This is how you can send an email via Microsoft Office Outlook. In my case I was using Office 2010, but I suppose it should work with newer versions.
The upvoted sample above just displays the message. It does not send it out. Moreover it doesn't compile.
So first you need to add these references to your .NET project:
Like I said in my comment to his OP:
You will need to add the following references: (1) From .NET tab add
Microsoft.Office.Tools.Outlook for runtime v.4.0.*, then (2) again
from .NET tab add Microsoft.Office.Interop.Outlook for version
14.0.0.0 in my case, and (3) COM object Microsoft Office 12.0 Object Library for Microsoft.Office.Core.
Then here's the code to send out emails:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Configuration;
using System.IO;
using System.Net.Mail;
using System.Runtime.InteropServices;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
public enum BodyType
{
PlainText,
RTF,
HTML
}
//....
public static bool sendEmailViaOutlook(string sFromAddress, string sToAddress, string sCc, string sSubject, string sBody, BodyType bodyType, List<string> arrAttachments = null, string sBcc = null)
{
//Send email via Office Outlook 2010
//'sFromAddress' = email address sending from (ex: "me#somewhere.com") -- this account must exist in Outlook. Only one email address is allowed!
//'sToAddress' = email address sending to. Can be multiple. In that case separate with semicolons or commas. (ex: "recipient#gmail.com", or "recipient1#gmail.com; recipient2#gmail.com")
//'sCc' = email address sending to as Carbon Copy option. Can be multiple. In that case separate with semicolons or commas. (ex: "recipient#gmail.com", or "recipient1#gmail.com; recipient2#gmail.com")
//'sSubject' = email subject as plain text
//'sBody' = email body. Type of data depends on 'bodyType'
//'bodyType' = type of text in 'sBody': plain text, HTML or RTF
//'arrAttachments' = if not null, must be a list of absolute file paths to attach to the email
//'sBcc' = single email address to use as a Blind Carbon Copy, or null not to use
//RETURN:
// = true if success
bool bRes = false;
try
{
//Get Outlook COM objects
Outlook.Application app = new Outlook.Application();
Outlook.MailItem newMail = (Outlook.MailItem)app.CreateItem(Outlook.OlItemType.olMailItem);
//Parse 'sToAddress'
if (!string.IsNullOrWhiteSpace(sToAddress))
{
string[] arrAddTos = sToAddress.Split(new char[] { ';', ',' });
foreach (string strAddr in arrAddTos)
{
if (!string.IsNullOrWhiteSpace(strAddr) &&
strAddr.IndexOf('#') != -1)
{
newMail.Recipients.Add(strAddr.Trim());
}
else
throw new Exception("Bad to-address: " + sToAddress);
}
}
else
throw new Exception("Must specify to-address");
//Parse 'sCc'
if (!string.IsNullOrWhiteSpace(sCc))
{
string[] arrAddTos = sCc.Split(new char[] { ';', ',' });
foreach (string strAddr in arrAddTos)
{
if (!string.IsNullOrWhiteSpace(strAddr) &&
strAddr.IndexOf('#') != -1)
{
newMail.Recipients.Add(strAddr.Trim());
}
else
throw new Exception("Bad CC-address: " + sCc);
}
}
//Is BCC empty?
if (!string.IsNullOrWhiteSpace(sBcc))
{
newMail.BCC = sBcc.Trim();
}
//Resolve all recepients
if (!newMail.Recipients.ResolveAll())
{
throw new Exception("Failed to resolve all recipients: " + sToAddress + ";" + sCc);
}
//Set type of message
switch (bodyType)
{
case BodyType.HTML:
newMail.HTMLBody = sBody;
break;
case BodyType.RTF:
newMail.RTFBody = sBody;
break;
case BodyType.PlainText:
newMail.Body = sBody;
break;
default:
throw new Exception("Bad email body type: " + bodyType);
}
if (arrAttachments != null)
{
//Add attachments
foreach (string strPath in arrAttachments)
{
if (File.Exists(strPath))
{
newMail.Attachments.Add(strPath);
}
else
throw new Exception("Attachment file is not found: \"" + strPath + "\"");
}
}
//Add subject
if(!string.IsNullOrWhiteSpace(sSubject))
newMail.Subject = sSubject;
Outlook.Accounts accounts = app.Session.Accounts;
Outlook.Account acc = null;
//Look for our account in the Outlook
foreach (Outlook.Account account in accounts)
{
if (account.SmtpAddress.Equals(sFromAddress, StringComparison.CurrentCultureIgnoreCase))
{
//Use it
acc = account;
break;
}
}
//Did we get the account
if (acc != null)
{
//Use this account to send the e-mail.
newMail.SendUsingAccount = acc;
//And send it
((Outlook._MailItem)newMail).Send();
//Done
bRes = true;
}
else
{
throw new Exception("Account does not exist in Outlook: " + sFromAddress);
}
}
catch (Exception ex)
{
Console.WriteLine("ERROR: Failed to send mail: " + ex.Message);
}
return bRes;
}
And here's how you'd use it:
List<string> arrAttachFiles = new List<string>() { #"C:\Users\User\Desktop\Picture.png" };
bool bRes = sendEmailViaOutlook("senders_email#somewhere.com",
"john.doe#hotmail.com, jane_smith#gmail.com", null,
"Test email from script - " + DateTime.Now.ToString(),
"My message body - " + DateTime.Now.ToString(),
BodyType.PlainText,
arrAttachFiles,
null);
You need to cast the
app.CreateItem(Outlook.OlItemType.olMailItem)
object in
Outlook.MailItem mailItem = app.CreateItem(Outlook.OlItemType.olMailItem)
to
Outlook.MailItem type
since no implicit casting is available.
Replace
Outlook.MailItem mailItem = app.CreateItem(Outlook.OlItemType.olMailItem);
with
Outlook.MailItem mailItem = (Outlook.MailItem)app.CreateItem(Outlook.OlItemType.olMailItem);

How to get path of Firefox history.sqlite file programatically?

The path of firefox history file contain a Profile Number how can i get this number dynamically in C#
C:\Users\\AppData\Roaming\Mozilla\Firefox\Profiles\.default\formhistory.sqlite
you need to read profiles.ini file and catch the default profile
using System;
using System.Linq;
using System.IO;
namespace Firefox
{
class Reader
{
public static string ReadFirefoxProfile()
{
string apppath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string mozilla = System.IO.Path.Combine(apppath, "Mozilla");
bool exist = System.IO.Directory.Exists(mozilla);
if (exist)
{
string firefox = System.IO.Path.Combine(mozilla, "firefox");
if (System.IO.Directory.Exists(firefox))
{
string prof_file = System.IO.Path.Combine(firefox, "profiles.ini");
bool file_exist = System.IO.File.Exists(prof_file);
if (file_exist)
{
StreamReader rdr = new StreamReader(prof_file);
string resp = rdr.ReadToEnd();
string[] lines = resp.Split(new string[] { "\r\n" }, StringSplitOptions.None);
string location = lines.First(x => x.Contains("Path=")).Split(new string[] { "=" }, StringSplitOptions.None)[1];
string prof_dir = System.IO.Path.Combine(firefox, location);
return prof_dir;
}
}
}
return "";
}
}
}
You can read out the following ini file which contains the profile names of every firefoxprofile:
"C:\Users\Username\AppData\Roaming\Mozilla\Firefox\profiles.ini"
Click the Windows Start button and type %APPDATA%\Mozilla\Firefox\Profiles\ in the Search box at the bottom of the Start menu, without pressing Enter. A list of profiles will appear at the top of the Start menu.
Click on the profile with “default” in the name to open it in a window.

Categories