This question already has answers here:
How to get relative path from absolute path
(24 answers)
Closed 7 years ago.
I have 2 Files:
C:\Program Files\MyApp\images\image.png
C:\Users\Steve\media.jpg
Now i want to calculate the File-Path of File 2 (media.jpg) relative to File 1:
..\..\..\Users\Steve\
Is there a built-in function in .NET to do this?
Use:
var s1 = #"C:\Users\Steve\media.jpg";
var s2 = #"C:\Program Files\MyApp\images\image.png";
var uri = new Uri(s2);
var result = uri.MakeRelativeUri(new Uri(s1)).ToString();
There is no built-in .NET, but there is native function. Use it like this:
[DllImport("shlwapi.dll", CharSet=CharSet.Auto)]
static extern bool PathRelativePathTo(
[Out] StringBuilder pszPath,
[In] string pszFrom,
[In] FileAttributes dwAttrFrom,
[In] string pszTo,
[In] FileAttributes dwAttrTo
);
Or if you still prefer managed code then try this:
public static string GetRelativePath(FileSystemInfo path1, FileSystemInfo path2)
{
if (path1 == null) throw new ArgumentNullException("path1");
if (path2 == null) throw new ArgumentNullException("path2");
Func<FileSystemInfo, string> getFullName = delegate(FileSystemInfo path)
{
string fullName = path.FullName;
if (path is DirectoryInfo)
{
if (fullName[fullName.Length - 1] != System.IO.Path.DirectorySeparatorChar)
{
fullName += System.IO.Path.DirectorySeparatorChar;
}
}
return fullName;
};
string path1FullName = getFullName(path1);
string path2FullName = getFullName(path2);
Uri uri1 = new Uri(path1FullName);
Uri uri2 = new Uri(path2FullName);
Uri relativeUri = uri1.MakeRelativeUri(uri2);
return relativeUri.OriginalString;
}
Related
I'd like to open a local HTML file navigated to a specific headline with an ID.
string url = "file:///C:/myFile.html#myHeading"
If I paste the URL in the browser directly, it correctly navigates to the desired heading.
But when I try to have the system handle the URL, it omits the hash entirely.
ProcessStartInfo si = new ProcessStartInfo(url);
si.UseShellExecute = true;
Process.Start(si);
will simply open file:///C:/myFile.html.
Is there a way I can make this work?
Sadly, I don't know where this stripping happens, so my research so far turned up empty.
I tried replacing the hash symbol with its escaped form %23, which of course didn't work (could not find the file specified).
A work-around I'm using in the meantime:
From here, I wrote an extension which tells me the path to the executable set as the default app for opening files with a given extension.
public static string getDefaultAssociation(string extension)
{
if (extension.Substring(0, 1) != ".")
{
int os = extension.IndexOf('.');
if (os > 0)
{
extension = extension.Substring(os);
}
else
{
extension = "." + extension;
}
}
const int S_OK = 0;
const int S_FALSE = 1;
uint length = 0;
uint ret = AssocQueryString(AssocF.None, AssocStr.Executable, extension, null, null, ref length);
if (ret != S_FALSE)
{
//throw new InvalidOperationException("Could not determine associated string");
WriteLog("Could not determine associated string");
return "";
}
var sb = new StringBuilder((int)length); // (length-1) will probably work too as the marshaller adds null termination
ret = AssocQueryString(AssocF.None, AssocStr.Executable, extension, null, sb, ref length);
if (ret != S_OK)
{
//throw new InvalidOperationException("Could not determine associated string");
WriteLog("Could not determine associated string");
return "";
}
return sb.ToString();
}
[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern uint AssocQueryString(
AssocF flags,
AssocStr str,
string pszAssoc,
string pszExtra,
[Out] StringBuilder pszOut,
ref uint pcchOut
);
[Flags]
public enum AssocF
{
None = 0,
Init_NoRemapCLSID = 0x1,
Init_ByExeName = 0x2,
Open_ByExeName = 0x2,
Init_DefaultToStar = 0x4,
Init_DefaultToFolder = 0x8,
NoUserSettings = 0x10,
NoTruncate = 0x20,
Verify = 0x40,
RemapRunDll = 0x80,
NoFixUps = 0x100,
IgnoreBaseClass = 0x200,
Init_IgnoreUnknown = 0x400,
Init_Fixed_ProgId = 0x800,
Is_Protocol = 0x1000,
Init_For_File = 0x2000
}
public enum AssocStr
{
Command = 1,
Executable,
FriendlyDocName,
FriendlyAppName,
NoOpen,
ShellNewValue,
DDECommand,
DDEIfExec,
DDEApplication,
DDETopic,
InfoTip,
QuickTip,
TileInfo,
ContentType,
DefaultIcon,
ShellExtension,
DropTarget,
DelegateExecute,
Supported_Uri_Protocols,
ProgID,
AppID,
AppPublisher,
AppIconReference,
Max
}
So I can use
string def = getDefaultAssociation("html");
ProcessStartInfo si = new ProcessStartInfo(def);
si.Arguments = url;
si.UseShellExecute = true;
Process.Start(si);
to directly tell my default browser to go to the file URL, INCLUDING the ID hash.
File scheme (file://) just doesn't support anchors or actually any parameters, according to RFC. So query string, anchors or anything else besides path to file can be ignored by whatever processes url with this scheme, which is what happens here. If you try file:///C:/myFile.html?x=1 - query string will also be stripped. If on the other hand you'll try http://google.com?x=1#test then it will open exactly this url in browser, because other scheme.
So I'd say it works as expected and your workaround is fine.
This question already has answers here:
Best way to specify whitespace in a String.Split operation
(11 answers)
Closed 4 years ago.
I am trying to split a string in c#. I am receiving a string with multiple whitespaces and i want to split it at the whitspaces. So far all I have tried failed. It is not throwing an error put the string simply stays empty
using System;
using System.Diagnostics;
using System.Management;
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
public static Process GetActiveWindowProcess(){
var processWithFocus = GetForegroundWindow();
int processId;
GetWindowThreadProcessId(processWithFocus, out processId);
Process process = Process.GetProcessById(processId);
return process;
}
public static String getCommandLine(){
string wmiQueryString = "SELECT * FROM Win32_Process WHERE ProcessId = " + process.Id;
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
{
using (var results = searcher.Get())
{
ManagementObject mo = results.Cast<ManagementObject>().FirstOrDefault();
if (mo != null)
{
String str = (string)mo["CommandLine"];
Debug.WriteLine(str.Split(' ')); //Splitting the string
return str;
}
}
}
}
I tried all of the methods I could find yet the result is the same. The string is there but the string array is empty.
var ssizes = myStr.Split(" \t".ToCharArray());
string[] ssize = myStr.Split(null);
string[] ssize = myStr.Split(new char[0]);
//all arrays are emtpy...
Am I missing out something?
EDIT
Sorry the error was on my Site. Debug does not output the Array. I have mistaken it to be empty.
String.Split() (no parameters) does split on all whitespace (including LF/CR)
I have a folder in Windows Server with subfolders and ≈50000 files. When I click the right mouse button and choose delete (or shift+delete) – all files are deleted in 10-20 seconds.
When I delete files using code – 1500-4000 seconds.
Delete large number of files – don't work for me.
My code:
string folderPath = #"C://myFolder";
DirectoryInfo folderInfo = new DirectoryInfo(folderPath);
folderInfo.Delete(true); // true - recursive, with sub-folders
How to delete files faster?
A much faster way to delete files is to use the Windows functions instead of the .NET ones.
You will need to first import the function:
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool DeleteFile(string lpFileName);
And then you can do this:
string[] files = Directory.EnumerateFiles(path, "*". SearchOption.AllDirectories);
foreach (string file in files)
{
DeleteFile(file);
}
Once the files are deleted, which is the slowest part by using the managed APIs, you can call Directory.DeleteFolder(path, true) to delete the empty folders.
Since the question is actually about deleting network shared folders and it's stated that the explorer based delete is much faster than the C# internal delete mechanism, it might help to just invoke a windows shell based delete.
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C rd /s /q \"<your-path>\"";
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
Ofcourse, you have to replace <your-path>.
However, I don't have the infrastructure and files available to test the performance myself right now.
Not quite sure why the method DirectoryInfo.Delete() takes too much time when deleting folders that have a lot of files and sub-folders. I suspect that the method may also do quite a few things that are unnecessary.
I write a small class to to use Win API without doing too many unnecessary things to test my idea. It takes about 40 seconds to delete a folder that have 50,000 files and sub-folders. So, hope it helps.
I use this PowerScript to generate the testing files.
$folder = "d:\test1";
For ($i=0; $i -lt 50000; $i++)
{
New-Item -Path $folder -Name "test$i.txt" -ItemType "file" -Value $i.ToString();
}
The following is the code in C#.
using System;
using System.Collections.Generic;
//
using System.Runtime.InteropServices;
using System.IO;
//
namespace TestFileDelete
{
class FileDelete
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct WIN32_FIND_DATAW
{
public FileAttributes dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public UInt32 nFileSizeHigh; // DWORD
public UInt32 nFileSizeLow; // DWORD
public UInt32 dwReserved0; // DWORD
public UInt32 dwReserved1; // DWORD
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public String cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public String cAlternateFileName;
};
static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr FindFirstFileW(String lpFileName, out WIN32_FIND_DATAW lpFindFileData);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern Boolean FindNextFileW(IntPtr hFindFile, out WIN32_FIND_DATAW lpFindFileData);
[DllImport("kernel32.dll")]
private static extern Boolean FindClose(IntPtr handle);
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern Boolean DeleteFileW(String lpFileName); // Deletes an existing file
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern Boolean RemoveDirectoryW(String lpPathName); // Deletes an existing empty directory
// This method check to see if the given folder is empty or not.
public static Boolean IsEmptyFolder(String folder)
{
Boolean res = true;
if (folder == null && folder.Length == 0)
{
throw new Exception(folder + "is invalid");
}
WIN32_FIND_DATAW findFileData;
String searchFiles = folder + #"\*.*";
IntPtr searchHandle = FindFirstFileW(searchFiles, out findFileData);
if (searchHandle == INVALID_HANDLE_VALUE)
{
throw new Exception("Cannot check folder " + folder);
}
do
{
if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
{
// found a sub folder
if (findFileData.cFileName != "." && findFileData.cFileName != "..")
{
res = false;
break;
}
} // if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
else
{
// found a file
res = false;
break;
}
} while (FindNextFileW(searchHandle, out findFileData));
FindClose(searchHandle);
return res;
} // public static Boolean IsEmptyFolder(String folder)
// This method deletes the given folder
public static Boolean DeleteFolder(String folder)
{
Boolean res = true;
// keep non-empty folders to delete later (after we delete everything inside)
Stack<String> nonEmptyFolder = new Stack<String>();
String currentFolder = folder;
do
{
Boolean isEmpty = false;
try
{
isEmpty = IsEmptyFolder(currentFolder);
}
catch (Exception ex)
{
// Something wrong
res = false;
break;
}
if (!isEmpty)
{
nonEmptyFolder.Push(currentFolder);
WIN32_FIND_DATAW findFileData;
IntPtr searchHandle = FindFirstFileW(currentFolder + #"\*.*", out findFileData);
if (searchHandle != INVALID_HANDLE_VALUE)
{
do
{ // for each folder, find all of its sub folders and files
String foundPath = currentFolder + #"\" + findFileData.cFileName;
if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
{
// found a sub folder
if (findFileData.cFileName != "." && findFileData.cFileName != "..")
{
if (IsEmptyFolder(foundPath))
{ // found an empty folder, delete it
if (!(res = RemoveDirectoryW(foundPath)))
{
Int32 error = Marshal.GetLastWin32Error();
break;
}
}
else
{ // found a non-empty folder
nonEmptyFolder.Push(foundPath);
}
} // if (findFileData.cFileName != "." && findFileData.cFileName != "..")
} // if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
else
{
// found a file, delete it
if (!(res = DeleteFileW(foundPath)))
{
Int32 error = Marshal.GetLastWin32Error();
break;
}
}
} while (FindNextFileW(searchHandle, out findFileData));
FindClose(searchHandle);
} // if (searchHandle != INVALID_HANDLE_VALUE)
}// if (!IsEmptyFolder(folder))
else
{
if (!(res = RemoveDirectoryW(currentFolder)))
{
Int32 error = Marshal.GetLastWin32Error();
break;
}
}
if (nonEmptyFolder.Count > 0)
{
currentFolder = nonEmptyFolder.Pop();
}
else
{
currentFolder = null;
}
} while (currentFolder != null && res);
return res;
} // public static Boolean DeleteFolder(String folder)
};
class Program
{
static void Main(string[] args)
{
DateTime t1 = DateTime.Now;
try
{
Boolean b = FileDelete.DeleteFolder(#"d:\test1");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
DateTime t2 = DateTime.Now;
TimeSpan ts = t2 - t1;
Console.WriteLine(ts.Seconds);
}
}
}
I have this file types Filters:
public const string Png = "PNG Portable Network Graphics (*.png)|" + "*.png";
public const string Jpg = "JPEG File Interchange Format (*.jpg *.jpeg *jfif)|" + "*.jpg;*.jpeg;*.jfif";
public const string Bmp = "BMP Windows Bitmap (*.bmp)|" + "*.bmp";
public const string Tif = "TIF Tagged Imaged File Format (*.tif *.tiff)|" + "*.tif;*.tiff";
public const string Gif = "GIF Graphics Interchange Format (*.gif)|" + "*.gif";
public const string AllImages = "Image file|" + "*.png; *.jpg; *.jpeg; *.jfif; *.bmp;*.tif; *.tiff; *.gif";
public const string AllFiles = "All files (*.*)" + "|*.*";
static FilesFilters()
{
imagesTypes = new List<string>();
imagesTypes.Add(Png);
imagesTypes.Add(Jpg);
imagesTypes.Add(Bmp);
imagesTypes.Add(Tif);
imagesTypes.Add(Gif);
}
OBS: Is there any default filters in .NET or a free library for that?
I need a static method that checks if a string is an image or not. How would you solve this?
//ext == Path.GetExtension(yourpath)
public static bool IsImageExtension(string ext)
{
return (ext == ".bmp" || .... etc etc...)
}
Solution using Jeroen Vannevel EndsWith. I think it is ok.
public static bool IsImageExtension(string ext)
{
return imagesTypes.Contains(ext);
}
You could use .endsWith(ext). It's not a very secure method though: I could rename 'bla.jpg' to 'bla.png' and it would still be a jpg file.
public static bool HasImageExtension(this string source){
return (source.EndsWith(".png") || source.EndsWith(".jpg"));
}
This provides a more secure solution:
string InputSource = "mypic.png";
System.Drawing.Image imgInput = System.Drawing.Image.FromFile(InputSource);
Graphics gInput = Graphics.fromimage(imgInput);
Imaging.ImageFormat thisFormat = imgInput.rawformat;
private static readonly string[] _validExtensions = {"jpg","bmp","gif","png"}; // etc
public static bool IsImageExtension(string ext)
{
return _validExtensions.Contains(ext.ToLower());
}
If you want to be able to make the list configurable at runtime without recompiling, add something like:
private static string[] _validExtensions;
private static string[] ValidExtensions()
{
if(_validExtensions==null)
{
// load from app.config, text file, DB, wherever
}
return _validExtensions
}
public static bool IsImageExtension(string ext)
{
return ValidExtensions().Contains(ext.ToLower());
}
An option would be to have a list of all possible valid image extensions, then that method would only check if the supplied extension is within that collection:
private static readonly HashSet<string> validExtensions = new HashSet<string>()
{
"png",
"jpg",
"bmp"
// Other possible extensions
};
Then in the validation you just check against that:
public static bool IsImageExtension(string ext)
{
return validExtensions.Contains(ext);
}
This method automatically creates a filter for the OpenFileDialog. It uses the informations of the image decoders supported by Windows. It also adds information of "unknown" image formats (see default case of the switch statement).
private static string SupportedImageDecodersFilter()
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageDecoders();
string allExtensions = encoders
.Select(enc => enc.FilenameExtension)
.Aggregate((current, next) => current + ";" + next)
.ToLowerInvariant();
var sb = new StringBuilder(500)
.AppendFormat("Image files ({0})|{1}", allExtensions.Replace(";", ", "),
allExtensions);
foreach (ImageCodecInfo encoder in encoders) {
string ext = encoder.FilenameExtension.ToLowerInvariant();
// ext = "*.bmp;*.dib;*.rle" descr = BMP
// ext = "*.jpg;*.jpeg;*.jpe;*.jfif" descr = JPEG
// ext = "*.gif" descr = GIF
// ext = "*.tif;*.tiff" descr = TIFF
// ext = "*.png" descr = PNG
string caption;
switch (encoder.FormatDescription) {
case "BMP":
caption = "Windows Bitmap";
break;
case "JPEG":
caption = "JPEG file";
break;
case "GIF":
caption = "Graphics Interchange Format";
break;
case "TIFF":
caption = "Tagged Image File Format";
break;
case "PNG":
caption = "Portable Network Graphics";
break;
default:
caption = encoder.FormatDescription;
break;
}
sb.AppendFormat("|{0} ({1})|{2}", caption, ext.Replace(";", ", "), ext);
}
return sb.ToString();
}
Use it like this:
var dlg = new OpenFileDialog {
Filter = SupportedImageDecodersFilter(),
Multiselect = false,
Title = "Choose Image"
};
The code above (slightly modified) can be used to find available image file extensions. In order to test if a given file extension denotes an image, I would put the valid extension in a HashSet. HashSets have an
O(1) access time! Make sure to choose a case insensitive string comparer. Since the file extensions do not contain accented or non Latin letters, the culture can safely be ignored. Therefore I use an ordinal string comparison.
var imageExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
imageExtensions.Add(".png");
imageExtensions.Add(".bmp");
...
And test if a filename is an image:
string extension = Path.GetExtension(filename);
bool isImage = imageExtensions.Contains(extension);
I just had to do something similiar. Here is my solution:
private bool IsImage(string fileExtension)
{
return GetImageFileExtensions().Contains(fileExtension.ToLower()));
}
private static List<string> GetImageFileExtensions()
{
return ImageCodecInfo.GetImageEncoders()
.Select(c => c.FilenameExtension)
.SelectMany(e => e.Split(';'))
.Select(e => e.Replace("*", "").ToLower())
.ToList();
}
How do I load a setting from an external xml file located in the same folder as my program? Or should I be using an old school .ini file? It is only the MySQL server name and a location name that I need to pass to my App.
You should look at Application Settings and the ConfigurationManager. You could also use the Connection Strings section in the app.config.
How to: Add Application Configuration Files to C# Projects
MySQL Connection Strings
... For AppSettings ...
C# Code...
You will need reference System.Configuration
var value = ConfigurationManager.AppSettings["MySetting"];
App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="MySetting" value="My Value"/>
</appSettings>
</configuration>
... For Connection Strings ...
C# Code...
You will need reference System.Configuration
var value = ConfigurationManager.ConnectionStrings["MySqlConn"];
App.Config
<configuration>
<connectionStrings>
<add name ="MySqlConn"
connectionString="Server=myServerAddress;Database=myDataBase;
Uid=myUsername;Pwd=myPassword;"/>
</connectionStrings>
</configuration>
To Elaborate on Matthew W's answer, it sounds like you need to Add -> New Item -> Application Configuration File in your project. This will generate an app.config (which will compile to [executableName].exe.config).
Within the app.config, you'll have an area for ConnectionStrings. Put your connection information there and call it using ConfigurationManager.
You might want to go with the new, but in case you want to go with the INI, here's some source for a windows forms version:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
//After you've added this class code to your application, here's how you may want to use it:
//Dim objclsINI As New clsINI("c:\fName.ini")
//objclsINI.WriteINI("Settings", "ClockTime", "12:59")
//objclsINI.WriteINI("Settings", "ClockTime", "12:59", "c:\test.ini")
//Dim strData As String = objclsINI.ReadINI("Settings", "ClockTime", "(none)")
public class clsINI
{
[DllImport("kernel32.dll", EntryPoint = "GetPrivateProfileStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int GetPrivateProfileString(string lpApplicationName, string lpKeyName, string lpDefault, System.Text.StringBuilder lpReturnedString, int nSize, string lpFileName);
[DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int WritePrivateProfileString(string lpApplicationName, string lpKeyName, string lpString, string lpFileName);
[DllImport("kernel32.dll", EntryPoint = "WritePrivateProfileStringA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern int FlushPrivateProfileString(int lpApplicationName, int lpKeyName, int lpString, string lpFileName);
// API functions
string strFilename;
string strSection;
string strKey;
// Constructor, accepting a filename
public clsINI(string Filename)
{
strFilename = Filename;
}
// Overloaded Constructor Creating The Default FileName
public clsINI()
{
strFilename = Application.StartupPath + "\\" + Application.ProductName + ".ini";
}
// filename property
public string FileName {
get { return strFilename; }
set { strFilename = value; }
}
// Section property
public string Section {
get { return strSection; }
set { strSection = value; }
}
// Key property
public string Key {
get { return strKey; }
set { strKey = value; }
}
public string ReadINI(string Default)
{
string functionReturnValue = null;
// Returns a string from your INI file
int intCharCount = 0;
string strMessage = null;
System.Text.StringBuilder objResult = new System.Text.StringBuilder(256);
strMessage = "";
if (string.IsNullOrEmpty(strKey))
strMessage = "The INI File Class Does Not Have A Defined Key To Read.";
if (string.IsNullOrEmpty(strSection))
strMessage = strMessage + ControlChars.CrLf + "The INI File Class Does Not Have A Defined Section To Read.";
if (!string.IsNullOrEmpty(strMessage)) {
MessageBox.Show(strMessage, "INI Error");
return;
}
intCharCount = GetPrivateProfileString(strSection, strKey, Default, objResult, objResult.Capacity, strFilename);
if (intCharCount > 0)
functionReturnValue = Strings.Left(objResult.ToString(), intCharCount);
return functionReturnValue;
}
public string ReadINI(string Key, string Default)
{
string functionReturnValue = null;
// Returns a string from your INI file
int intCharCount = 0;
System.Text.StringBuilder objResult = new System.Text.StringBuilder(256);
if (string.IsNullOrEmpty(strSection)) {
MessageBox.Show("The INI File Class Does Not Have A Defined Section.", "INI Error");
return;
}
strKey = Key;
intCharCount = GetPrivateProfileString(strSection, Key, Default, objResult, objResult.Capacity, strFilename);
if (intCharCount > 0)
functionReturnValue = Strings.Left(objResult.ToString(), intCharCount);
return functionReturnValue;
}
public string ReadINI(string Section, string Key, string Default)
{
string functionReturnValue = null;
// Returns a string from your INI file
int intCharCount = 0;
System.Text.StringBuilder objResult = new System.Text.StringBuilder(256);
strSection = Section;
strKey = Key;
intCharCount = GetPrivateProfileString(Section, Key, Default, objResult, objResult.Capacity, strFilename);
if (intCharCount > 0)
functionReturnValue = Strings.Left(objResult.ToString(), intCharCount);
return functionReturnValue;
}
public string ReadINI(string Section, string Key, string Default, string sFileName)
{
string functionReturnValue = null;
// Returns a string from your INI file
int intCharCount = 0;
System.Text.StringBuilder objResult = new System.Text.StringBuilder(256);
strKey = Key;
strSection = Section;
strFilename = sFileName;
intCharCount = GetPrivateProfileString(Section, Key, Default, objResult, objResult.Capacity, sFileName);
if (intCharCount > 0)
functionReturnValue = Strings.Left(objResult.ToString(), intCharCount);
return functionReturnValue;
}
public void WriteINI(string Value)
{
// Writes a string to your INI file
string strMessage = null;
strMessage = "";
if (string.IsNullOrEmpty(strKey))
strMessage = "The INI File Class Does Not Have A Defined Key To Write.";
if (string.IsNullOrEmpty(strSection))
strMessage = strMessage + ControlChars.CrLf + "The INI File Class Does Not Have A Defined Section To Write.";
if (!string.IsNullOrEmpty(strMessage)) {
MessageBox.Show(strMessage, "INI Error");
return;
}
WritePrivateProfileString(strSection, strKey, Value, strFilename);
Flush();
}
public void WriteINI(string Key, string Value)
{
// Writes a string to your INI file
if (string.IsNullOrEmpty(strSection)) {
MessageBox.Show("The INI File Class Does Not Have A Defined Section To Write.", "INI Error");
return;
}
WritePrivateProfileString(strSection, Key, Value, strFilename);
Flush();
}
public void WriteINI(string Section, string Key, string Value)
{
// Writes a string to your INI file
strKey = Key;
strSection = Section;
WritePrivateProfileString(Section, Key, Value, strFilename);
Flush();
}
public void WriteINI(string Section, string Key, string Value, string sFileName)
{
strKey = Key;
strSection = Section;
strFilename = sFileName;
// Writes a string to your INI file
WritePrivateProfileString(Section, Key, Value, sFileName);
Flush();
}
private void Flush()
{
// Stores all the cached changes to your INI file
FlushPrivateProfileString(0, 0, 0, strFilename);
}
}
.NET has the notion of a settings file associated with an assembly.
If your assembly name is:
My.Program.exe
you can create a settings file for that assembly that is automatically available through the ConfigurationManager:
My.Program.exe.config
You can easily make this a part of your project by adding an App.config file:
http://msdn.microsoft.com/en-us/library/ms184658(VS.80).aspx