2013-11-03 23:53:49 +13:00
#region License Information ( GPL v3 )
/ *
ShareX - A program that allows you to take screenshots and share any file type
2022-01-12 05:32:17 +13:00
Copyright ( c ) 2007 - 2022 ShareX Team
2013-11-03 23:53:49 +13:00
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
Optionally you can also view the license at < http : //www.gnu.org/licenses/>.
* /
#endregion License Information ( GPL v3 )
2022-01-05 20:27:48 +13:00
using Microsoft.VisualBasic.FileIO ;
2016-02-15 19:53:30 +13:00
using Microsoft.Win32 ;
2019-01-10 05:08:55 +13:00
using Newtonsoft.Json.Linq ;
2016-02-15 19:53:30 +13:00
using ShareX.HelpersLib.Properties ;
2013-11-03 23:53:49 +13:00
using System ;
2014-08-11 03:36:08 +12:00
using System.Collections.Generic ;
2013-11-03 23:53:49 +13:00
using System.Diagnostics ;
using System.Drawing ;
2014-10-25 13:51:15 +13:00
using System.Globalization ;
2013-11-03 23:53:49 +13:00
using System.IO ;
using System.Linq ;
using System.Media ;
2014-06-21 00:05:04 +12:00
using System.Net ;
2014-06-07 06:01:02 +12:00
using System.Net.NetworkInformation ;
2014-08-11 03:36:08 +12:00
using System.Reflection ;
2014-10-18 08:00:10 +13:00
using System.Resources ;
2016-01-19 10:52:47 +13:00
using System.Runtime.InteropServices ;
2013-11-03 23:53:49 +13:00
using System.Runtime.Serialization ;
using System.Runtime.Serialization.Formatters.Binary ;
2017-03-20 12:53:32 +13:00
using System.Security.Cryptography ;
2018-04-30 06:23:20 +12:00
using System.Security.Permissions ;
2015-05-07 04:49:57 +12:00
using System.Security.Principal ;
2013-11-03 23:53:49 +13:00
using System.Text ;
using System.Text.RegularExpressions ;
using System.Threading ;
2018-08-03 23:01:12 +12:00
using System.Threading.Tasks ;
Fix issue #372
Several changes were made to fix the encoding of ftp dirpaths and allow
uploads to folders with non-ascii characters:
-Fixed encoding of valid urls in ShareX.HelpersLib.NameParser.cs
-Fixed subfolder path generation and wrong url re-encoding in
FTPAccount.cs
-Fixed preview paths in FTP Destination settings (FTPAccount.cs)
-Fixed subfolder path generation in FTP.cs
This fixes issue #372, which was reproduced with the following account
config on a local ftp server (import from clipboard on destination
settings):
{
"Protocol": "FTP",
"Name": "New account",
"Host": "localhost",
"Port": 21,
"Username": "test",
"Password": "test",
"ServerProtocol": "ftp",
"SubFolderPath": "DEV/grhh本人%",
"BrowserProtocol": "http",
"HttpHomePath": "",
"HttpHomePathAutoAddSubFolderPath": true,
"HttpHomePathNoExtension": false,
"IsActive": false,
"FTPSEncryption": "Explicit",
"FTPSCertificateLocation": "",
"Passphrase": null,
"Keypath": null
}
2015-01-02 10:44:18 +13:00
using System.Web ;
2015-01-09 21:19:44 +13:00
using System.Windows.Forms ;
2019-01-10 05:08:55 +13:00
using System.Xml ;
2013-11-03 23:53:49 +13:00
2014-12-11 09:25:20 +13:00
namespace ShareX.HelpersLib
2013-11-03 23:53:49 +13:00
{
public static class Helpers
{
public const string Numbers = "0123456789" ; // 48 ... 57
public const string AlphabetCapital = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; // 65 ... 90
public const string Alphabet = "abcdefghijklmnopqrstuvwxyz" ; // 97 ... 122
public const string Alphanumeric = Numbers + AlphabetCapital + Alphabet ;
2015-09-23 15:01:59 +12:00
public const string AlphanumericInverse = Numbers + Alphabet + AlphabetCapital ;
public const string Hexadecimal = Numbers + "ABCDEF" ;
2019-06-09 05:52:22 +12:00
public const string Base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" ; // https://en.wikipedia.org/wiki/Base58
public const string Base56 = "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz" ; // A variant, Base56, excludes 1 (one) and o (lowercase o) compared to Base 58.
2013-11-03 23:53:49 +13:00
2016-03-02 13:02:08 +13:00
public static readonly string [ ] ImageFileExtensions = new string [ ] { "jpg" , "jpeg" , "png" , "gif" , "bmp" , "ico" , "tif" , "tiff" } ;
2017-09-12 19:20:23 +12:00
public static readonly string [ ] TextFileExtensions = new string [ ] { "txt" , "log" , "nfo" , "c" , "cpp" , "cc" , "cxx" , "h" , "hpp" , "hxx" , "cs" , "vb" , "html" , "htm" , "xhtml" , "xht" , "xml" , "css" , "js" , "php" , "bat" , "java" , "lua" , "py" , "pl" , "cfg" , "ini" , "dart" , "go" , "gohtml" } ;
2016-09-11 09:36:01 +12:00
public static readonly string [ ] VideoFileExtensions = new string [ ] { "mp4" , "webm" , "mkv" , "avi" , "vob" , "ogv" , "ogg" , "mov" , "qt" , "wmv" , "m4p" , "m4v" , "mpg" , "mp2" , "mpeg" , "mpe" , "mpv" , "m2v" , "m4v" , "flv" , "f4v" } ;
2016-03-02 13:02:08 +13:00
2013-11-03 23:53:49 +13:00
public static readonly Version OSVersion = Environment . OSVersion . Version ;
2018-10-07 08:09:15 +13:00
private static Cursor [ ] cursorList ;
2018-06-22 04:25:11 +12:00
2018-04-30 06:23:20 +12:00
public static Cursor [ ] CursorList
{
get
{
2018-10-07 08:09:15 +13:00
if ( cursorList = = null )
2018-04-30 06:23:20 +12:00
{
2018-10-07 08:09:15 +13:00
cursorList = new Cursor [ ] {
2018-04-30 06:23:20 +12:00
Cursors . AppStarting , Cursors . Arrow , Cursors . Cross , Cursors . Default , Cursors . Hand , Cursors . Help ,
Cursors . HSplit , Cursors . IBeam , Cursors . No , Cursors . NoMove2D , Cursors . NoMoveHoriz , Cursors . NoMoveVert ,
Cursors . PanEast , Cursors . PanNE , Cursors . PanNorth , Cursors . PanNW , Cursors . PanSE , Cursors . PanSouth ,
Cursors . PanSW , Cursors . PanWest , Cursors . SizeAll , Cursors . SizeNESW , Cursors . SizeNS , Cursors . SizeNWSE ,
Cursors . SizeWE , Cursors . UpArrow , Cursors . VSplit , Cursors . WaitCursor
} ;
}
2018-10-07 08:09:15 +13:00
return cursorList ;
2018-04-30 06:23:20 +12:00
}
}
2017-08-13 23:07:52 +12:00
2021-12-12 10:21:19 +13:00
public static string GetFileNameExtension ( string filePath , bool includeDot = false , bool checkSecondExtension = true )
2013-11-03 23:53:49 +13:00
{
2019-03-04 04:35:39 +13:00
string extension = "" ;
2014-08-28 12:53:38 +12:00
if ( ! string . IsNullOrEmpty ( filePath ) )
2013-11-03 23:53:49 +13:00
{
int pos = filePath . LastIndexOf ( '.' ) ;
2014-08-28 12:53:38 +12:00
if ( pos > = 0 )
2013-11-03 23:53:49 +13:00
{
2019-03-04 04:35:39 +13:00
extension = filePath . Substring ( pos + 1 ) ;
if ( checkSecondExtension )
{
filePath = filePath . Remove ( pos ) ;
2021-12-12 10:21:19 +13:00
string extension2 = GetFileNameExtension ( filePath , false , false ) ;
2019-03-04 04:35:39 +13:00
if ( ! string . IsNullOrEmpty ( extension2 ) )
{
foreach ( string knownExtension in new string [ ] { "tar" } )
{
if ( extension2 . Equals ( knownExtension , StringComparison . OrdinalIgnoreCase ) )
{
extension = extension2 + "." + extension ;
break ;
}
}
}
}
if ( includeDot )
{
extension = "." + extension ;
}
2013-11-03 23:53:49 +13:00
}
}
2019-03-04 04:35:39 +13:00
return extension ;
2014-08-28 12:53:38 +12:00
}
2021-12-12 10:21:19 +13:00
public static string GetFileNameSafe ( string filePath )
2016-03-12 11:34:56 +13:00
{
if ( ! string . IsNullOrEmpty ( filePath ) )
{
int pos = filePath . LastIndexOf ( '\\' ) ;
if ( pos < 0 )
{
pos = filePath . LastIndexOf ( '/' ) ;
}
if ( pos > = 0 )
{
return filePath . Substring ( pos + 1 ) ;
}
}
return filePath ;
}
2021-12-12 10:21:19 +13:00
public static string ChangeFileNameExtension ( string fileName , string extension )
2014-08-28 12:53:38 +12:00
{
2020-08-30 13:30:41 +12:00
if ( ! string . IsNullOrEmpty ( fileName ) )
2014-08-28 12:53:38 +12:00
{
2020-08-30 13:30:41 +12:00
int pos = fileName . LastIndexOf ( '.' ) ;
2014-08-28 12:53:38 +12:00
if ( pos > = 0 )
{
2020-08-30 13:30:41 +12:00
fileName = fileName . Remove ( pos ) ;
}
2014-08-28 12:53:38 +12:00
2020-08-30 13:30:41 +12:00
if ( ! string . IsNullOrEmpty ( extension ) )
{
2014-08-28 12:53:38 +12:00
pos = extension . LastIndexOf ( '.' ) ;
if ( pos > = 0 )
{
extension = extension . Substring ( pos + 1 ) ;
}
2020-08-30 13:30:41 +12:00
return fileName + "." + extension ;
2014-08-28 12:53:38 +12:00
}
}
2020-08-30 13:30:41 +12:00
return fileName ;
2013-11-03 23:53:49 +13:00
}
2015-10-23 11:43:04 +13:00
public static string AppendExtension ( string filePath , string extension )
{
return filePath . TrimEnd ( '.' ) + '.' + extension . TrimStart ( '.' ) ;
}
2016-09-11 09:36:01 +12:00
public static bool CheckExtension ( string filePath , IEnumerable < string > extensions )
2013-11-03 23:53:49 +13:00
{
2021-12-12 10:21:19 +13:00
string ext = GetFileNameExtension ( filePath ) ;
2013-11-03 23:53:49 +13:00
if ( ! string . IsNullOrEmpty ( ext ) )
{
2019-03-04 05:21:05 +13:00
return extensions . Any ( x = > ext . Equals ( x , StringComparison . OrdinalIgnoreCase ) ) ;
2013-11-03 23:53:49 +13:00
}
return false ;
}
public static bool IsImageFile ( string filePath )
{
2016-09-11 09:36:01 +12:00
return CheckExtension ( filePath , ImageFileExtensions ) ;
2013-11-03 23:53:49 +13:00
}
public static bool IsTextFile ( string filePath )
{
2016-09-11 09:36:01 +12:00
return CheckExtension ( filePath , TextFileExtensions ) ;
}
public static bool IsVideoFile ( string filePath )
{
return CheckExtension ( filePath , VideoFileExtensions ) ;
2013-11-03 23:53:49 +13:00
}
public static EDataType FindDataType ( string filePath )
{
if ( IsImageFile ( filePath ) )
{
return EDataType . Image ;
}
if ( IsTextFile ( filePath ) )
{
return EDataType . Text ;
}
return EDataType . File ;
}
2015-09-23 15:01:59 +12:00
public static string AddZeroes ( string input , int digits = 2 )
{
return input . PadLeft ( digits , '0' ) ;
}
2013-11-03 23:53:49 +13:00
public static string AddZeroes ( int number , int digits = 2 )
{
2015-09-23 15:01:59 +12:00
return AddZeroes ( number . ToString ( ) , digits ) ;
2013-11-03 23:53:49 +13:00
}
public static string HourTo12 ( int hour )
{
if ( hour = = 0 )
{
return 12. ToString ( ) ;
}
if ( hour > 12 )
{
return AddZeroes ( hour - 12 ) ;
}
return AddZeroes ( hour ) ;
}
public static char GetRandomChar ( string chars )
{
2020-04-24 01:41:09 +12:00
return chars [ RandomCrypto . Next ( chars . Length - 1 ) ] ;
2013-11-03 23:53:49 +13:00
}
public static string GetRandomString ( string chars , int length )
{
StringBuilder sb = new StringBuilder ( ) ;
while ( length - - > 0 )
{
sb . Append ( GetRandomChar ( chars ) ) ;
}
return sb . ToString ( ) ;
}
public static string GetRandomNumber ( int length )
{
return GetRandomString ( Numbers , length ) ;
}
public static string GetRandomAlphanumeric ( int length )
{
return GetRandomString ( Alphanumeric , length ) ;
}
public static string GetRandomKey ( int length = 5 , int count = 3 , char separator = '-' )
{
2018-05-17 01:27:11 +12:00
return Enumerable . Range ( 1 , ( ( length + 1 ) * count ) - 1 ) . Aggregate ( "" , ( x , index ) = > x + = index % ( length + 1 ) = = 0 ? separator : GetRandomChar ( Alphanumeric ) ) ;
2013-11-03 23:53:49 +13:00
}
public static string GetAllCharacters ( )
{
return Encoding . UTF8 . GetString ( Enumerable . Range ( 1 , 255 ) . Select ( i = > ( byte ) i ) . ToArray ( ) ) ;
}
2018-01-31 10:35:17 +13:00
public static string GetRandomLine ( string text )
{
2018-02-02 06:04:24 +13:00
string [ ] lines = text . Trim ( ) . Lines ( ) ;
2020-04-24 01:41:09 +12:00
2018-01-31 10:35:17 +13:00
if ( lines ! = null & & lines . Length > 0 )
{
2020-04-24 01:41:09 +12:00
return RandomCrypto . Pick ( lines ) ;
2018-01-31 10:35:17 +13:00
}
2020-04-24 01:41:09 +12:00
2018-01-31 10:35:17 +13:00
return null ;
}
2018-02-02 06:04:24 +13:00
public static string GetRandomLineFromFile ( string path )
2018-02-01 11:20:44 +13:00
{
2019-10-22 00:18:23 +13:00
string text = File . ReadAllText ( path , Encoding . UTF8 ) ;
2018-02-02 06:04:24 +13:00
return GetRandomLine ( text ) ;
2018-02-01 11:20:44 +13:00
}
2016-01-30 23:10:19 +13:00
public static string GetValidFileName ( string fileName , string separator = "" )
2013-11-03 23:53:49 +13:00
{
char [ ] invalidFileNameChars = Path . GetInvalidFileNameChars ( ) ;
2019-10-10 09:03:36 +13:00
2016-01-30 23:10:19 +13:00
if ( string . IsNullOrEmpty ( separator ) )
{
return new string ( fileName . Where ( c = > ! invalidFileNameChars . Contains ( c ) ) . ToArray ( ) ) ;
}
else
{
2019-10-10 09:03:36 +13:00
foreach ( char invalidFileNameChar in invalidFileNameChars )
{
fileName = fileName . Replace ( invalidFileNameChar . ToString ( ) , separator ) ;
}
2016-01-31 19:57:53 +13:00
return fileName . Trim ( ) . Replace ( separator + separator , separator ) ;
2016-01-30 23:10:19 +13:00
}
2013-11-03 23:53:49 +13:00
}
public static string GetValidFolderPath ( string folderPath )
{
char [ ] invalidPathChars = Path . GetInvalidPathChars ( ) ;
return new string ( folderPath . Where ( c = > ! invalidPathChars . Contains ( c ) ) . ToArray ( ) ) ;
}
public static string GetValidFilePath ( string filePath )
{
string folderPath = Path . GetDirectoryName ( filePath ) ;
string fileName = Path . GetFileName ( filePath ) ;
return GetValidFolderPath ( folderPath ) + Path . DirectorySeparatorChar + GetValidFileName ( fileName ) ;
}
2014-04-20 11:00:19 +12:00
public static string GetValidURL ( string url , bool replaceSpace = false )
2013-11-03 23:53:49 +13:00
{
if ( replaceSpace ) url = url . Replace ( ' ' , '_' ) ;
Fix issue #372
Several changes were made to fix the encoding of ftp dirpaths and allow
uploads to folders with non-ascii characters:
-Fixed encoding of valid urls in ShareX.HelpersLib.NameParser.cs
-Fixed subfolder path generation and wrong url re-encoding in
FTPAccount.cs
-Fixed preview paths in FTP Destination settings (FTPAccount.cs)
-Fixed subfolder path generation in FTP.cs
This fixes issue #372, which was reproduced with the following account
config on a local ftp server (import from clipboard on destination
settings):
{
"Protocol": "FTP",
"Name": "New account",
"Host": "localhost",
"Port": 21,
"Username": "test",
"Password": "test",
"ServerProtocol": "ftp",
"SubFolderPath": "DEV/grhh本人%",
"BrowserProtocol": "http",
"HttpHomePath": "",
"HttpHomePathAutoAddSubFolderPath": true,
"HttpHomePathNoExtension": false,
"IsActive": false,
"FTPSEncryption": "Explicit",
"FTPSCertificateLocation": "",
"Passphrase": null,
"Keypath": null
}
2015-01-02 10:44:18 +13:00
return HttpUtility . UrlPathEncode ( url ) ;
2013-11-03 23:53:49 +13:00
}
public static string GetXMLValue ( string input , string tag )
{
2016-05-20 23:43:13 +12:00
return Regex . Match ( input , string . Format ( "(?<={0}>).+?(?=</{0})" , tag ) ) . Value ;
2013-11-03 23:53:49 +13:00
}
2014-07-08 04:46:55 +12:00
public static T [ ] GetEnums < T > ( )
{
2014-07-08 10:58:59 +12:00
return ( T [ ] ) Enum . GetValues ( typeof ( T ) ) ;
2014-07-08 04:46:55 +12:00
}
2018-12-01 00:03:45 +13:00
public static string [ ] GetEnumDescriptions < T > ( int skip = 0 )
2013-11-03 23:53:49 +13:00
{
2018-12-01 00:03:45 +13:00
return Enum . GetValues ( typeof ( T ) ) . OfType < Enum > ( ) . Skip ( skip ) . Select ( x = > x . GetDescription ( ) ) . ToArray ( ) ;
2013-11-03 23:53:49 +13:00
}
2014-10-25 13:04:41 +13:00
/ * public static string [ ] GetLocalizedEnumDescriptions < T > ( )
2014-10-18 08:00:10 +13:00
{
2014-10-19 09:29:23 +13:00
Assembly assembly = typeof ( T ) . Assembly ;
2014-10-18 08:00:10 +13:00
string resourcePath = assembly . GetName ( ) . Name + ".Properties.Resources" ;
ResourceManager resourceManager = new ResourceManager ( resourcePath , assembly ) ;
return GetLocalizedEnumDescriptions < T > ( resourceManager ) ;
2014-10-25 13:04:41 +13:00
} * /
2014-10-18 08:00:10 +13:00
2014-10-25 13:18:57 +13:00
public static string [ ] GetLocalizedEnumDescriptions < T > ( )
{
return GetLocalizedEnumDescriptions < T > ( Resources . ResourceManager ) ;
}
2014-10-19 09:29:23 +13:00
public static string [ ] GetLocalizedEnumDescriptions < T > ( ResourceManager resourceManager )
2014-10-18 08:00:10 +13:00
{
2014-10-19 09:29:23 +13:00
return Enum . GetValues ( typeof ( T ) ) . OfType < Enum > ( ) . Select ( x = > x . GetLocalizedDescription ( resourceManager ) ) . ToArray ( ) ;
2014-10-18 08:00:10 +13:00
}
2013-11-03 23:53:49 +13:00
public static int GetEnumLength < T > ( )
{
return Enum . GetValues ( typeof ( T ) ) . Length ;
}
2013-11-16 22:50:08 +13:00
public static T GetEnumFromIndex < T > ( int i )
{
2014-07-08 10:58:59 +12:00
return GetEnums < T > ( ) [ i ] ;
2013-11-16 22:50:08 +13:00
}
2013-11-20 01:10:06 +13:00
public static string [ ] GetEnumNamesProper < T > ( )
{
string [ ] names = Enum . GetNames ( typeof ( T ) ) ;
string [ ] newNames = new string [ names . Length ] ;
for ( int i = 0 ; i < names . Length ; i + + )
{
2013-11-21 01:39:33 +13:00
newNames [ i ] = GetProperName ( names [ i ] ) ;
}
return newNames ;
}
2014-10-19 09:29:23 +13:00
// returns a list of public static fields of the class type (similar to enum values)
2014-08-11 03:36:08 +12:00
public static T [ ] GetValueFields < T > ( )
{
2016-09-17 19:07:02 +12:00
List < T > res = new List < T > ( ) ;
2014-08-28 12:53:38 +12:00
foreach ( FieldInfo fi in typeof ( T ) . GetFields ( BindingFlags . Static | BindingFlags . Public ) )
{
2014-08-11 03:36:08 +12:00
if ( fi . FieldType ! = typeof ( T ) ) continue ;
res . Add ( ( T ) fi . GetValue ( null ) ) ;
}
return res . ToArray ( ) ;
}
2013-11-21 01:39:33 +13:00
// Example: "TopLeft" becomes "Top left"
2021-02-15 20:31:26 +13:00
// Example2: "Rotate180" becomes "Rotate 180"
public static string GetProperName ( string name , bool keepCase = false )
2013-11-21 01:39:33 +13:00
{
StringBuilder sb = new StringBuilder ( ) ;
2021-02-15 20:31:26 +13:00
bool number = false ;
2013-11-21 01:39:33 +13:00
for ( int i = 0 ; i < name . Length ; i + + )
{
char c = name [ i ] ;
2013-11-20 01:10:06 +13:00
2021-02-15 20:31:26 +13:00
if ( i > 0 & & ( char . IsUpper ( c ) | | ( ! number & & char . IsNumber ( c ) ) ) )
2013-11-20 01:10:06 +13:00
{
2013-11-21 01:39:33 +13:00
sb . Append ( ' ' ) ;
2021-02-15 20:31:26 +13:00
if ( keepCase )
{
sb . Append ( c ) ;
}
else
{
sb . Append ( char . ToLowerInvariant ( c ) ) ;
}
2013-11-21 01:39:33 +13:00
}
else
{
sb . Append ( c ) ;
2013-11-20 01:10:06 +13:00
}
2021-02-15 20:31:26 +13:00
number = char . IsNumber ( c ) ;
2013-11-20 01:10:06 +13:00
}
2013-11-21 01:39:33 +13:00
return sb . ToString ( ) ;
2013-11-20 01:10:06 +13:00
}
2016-03-25 08:27:51 +13:00
public static bool OpenFile ( string filePath )
2013-11-03 23:53:49 +13:00
{
2016-03-25 08:03:10 +13:00
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
2013-11-03 23:53:49 +13:00
{
2016-03-25 08:27:51 +13:00
try
2013-12-12 07:36:23 +13:00
{
2018-12-07 07:51:41 +13:00
using ( Process process = new Process ( ) )
{
ProcessStartInfo psi = new ProcessStartInfo ( )
{
FileName = filePath
} ;
process . StartInfo = psi ;
process . Start ( ) ;
}
DebugHelper . WriteLine ( "File opened: " + filePath ) ;
2016-03-25 08:27:51 +13:00
return true ;
}
catch ( Exception e )
{
DebugHelper . WriteException ( e , $"OpenFile({filePath}) failed." ) ;
}
2016-03-25 08:03:10 +13:00
}
else
{
MessageBox . Show ( Resources . Helpers_OpenFile_File_not_exist_ + Environment . NewLine + filePath , "ShareX" , MessageBoxButtons . OK , MessageBoxIcon . Information ) ;
}
2016-03-25 08:27:51 +13:00
return false ;
2016-03-25 08:03:10 +13:00
}
2016-03-25 08:27:51 +13:00
public static bool OpenFolder ( string folderPath )
2016-03-25 08:03:10 +13:00
{
if ( ! string . IsNullOrEmpty ( folderPath ) & & Directory . Exists ( folderPath ) )
{
2016-09-30 22:24:08 +13:00
if ( ! folderPath . EndsWith ( @"\" ) )
{
folderPath + = @"\" ;
}
2016-03-25 08:27:51 +13:00
try
{
2018-12-07 07:51:41 +13:00
using ( Process process = new Process ( ) )
{
ProcessStartInfo psi = new ProcessStartInfo ( )
{
FileName = folderPath
} ;
process . StartInfo = psi ;
process . Start ( ) ;
}
DebugHelper . WriteLine ( "Folder opened: " + folderPath ) ;
2016-03-25 08:27:51 +13:00
return true ;
}
catch ( Exception e )
{
DebugHelper . WriteException ( e , $"OpenFolder({folderPath}) failed." ) ;
}
2016-03-25 08:03:10 +13:00
}
else
{
MessageBox . Show ( Resources . Helpers_OpenFolder_Folder_not_exist_ + Environment . NewLine + folderPath , "ShareX" , MessageBoxButtons . OK , MessageBoxIcon . Information ) ;
2013-11-03 23:53:49 +13:00
}
2016-03-25 08:27:51 +13:00
return false ;
2013-11-03 23:53:49 +13:00
}
2016-03-25 08:27:51 +13:00
public static bool OpenFolderWithFile ( string filePath )
2013-11-03 23:53:49 +13:00
{
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
{
2016-03-25 08:27:51 +13:00
try
{
2016-06-29 08:10:53 +12:00
NativeMethods . OpenFolderAndSelectFile ( filePath ) ;
2018-12-07 07:51:41 +13:00
DebugHelper . WriteLine ( "Folder opened with file: " + filePath ) ;
2016-03-25 08:27:51 +13:00
return true ;
}
catch ( Exception e )
{
DebugHelper . WriteException ( e , $"OpenFolderWithFile({filePath}) failed." ) ;
}
2016-03-25 08:03:10 +13:00
}
else
{
MessageBox . Show ( Resources . Helpers_OpenFile_File_not_exist_ + Environment . NewLine + filePath , "ShareX" , MessageBoxButtons . OK , MessageBoxIcon . Information ) ;
2013-11-03 23:53:49 +13:00
}
2016-03-25 08:27:51 +13:00
return false ;
2013-11-03 23:53:49 +13:00
}
2014-07-04 01:48:35 +12:00
/// <summary>
/// If version1 newer than version2 = 1
/// If version1 equal to version2 = 0
/// If version1 older than version2 = -1
/// </summary>
public static int CompareVersion ( string version1 , string version2 )
{
return NormalizeVersion ( version1 ) . CompareTo ( NormalizeVersion ( version2 ) ) ;
}
2014-07-23 12:18:49 +12:00
/// <summary>
/// If version1 newer than version2 = 1
/// If version1 equal to version2 = 0
/// If version1 older than version2 = -1
/// </summary>
public static int CompareVersion ( Version version1 , Version version2 )
{
return version1 . Normalize ( ) . CompareTo ( version2 . Normalize ( ) ) ;
}
2014-07-04 01:48:35 +12:00
/// <summary>
/// If version newer than ApplicationVersion = 1
/// If version equal to ApplicationVersion = 0
/// If version older than ApplicationVersion = -1
/// </summary>
public static int CompareApplicationVersion ( string version )
{
return CompareVersion ( version , Application . ProductVersion ) ;
}
2014-07-06 05:46:37 +12:00
private static Version NormalizeVersion ( string version )
{
return Version . Parse ( version ) . Normalize ( ) ;
}
2013-11-03 23:53:49 +13:00
public static bool IsWindowsXP ( )
{
return OSVersion . Major = = 5 & & OSVersion . Minor = = 1 ;
}
public static bool IsWindowsXPOrGreater ( )
{
return ( OSVersion . Major = = 5 & & OSVersion . Minor > = 1 ) | | OSVersion . Major > 5 ;
}
public static bool IsWindowsVista ( )
{
return OSVersion . Major = = 6 ;
}
public static bool IsWindowsVistaOrGreater ( )
{
return OSVersion . Major > = 6 ;
}
public static bool IsWindows7 ( )
{
return OSVersion . Major = = 6 & & OSVersion . Minor = = 1 ;
}
public static bool IsWindows7OrGreater ( )
{
return ( OSVersion . Major = = 6 & & OSVersion . Minor > = 1 ) | | OSVersion . Major > 6 ;
}
public static bool IsWindows8 ( )
{
return OSVersion . Major = = 6 & & OSVersion . Minor = = 2 ;
}
public static bool IsWindows8OrGreater ( )
{
return ( OSVersion . Major = = 6 & & OSVersion . Minor > = 2 ) | | OSVersion . Major > 6 ;
}
2019-05-23 22:59:20 +12:00
public static bool IsWindows10OrGreater ( int build = - 1 )
2015-07-21 10:44:03 +12:00
{
2019-05-23 22:59:20 +12:00
return OSVersion . Major > = 10 & & OSVersion . Build > = build ;
2019-05-23 05:04:53 +12:00
}
2014-04-09 23:07:33 +12:00
public static bool IsDefaultInstallDir ( )
{
2014-04-10 00:21:18 +12:00
string path = Environment . GetFolderPath ( Environment . SpecialFolder . ProgramFiles ) ;
return Application . ExecutablePath . StartsWith ( path ) ;
2014-04-09 23:07:33 +12:00
}
2014-03-23 12:15:13 +13:00
public static bool IsValidIPAddress ( string ip )
{
if ( string . IsNullOrEmpty ( ip ) ) return false ;
string pattern = @"(?<First>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Second>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Third>2[0-4]\d|25[0-5]|[01]?\d\d?)\.(?<Fourth>2[0-4]\d|25[0-5]|[01]?\d\d?)" ;
return Regex . IsMatch ( ip . Trim ( ) , pattern ) ;
}
2019-11-27 03:17:43 +13:00
public static string GetUniqueFilePath ( string filePath )
2013-11-03 23:53:49 +13:00
{
2019-11-27 03:17:43 +13:00
if ( File . Exists ( filePath ) )
2013-11-03 23:53:49 +13:00
{
2019-11-27 03:17:43 +13:00
string folderPath = Path . GetDirectoryName ( filePath ) ;
string fileName = Path . GetFileNameWithoutExtension ( filePath ) ;
string fileExtension = Path . GetExtension ( filePath ) ;
2014-03-13 22:13:02 +13:00
int number = 1 ;
2013-11-03 23:53:49 +13:00
2019-11-27 03:17:43 +13:00
Match regex = Regex . Match ( fileName , @"^(.+) \((\d+)\)$" ) ;
2013-11-03 23:53:49 +13:00
2014-03-13 22:13:02 +13:00
if ( regex . Success )
2013-11-03 23:53:49 +13:00
{
2019-11-27 03:17:43 +13:00
fileName = regex . Groups [ 1 ] . Value ;
2014-03-13 22:13:02 +13:00
number = int . Parse ( regex . Groups [ 2 ] . Value ) ;
2013-11-03 23:53:49 +13:00
}
do
{
2014-03-13 22:13:02 +13:00
number + + ;
2019-11-27 03:17:43 +13:00
string newFileName = $"{fileName} ({number}){fileExtension}" ;
filePath = Path . Combine ( folderPath , newFileName ) ;
2013-11-03 23:53:49 +13:00
}
2019-11-27 03:17:43 +13:00
while ( File . Exists ( filePath ) ) ;
2013-11-03 23:53:49 +13:00
}
2019-11-27 03:17:43 +13:00
return filePath ;
2013-11-03 23:53:49 +13:00
}
public static string ProperTimeSpan ( TimeSpan ts )
{
string time = string . Format ( "{0:00}:{1:00}" , ts . Minutes , ts . Seconds ) ;
int hours = ( int ) ts . TotalHours ;
if ( hours > 0 ) time = hours + ":" + time ;
return time ;
}
public static object Clone ( object obj )
{
using ( MemoryStream ms = new MemoryStream ( ) )
{
BinaryFormatter binaryFormatter = new BinaryFormatter ( null , new StreamingContext ( StreamingContextStates . Clone ) ) ;
binaryFormatter . Serialize ( ms , obj ) ;
ms . Seek ( 0 , SeekOrigin . Begin ) ;
return binaryFormatter . Deserialize ( ms ) ;
}
}
public static void PlaySoundAsync ( Stream stream )
{
2015-08-16 20:34:46 +12:00
if ( stream ! = null )
2013-11-03 23:53:49 +13:00
{
2018-08-03 23:01:12 +12:00
Task . Run ( ( ) = >
2013-11-03 23:53:49 +13:00
{
2015-08-16 20:34:46 +12:00
using ( stream )
using ( SoundPlayer soundPlayer = new SoundPlayer ( stream ) )
{
soundPlayer . PlaySync ( ) ;
}
} ) ;
}
}
2022-01-05 20:44:18 +13:00
public static void PlaySoundAsync ( string filePath )
2015-08-16 20:34:46 +12:00
{
2022-01-05 20:44:18 +13:00
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
2015-08-16 20:34:46 +12:00
{
2018-08-03 23:01:12 +12:00
Task . Run ( ( ) = >
2015-08-16 20:34:46 +12:00
{
2022-01-05 20:44:18 +13:00
using ( SoundPlayer soundPlayer = new SoundPlayer ( filePath ) )
2015-08-16 20:34:46 +12:00
{
soundPlayer . PlaySync ( ) ;
}
} ) ;
}
2013-11-03 23:53:49 +13:00
}
2016-03-27 12:31:22 +13:00
public static bool BrowseFile ( TextBox tb , string initialDirectory = "" , bool detectSpecialFolders = false )
{
return BrowseFile ( "ShareX - " + Resources . Helpers_BrowseFile_Choose_file , tb , initialDirectory , detectSpecialFolders ) ;
}
2016-02-13 11:51:56 +13:00
public static bool BrowseFile ( string title , TextBox tb , string initialDirectory = "" , bool detectSpecialFolders = false )
2013-11-03 23:53:49 +13:00
{
using ( OpenFileDialog ofd = new OpenFileDialog ( ) )
{
ofd . Title = title ;
try
{
string path = tb . Text ;
2019-10-10 09:03:36 +13:00
if ( detectSpecialFolders )
{
path = ExpandFolderVariables ( path ) ;
}
2013-11-03 23:53:49 +13:00
if ( ! string . IsNullOrEmpty ( path ) )
{
path = Path . GetDirectoryName ( path ) ;
if ( Directory . Exists ( path ) )
{
ofd . InitialDirectory = path ;
}
}
}
finally
{
if ( string . IsNullOrEmpty ( ofd . InitialDirectory ) & & ! string . IsNullOrEmpty ( initialDirectory ) )
{
ofd . InitialDirectory = initialDirectory ;
}
}
if ( ofd . ShowDialog ( ) = = DialogResult . OK )
{
2019-10-10 09:03:36 +13:00
string fileName = ofd . FileName ;
if ( detectSpecialFolders )
{
fileName = GetVariableFolderPath ( fileName ) ;
}
tb . Text = fileName ;
2013-11-03 23:53:49 +13:00
return true ;
}
}
return false ;
}
2016-03-27 12:31:22 +13:00
public static bool BrowseFolder ( TextBox tb , string initialDirectory = "" , bool detectSpecialFolders = false )
{
return BrowseFolder ( "ShareX - " + Resources . Helpers_BrowseFolder_Choose_folder , tb , initialDirectory , detectSpecialFolders ) ;
}
2016-02-03 01:58:34 +13:00
public static bool BrowseFolder ( string title , TextBox tb , string initialDirectory = "" , bool detectSpecialFolders = false )
2013-11-03 23:53:49 +13:00
{
using ( FolderSelectDialog fsd = new FolderSelectDialog ( ) )
{
fsd . Title = title ;
string path = tb . Text ;
if ( ! string . IsNullOrEmpty ( path ) & & Directory . Exists ( path ) )
{
fsd . InitialDirectory = path ;
}
else if ( ! string . IsNullOrEmpty ( initialDirectory ) )
{
fsd . InitialDirectory = initialDirectory ;
}
if ( fsd . ShowDialog ( ) )
{
2016-01-17 01:15:27 +13:00
tb . Text = detectSpecialFolders ? GetVariableFolderPath ( fsd . FileName ) : fsd . FileName ;
2013-11-03 23:53:49 +13:00
return true ;
}
}
return false ;
}
2020-07-06 11:23:59 +12:00
public static string GetVariableFolderPath ( string path , bool supportCustomSpecialFolders = false )
2016-01-16 17:42:42 +13:00
{
2016-02-13 11:51:56 +13:00
if ( ! string . IsNullOrEmpty ( path ) )
2016-01-17 01:15:27 +13:00
{
2016-01-17 19:58:56 +13:00
try
{
2020-07-06 11:23:59 +12:00
if ( supportCustomSpecialFolders )
{
foreach ( KeyValuePair < string , string > specialFolder in HelpersOptions . ShareXSpecialFolders )
{
path = path . Replace ( specialFolder . Value , $"%{specialFolder.Key}%" , StringComparison . OrdinalIgnoreCase ) ;
}
}
2019-10-10 09:03:36 +13:00
foreach ( Environment . SpecialFolder specialFolder in GetEnums < Environment . SpecialFolder > ( ) )
{
path = path . Replace ( Environment . GetFolderPath ( specialFolder ) , $"%{specialFolder}%" , StringComparison . OrdinalIgnoreCase ) ;
}
2016-01-17 19:58:56 +13:00
}
catch ( Exception e )
{
DebugHelper . WriteException ( e ) ;
}
2016-01-17 01:15:27 +13:00
}
2016-01-16 17:42:42 +13:00
2016-02-13 11:51:56 +13:00
return path ;
2016-01-16 17:42:42 +13:00
}
2020-07-06 11:23:59 +12:00
public static string ExpandFolderVariables ( string path , bool supportCustomSpecialFolders = false )
2016-01-16 17:42:42 +13:00
{
2016-02-13 11:51:56 +13:00
if ( ! string . IsNullOrEmpty ( path ) )
2016-01-17 01:15:27 +13:00
{
2016-01-17 19:58:56 +13:00
try
{
2020-07-06 11:23:59 +12:00
if ( supportCustomSpecialFolders )
{
foreach ( KeyValuePair < string , string > specialFolder in HelpersOptions . ShareXSpecialFolders )
{
path = path . Replace ( $"%{specialFolder.Key}%" , specialFolder . Value , StringComparison . OrdinalIgnoreCase ) ;
}
}
2019-10-10 09:03:36 +13:00
foreach ( Environment . SpecialFolder specialFolder in GetEnums < Environment . SpecialFolder > ( ) )
{
path = path . Replace ( $"%{specialFolder}%" , Environment . GetFolderPath ( specialFolder ) , StringComparison . OrdinalIgnoreCase ) ;
}
2016-02-13 11:51:56 +13:00
path = Environment . ExpandEnvironmentVariables ( path ) ;
2016-01-17 19:58:56 +13:00
}
catch ( Exception e )
{
DebugHelper . WriteException ( e ) ;
}
2016-01-17 01:15:27 +13:00
}
2016-01-16 17:42:42 +13:00
2016-02-15 19:53:30 +13:00
return path ;
2016-01-16 17:42:42 +13:00
}
2019-10-10 09:03:36 +13:00
public static string OutputSpecialFolders ( )
{
StringBuilder sb = new StringBuilder ( ) ;
foreach ( Environment . SpecialFolder specialFolder in GetEnums < Environment . SpecialFolder > ( ) )
{
sb . AppendLine ( string . Format ( "{0,-25}{1}" , specialFolder , Environment . GetFolderPath ( specialFolder ) ) ) ;
}
return sb . ToString ( ) ;
}
2013-11-03 23:53:49 +13:00
public static bool WaitWhile ( Func < bool > check , int interval , int timeout = - 1 )
{
Stopwatch timer = Stopwatch . StartNew ( ) ;
while ( check ( ) )
{
if ( timeout > = 0 & & timer . ElapsedMilliseconds > = timeout )
{
return false ;
}
Thread . Sleep ( interval ) ;
}
return true ;
}
2018-08-04 01:38:18 +12:00
public static async Task WaitWhileAsync ( Func < bool > check , int interval , int timeout , Action onSuccess , int waitStart = 0 )
2013-11-03 23:53:49 +13:00
{
2014-05-22 13:48:27 +12:00
bool result = false ;
2018-08-04 01:38:18 +12:00
await Task . Run ( ( ) = >
2013-11-03 23:53:49 +13:00
{
if ( waitStart > 0 )
{
Thread . Sleep ( waitStart ) ;
}
2014-05-22 13:48:27 +12:00
result = WaitWhile ( check , interval , timeout ) ;
2018-08-04 01:38:18 +12:00
} ) ;
if ( result ) onSuccess ( ) ;
2013-11-03 23:53:49 +13:00
}
2020-08-30 13:07:45 +12:00
public static bool IsFileLocked ( string filePath )
2013-11-03 23:53:49 +13:00
{
try
{
2020-08-30 13:07:45 +12:00
using ( FileStream fs = new FileStream ( filePath , FileMode . Open , FileAccess . Read , FileShare . None ) )
2013-11-03 23:53:49 +13:00
{
2020-08-30 13:07:45 +12:00
fs . Close ( ) ;
2013-11-03 23:53:49 +13:00
}
}
catch ( IOException )
{
return true ;
}
return false ;
}
2020-08-30 13:07:45 +12:00
public static long GetFileSize ( string filePath )
2017-10-08 13:49:55 +13:00
{
try
{
2020-08-30 13:07:45 +12:00
return new FileInfo ( filePath ) . Length ;
2017-10-08 13:49:55 +13:00
}
catch
{
}
return - 1 ;
}
2021-03-27 08:42:54 +13:00
public static string GetFileSizeReadable ( string filePath , bool binaryUnits = false )
{
long fileSize = GetFileSize ( filePath ) ;
if ( fileSize > = 0 )
{
return fileSize . ToSizeString ( binaryUnits ) ;
}
return "" ;
}
2020-07-06 11:23:59 +12:00
public static void CreateDirectory ( string directoryPath )
2013-11-03 23:53:49 +13:00
{
2018-11-17 20:37:16 +13:00
if ( ! string . IsNullOrEmpty ( directoryPath ) & & ! Directory . Exists ( directoryPath ) )
2013-11-03 23:53:49 +13:00
{
2016-02-22 12:15:23 +13:00
try
2014-12-08 13:36:51 +13:00
{
2018-11-17 20:37:16 +13:00
Directory . CreateDirectory ( directoryPath ) ;
2014-12-08 13:36:51 +13:00
}
2016-02-22 12:15:23 +13:00
catch ( Exception e )
2013-11-03 23:53:49 +13:00
{
2016-02-22 12:15:23 +13:00
DebugHelper . WriteException ( e ) ;
2018-11-17 20:37:16 +13:00
MessageBox . Show ( Resources . Helpers_CreateDirectoryIfNotExist_Create_failed_ + "\r\n\r\n" + e , "ShareX - " + Resources . Error ,
MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
2013-11-03 23:53:49 +13:00
}
}
}
2018-11-17 20:37:16 +13:00
public static void CreateDirectoryFromFilePath ( string filePath )
2016-02-22 12:15:23 +13:00
{
2018-11-17 20:37:16 +13:00
if ( ! string . IsNullOrEmpty ( filePath ) )
2016-02-22 12:15:23 +13:00
{
2018-11-17 20:37:16 +13:00
string directoryPath = Path . GetDirectoryName ( filePath ) ;
2020-07-06 11:23:59 +12:00
CreateDirectory ( directoryPath ) ;
2016-02-22 12:15:23 +13:00
}
}
2018-08-26 00:51:37 +12:00
public static bool IsValidFilePath ( string path )
{
FileInfo fi = null ;
try
{
fi = new FileInfo ( path ) ;
}
catch ( ArgumentException ) { }
catch ( PathTooLongException ) { }
catch ( NotSupportedException ) { }
return fi ! = null ;
}
2019-10-26 01:42:17 +13:00
public static string CopyFile ( string filePath , string destinationFolder , bool overwrite = true )
2013-11-03 23:53:49 +13:00
{
2019-10-26 01:42:17 +13:00
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) & & ! string . IsNullOrEmpty ( destinationFolder ) )
2013-11-03 23:53:49 +13:00
{
2018-08-03 22:40:00 +12:00
string fileName = Path . GetFileName ( filePath ) ;
string destinationFilePath = Path . Combine ( destinationFolder , fileName ) ;
2020-07-06 11:23:59 +12:00
CreateDirectory ( destinationFolder ) ;
2018-08-03 22:40:00 +12:00
File . Copy ( filePath , destinationFilePath , overwrite ) ;
2019-10-26 01:42:17 +13:00
return destinationFilePath ;
}
return null ;
}
public static string MoveFile ( string filePath , string destinationFolder , bool overwrite = true )
{
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) & & ! string . IsNullOrEmpty ( destinationFolder ) )
{
string fileName = Path . GetFileName ( filePath ) ;
string destinationFilePath = Path . Combine ( destinationFolder , fileName ) ;
2020-07-06 11:23:59 +12:00
CreateDirectory ( destinationFolder ) ;
2019-10-26 01:42:17 +13:00
if ( overwrite & & File . Exists ( destinationFilePath ) )
{
File . Delete ( destinationFilePath ) ;
}
File . Move ( filePath , destinationFilePath ) ;
return destinationFilePath ;
2018-08-03 22:40:00 +12:00
}
2019-10-26 01:42:17 +13:00
return null ;
}
public static string RenameFile ( string filePath , string newFileName )
{
try
{
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
{
string directory = Path . GetDirectoryName ( filePath ) ;
string newFilePath = Path . Combine ( directory , newFileName ) ;
File . Move ( filePath , newFilePath ) ;
return newFilePath ;
}
}
catch ( Exception e )
{
MessageBox . Show ( "Rename file error:\r\n" + e . ToString ( ) , "ShareX - " + Resources . Error , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
return filePath ;
2018-08-03 22:40:00 +12:00
}
2013-11-03 23:53:49 +13:00
2018-08-03 22:40:00 +12:00
public static string BackupFileWeekly ( string filePath , string destinationFolder )
{
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
{
string fileName = Path . GetFileNameWithoutExtension ( filePath ) ;
DateTime dateTime = DateTime . Now ;
string extension = Path . GetExtension ( filePath ) ;
string newFileName = string . Format ( "{0}-{1:yyyy-MM}-W{2:00}{3}" , fileName , dateTime , dateTime . WeekOfYear ( ) , extension ) ;
string newFilePath = Path . Combine ( destinationFolder , newFileName ) ;
if ( ! File . Exists ( newFilePath ) )
2013-11-03 23:53:49 +13:00
{
2020-07-06 11:23:59 +12:00
CreateDirectory ( destinationFolder ) ;
2018-08-03 22:40:00 +12:00
File . Copy ( filePath , newFilePath , false ) ;
return newFilePath ;
2013-11-03 23:53:49 +13:00
}
}
2018-08-03 22:40:00 +12:00
return null ;
2013-11-03 23:53:49 +13:00
}
2018-08-03 22:40:00 +12:00
public static void BackupFileMonthly ( string filePath , string destinationFolder )
2013-11-03 23:53:49 +13:00
{
2018-08-03 22:40:00 +12:00
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
2013-11-03 23:53:49 +13:00
{
2018-08-03 22:40:00 +12:00
string fileName = Path . GetFileNameWithoutExtension ( filePath ) ;
string extension = Path . GetExtension ( filePath ) ;
string newFileName = string . Format ( "{0}-{1:yyyy-MM}{2}" , fileName , DateTime . Now , extension ) ;
string newFilePath = Path . Combine ( destinationFolder , newFileName ) ;
2013-11-03 23:53:49 +13:00
2018-08-03 22:40:00 +12:00
if ( ! File . Exists ( newFilePath ) )
2013-11-03 23:53:49 +13:00
{
2020-07-06 11:23:59 +12:00
CreateDirectory ( destinationFolder ) ;
2018-08-03 22:40:00 +12:00
File . Copy ( filePath , newFilePath , false ) ;
2013-11-03 23:53:49 +13:00
}
}
}
public static string GetUniqueID ( )
{
return Guid . NewGuid ( ) . ToString ( "N" ) ;
}
2020-08-05 04:44:26 +12:00
public static Point GetPosition ( ContentAlignment placement , int offset , Size backgroundSize , Size objectSize )
{
return GetPosition ( placement , new Point ( offset , offset ) , backgroundSize , objectSize ) ;
}
2014-01-16 12:20:36 +13:00
public static Point GetPosition ( ContentAlignment placement , Point offset , Size backgroundSize , Size objectSize )
2013-11-16 22:50:08 +13:00
{
2020-08-05 04:44:26 +12:00
int midX = ( int ) Math . Round ( ( backgroundSize . Width / 2f ) - ( objectSize . Width / 2f ) ) ;
int midY = ( int ) Math . Round ( ( backgroundSize . Height / 2f ) - ( objectSize . Height / 2f ) ) ;
2014-01-16 12:20:36 +13:00
int right = backgroundSize . Width - objectSize . Width ;
int bottom = backgroundSize . Height - objectSize . Height ;
2013-11-16 22:50:08 +13:00
2014-01-16 12:20:36 +13:00
switch ( placement )
2013-11-16 22:50:08 +13:00
{
2013-11-09 16:13:49 +13:00
default :
2013-11-16 22:50:08 +13:00
case ContentAlignment . TopLeft :
return new Point ( offset . X , offset . Y ) ;
case ContentAlignment . TopCenter :
return new Point ( midX , offset . Y ) ;
case ContentAlignment . TopRight :
return new Point ( right - offset . X , offset . Y ) ;
case ContentAlignment . MiddleLeft :
return new Point ( offset . X , midY ) ;
case ContentAlignment . MiddleCenter :
return new Point ( midX , midY ) ;
case ContentAlignment . MiddleRight :
return new Point ( right - offset . X , midY ) ;
case ContentAlignment . BottomLeft :
return new Point ( offset . X , bottom - offset . Y ) ;
case ContentAlignment . BottomCenter :
return new Point ( midX , bottom - offset . Y ) ;
case ContentAlignment . BottomRight :
return new Point ( right - offset . X , bottom - offset . Y ) ;
2013-11-09 16:13:49 +13:00
}
}
2013-11-13 14:29:20 +13:00
public static Size MeasureText ( string text , Font font )
{
using ( Graphics g = Graphics . FromHwnd ( IntPtr . Zero ) )
{
return g . MeasureString ( text , font ) . ToSize ( ) ;
}
}
2014-01-09 14:16:48 +13:00
public static Size MeasureText ( string text , Font font , int width )
{
using ( Graphics g = Graphics . FromHwnd ( IntPtr . Zero ) )
{
return g . MeasureString ( text , font , width ) . ToSize ( ) ;
}
}
2014-06-07 06:01:02 +12:00
public static string SendPing ( string host )
{
return SendPing ( host , 1 ) ;
}
public static string SendPing ( string host , int count )
{
string [ ] status = new string [ count ] ;
using ( Ping ping = new Ping ( ) )
{
PingReply reply ;
//byte[] buffer = Encoding.ASCII.GetBytes(new string('a', 32));
for ( int i = 0 ; i < count ; i + + )
{
reply = ping . Send ( host , 3000 ) ;
if ( reply . Status = = IPStatus . Success )
{
status [ i ] = reply . RoundtripTime . ToString ( ) + " ms" ;
}
else
{
status [ i ] = "Timeout" ;
}
Thread . Sleep ( 100 ) ;
}
}
return string . Join ( ", " , status ) ;
}
2014-06-21 00:05:04 +12:00
public static string DownloadString ( string url )
{
if ( ! string . IsNullOrEmpty ( url ) )
{
try
{
using ( WebClient wc = new WebClient ( ) )
{
wc . Encoding = Encoding . UTF8 ;
2017-03-12 10:35:18 +13:00
wc . Headers . Add ( HttpRequestHeader . UserAgent , ShareXResources . UserAgent ) ;
2015-01-12 22:14:59 +13:00
wc . Proxy = HelpersOptions . CurrentProxy . GetWebProxy ( ) ;
2014-06-21 00:05:04 +12:00
return wc . DownloadString ( url ) ;
}
}
catch ( Exception e )
{
DebugHelper . WriteException ( e ) ;
2018-11-17 20:37:16 +13:00
MessageBox . Show ( Resources . Helpers_DownloadString_Download_failed_ + "\r\n" + e , "ShareX - " + Resources . Error , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
2014-06-21 00:05:04 +12:00
}
}
return null ;
}
2014-10-25 13:51:15 +13:00
public static void SetDefaultUICulture ( CultureInfo culture )
{
Type type = typeof ( CultureInfo ) ;
try
{
// .NET 4.0
type . InvokeMember ( "s_userDefaultUICulture" , BindingFlags . SetField | BindingFlags . NonPublic | BindingFlags . Static , null , culture , new object [ ] { culture } ) ;
}
catch
{
try
{
// .NET 2.0
type . InvokeMember ( "m_userDefaultUICulture" , BindingFlags . SetField | BindingFlags . NonPublic | BindingFlags . Static , null , culture , new object [ ] { culture } ) ;
}
catch
{
DebugHelper . WriteLine ( "SetDefaultUICulture failed: " + culture . DisplayName ) ;
}
}
}
2014-12-06 05:22:49 +13:00
public static string GetAbsolutePath ( string path )
{
2016-03-25 08:27:51 +13:00
path = ExpandFolderVariables ( path ) ;
2016-02-13 11:51:56 +13:00
2014-12-06 05:22:49 +13:00
if ( ! Path . IsPathRooted ( path ) ) // Is relative path?
{
2015-09-05 02:42:13 +12:00
path = Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , path ) ;
2014-12-06 05:22:49 +13:00
}
return Path . GetFullPath ( path ) ;
}
2015-05-07 04:49:57 +12:00
2021-12-20 19:03:18 +13:00
public static string GetTempFilePath ( string extension )
2015-08-01 07:35:21 +12:00
{
string path = Path . GetTempFileName ( ) ;
return Path . ChangeExtension ( path , extension ) ;
}
2015-05-07 04:49:57 +12:00
public static bool IsAdministrator ( )
{
2018-11-18 23:51:15 +13:00
try
{
using ( WindowsIdentity identity = WindowsIdentity . GetCurrent ( ) )
{
WindowsPrincipal principal = new WindowsPrincipal ( identity ) ;
return principal . IsInRole ( WindowsBuiltInRole . Administrator ) ;
}
}
catch
{
return false ;
}
2015-05-07 04:49:57 +12:00
}
2015-08-20 10:17:50 +12:00
2020-10-23 22:08:29 +13:00
public static bool IsMemberOfAdministratorsGroup ( )
{
try
{
using ( WindowsIdentity identity = WindowsIdentity . GetCurrent ( ) )
{
WindowsPrincipal principal = new WindowsPrincipal ( identity ) ;
SecurityIdentifier sid = new SecurityIdentifier ( WellKnownSidType . BuiltinAdministratorsSid , null ) ;
return principal . UserClaims . Any ( x = > x . Value . Contains ( sid . Value ) ) ;
}
}
catch
{
}
return false ;
}
2015-08-20 10:17:50 +12:00
public static string RepeatGenerator ( int count , Func < string > generator )
{
string result = "" ;
for ( int x = count ; x > 0 ; x - - )
{
result + = generator ( ) ;
}
return result ;
}
2015-08-24 07:41:59 +12:00
2015-09-05 02:42:13 +12:00
public static bool IsRunning ( string name )
{
try
{
Mutex mutex = Mutex . OpenExisting ( name ) ;
mutex . ReleaseMutex ( ) ;
}
catch
{
return false ;
}
return true ;
}
public static void CopyAll ( string sourceDirectory , string targetDirectory )
{
DirectoryInfo diSource = new DirectoryInfo ( sourceDirectory ) ;
DirectoryInfo diTarget = new DirectoryInfo ( targetDirectory ) ;
CopyAll ( diSource , diTarget ) ;
}
public static void CopyAll ( DirectoryInfo source , DirectoryInfo target )
{
if ( ! Directory . Exists ( target . FullName ) )
{
Directory . CreateDirectory ( target . FullName ) ;
}
foreach ( FileInfo fi in source . GetFiles ( ) )
{
fi . CopyTo ( Path . Combine ( target . FullName , fi . Name ) , true ) ;
}
foreach ( DirectoryInfo diSourceSubDir in source . GetDirectories ( ) )
{
DirectoryInfo nextTargetSubDir = target . CreateSubdirectory ( diSourceSubDir . Name ) ;
CopyAll ( diSourceSubDir , nextTargetSubDir ) ;
}
}
2016-01-19 10:52:47 +13:00
public static T ByteArrayToStructure < T > ( byte [ ] bytes ) where T : struct
{
GCHandle handle = GCHandle . Alloc ( bytes , GCHandleType . Pinned ) ;
try
{
return ( T ) Marshal . PtrToStructure ( handle . AddrOfPinnedObject ( ) , typeof ( T ) ) ;
}
finally
{
handle . Free ( ) ;
}
}
2016-03-19 01:08:24 +13:00
2021-05-31 19:40:42 +12:00
public static IEnumerable < T > GetInstances < T > ( ) where T : class
2016-03-22 09:26:47 +13:00
{
2021-05-31 19:40:42 +12:00
Type baseType = typeof ( T ) ;
Assembly assembly = baseType . Assembly ;
return assembly . GetTypes ( ) . Where ( t = > t . IsClass & & t . IsSubclassOf ( baseType ) & & t . GetConstructor ( Type . EmptyTypes ) ! = null ) .
Select ( t = > Activator . CreateInstance ( t ) as T ) ;
2016-03-22 09:26:47 +13:00
}
2016-06-25 04:49:06 +12:00
2021-05-31 19:40:42 +12:00
public static IEnumerable < Type > FindSubclassesOf < T > ( )
2021-05-31 18:32:50 +12:00
{
2021-05-31 19:40:42 +12:00
Type baseType = typeof ( T ) ;
2021-05-31 18:32:50 +12:00
Assembly assembly = baseType . Assembly ;
return assembly . GetTypes ( ) . Where ( t = > t . IsSubclassOf ( baseType ) ) ;
}
2018-11-14 20:08:45 +13:00
public static string GetOperatingSystemProductName ( bool includeBit = false )
2016-06-25 04:49:06 +12:00
{
2021-10-13 00:04:20 +13:00
string productName = RegistryHelpers . GetValueString ( @"SOFTWARE\Microsoft\Windows NT\CurrentVersion" , "ProductName" , RegistryHive . LocalMachine ) ;
2016-06-25 04:49:06 +12:00
2018-11-14 20:08:45 +13:00
if ( string . IsNullOrEmpty ( productName ) )
{
productName = Environment . OSVersion . VersionString ;
}
if ( includeBit )
{
string bit ;
if ( Environment . Is64BitOperatingSystem )
{
bit = "64" ;
}
else
{
bit = "32" ;
}
productName = $"{productName} ({bit}-bit)" ;
}
return productName ;
2016-06-25 04:49:06 +12:00
}
2016-07-04 22:27:31 +12:00
public static Cursor CreateCursor ( byte [ ] data )
{
using ( MemoryStream ms = new MemoryStream ( data ) )
{
return new Cursor ( ms ) ;
}
}
2017-01-27 07:47:58 +13:00
public static string EscapeCLIText ( string text )
{
2021-12-20 19:03:18 +13:00
string escapedText = text . Replace ( "\\" , "\\\\" ) . Replace ( "\"" , "\\\"" ) ;
return $"\" { escapedText } \ "" ;
2017-01-27 07:47:58 +13:00
}
2017-03-20 12:53:32 +13:00
public static string BytesToHex ( byte [ ] bytes )
{
StringBuilder sb = new StringBuilder ( ) ;
foreach ( byte x in bytes )
{
sb . Append ( string . Format ( "{0:x2}" , x ) ) ;
}
return sb . ToString ( ) ;
}
public static byte [ ] ComputeSHA256 ( byte [ ] data )
{
using ( SHA256Managed hashAlgorithm = new SHA256Managed ( ) )
{
return hashAlgorithm . ComputeHash ( data ) ;
}
}
2018-12-05 05:10:01 +13:00
public static byte [ ] ComputeSHA256 ( Stream stream , int bufferSize = 1024 * 32 )
{
BufferedStream bufferedStream = new BufferedStream ( stream , bufferSize ) ;
using ( SHA256Managed hashAlgorithm = new SHA256Managed ( ) )
{
return hashAlgorithm . ComputeHash ( bufferedStream ) ;
}
}
2017-03-20 12:53:32 +13:00
public static byte [ ] ComputeSHA256 ( string data )
{
return ComputeSHA256 ( Encoding . UTF8 . GetBytes ( data ) ) ;
}
public static byte [ ] ComputeHMACSHA256 ( byte [ ] data , byte [ ] key )
{
using ( HMACSHA256 hashAlgorithm = new HMACSHA256 ( key ) )
{
return hashAlgorithm . ComputeHash ( data ) ;
}
}
public static byte [ ] ComputeHMACSHA256 ( string data , string key )
{
return ComputeHMACSHA256 ( Encoding . UTF8 . GetBytes ( data ) , Encoding . UTF8 . GetBytes ( key ) ) ;
}
public static byte [ ] ComputeHMACSHA256 ( byte [ ] data , string key )
{
return ComputeHMACSHA256 ( data , Encoding . UTF8 . GetBytes ( key ) ) ;
}
public static byte [ ] ComputeHMACSHA256 ( string data , byte [ ] key )
{
return ComputeHMACSHA256 ( Encoding . UTF8 . GetBytes ( data ) , key ) ;
}
2017-04-25 04:29:19 +12:00
public static void CreateEmptyFile ( string path )
{
File . Create ( path ) . Dispose ( ) ;
}
2017-11-02 00:38:07 +13:00
public static string SafeStringFormat ( string format , params object [ ] args )
{
return SafeStringFormat ( null , format , args ) ;
}
public static string SafeStringFormat ( IFormatProvider provider , string format , params object [ ] args )
{
try
{
if ( provider ! = null )
{
return string . Format ( provider , format , args ) ;
}
return string . Format ( format , args ) ;
}
catch ( Exception e )
{
DebugHelper . WriteException ( e ) ;
}
return format ;
}
2017-12-28 03:48:51 +13:00
public static string NumberToLetters ( int num )
{
string result = "" ;
while ( - - num > = 0 )
{
2018-05-17 01:27:11 +12:00
result = ( char ) ( 'A' + ( num % 26 ) ) + result ;
2017-12-28 03:48:51 +13:00
num / = 26 ;
}
return result ;
}
2018-04-30 03:30:03 +12:00
2021-04-17 11:23:17 +12:00
private static string GetNextRomanNumeralStep ( ref int num , int step , string numeral )
{
string result = "" ;
if ( num > = step )
{
result = numeral . Repeat ( num / step ) ;
num % = step ;
}
return result ;
}
2021-04-17 20:50:59 +12:00
2021-04-17 11:23:17 +12:00
public static string NumberToRomanNumeral ( int num )
{
2021-04-17 20:50:59 +12:00
string result = "" ;
2021-04-17 11:23:17 +12:00
result + = GetNextRomanNumeralStep ( ref num , 1000 , "M" ) ;
result + = GetNextRomanNumeralStep ( ref num , 900 , "CM" ) ;
result + = GetNextRomanNumeralStep ( ref num , 500 , "D" ) ;
result + = GetNextRomanNumeralStep ( ref num , 400 , "CD" ) ;
result + = GetNextRomanNumeralStep ( ref num , 100 , "C" ) ;
result + = GetNextRomanNumeralStep ( ref num , 90 , "XC" ) ;
result + = GetNextRomanNumeralStep ( ref num , 50 , "L" ) ;
result + = GetNextRomanNumeralStep ( ref num , 40 , "XL" ) ;
result + = GetNextRomanNumeralStep ( ref num , 10 , "X" ) ;
result + = GetNextRomanNumeralStep ( ref num , 9 , "IX" ) ;
result + = GetNextRomanNumeralStep ( ref num , 5 , "V" ) ;
result + = GetNextRomanNumeralStep ( ref num , 4 , "IV" ) ;
result + = GetNextRomanNumeralStep ( ref num , 1 , "I" ) ;
return result ;
}
2018-04-30 06:23:20 +12:00
[ReflectionPermission(SecurityAction.Assert, MemberAccess = true)]
2018-04-30 03:30:03 +12:00
public static bool TryFixHandCursor ( )
{
try
{
// https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Cursors.cs,423
typeof ( Cursors ) . GetField ( "hand" , BindingFlags . NonPublic | BindingFlags . Static )
2018-04-30 06:23:20 +12:00
. SetValue ( null , new Cursor ( NativeMethods . LoadCursor ( IntPtr . Zero , NativeConstants . IDC_HAND ) ) ) ;
2018-04-30 03:30:03 +12:00
return true ;
}
catch
{
// If it fails, we'll just have to live with the old hand.
return false ;
}
}
2018-12-29 21:17:44 +13:00
public static bool IsTabletMode ( )
{
//int state = NativeMethods.GetSystemMetrics(SystemMetric.SM_CONVERTIBLESLATEMODE);
//return state == 0;
try
{
int result = ( int ) Registry . GetValue ( @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ImmersiveShell" , "TabletMode" , 0 ) ;
return result > 0 ;
}
catch
{
}
return false ;
}
2019-01-10 05:08:55 +13:00
public static string JSONFormat ( string json , Newtonsoft . Json . Formatting formatting )
{
return JToken . Parse ( json ) . ToString ( formatting ) ;
}
public static string XMLFormat ( string xml )
{
using ( MemoryStream ms = new MemoryStream ( ) )
using ( XmlTextWriter writer = new XmlTextWriter ( ms , Encoding . Unicode ) )
{
// Load the XmlDocument with the XML.
XmlDocument document = new XmlDocument ( ) ;
document . LoadXml ( xml ) ;
writer . Formatting = System . Xml . Formatting . Indented ;
// Write the XML into a formatting XmlTextWriter
document . WriteContentTo ( writer ) ;
writer . Flush ( ) ;
ms . Flush ( ) ;
// Have to rewind the MemoryStream in order to read its contents.
ms . Position = 0 ;
// Read MemoryStream contents into a StreamReader.
StreamReader sReader = new StreamReader ( ms ) ;
// Extract the text from the StreamReader.
return sReader . ReadToEnd ( ) ;
}
}
2019-12-08 20:23:20 +13:00
public static IEnumerable < string > GetFilesByExtensions ( string directoryPath , params string [ ] extensions )
{
return GetFilesByExtensions ( new DirectoryInfo ( directoryPath ) , extensions ) ;
}
public static IEnumerable < string > GetFilesByExtensions ( DirectoryInfo directoryInfo , params string [ ] extensions )
{
HashSet < string > allowedExtensions = new HashSet < string > ( extensions , StringComparer . OrdinalIgnoreCase ) ;
return directoryInfo . EnumerateFiles ( ) . Where ( f = > allowedExtensions . Contains ( f . Extension ) ) . Select ( x = > x . FullName ) ;
}
2021-04-30 15:20:19 +12:00
public static Icon GetProgressIcon ( int percentage )
{
return GetProgressIcon ( percentage , Color . FromArgb ( 16 , 116 , 193 ) ) ;
}
public static Icon GetProgressIcon ( int percentage , Color color )
{
percentage = percentage . Clamp ( 0 , 99 ) ;
Size size = SystemInformation . SmallIconSize ;
using ( Bitmap bmp = new Bitmap ( size . Width , size . Height ) )
using ( Graphics g = Graphics . FromImage ( bmp ) )
{
int y = ( int ) ( size . Height * ( percentage / 100f ) ) ;
if ( y > 0 )
{
using ( Brush brush = new SolidBrush ( color ) )
{
g . FillRectangle ( brush , 0 , size . Height - 1 - y , size . Width , y ) ;
}
}
using ( Font font = new Font ( "Arial" , 10 ) )
using ( StringFormat sf = new StringFormat { Alignment = StringAlignment . Center , LineAlignment = StringAlignment . Center } )
{
g . DrawString ( percentage . ToString ( ) , font , Brushes . Black , size . Width / 2f , size . Height / 2f , sf ) ;
g . DrawString ( percentage . ToString ( ) , font , Brushes . White , size . Width / 2f , ( size . Height / 2f ) - 1 , sf ) ;
}
return Icon . FromHandle ( bmp . GetHicon ( ) ) ;
}
}
2021-11-10 21:57:10 +13:00
public static string GetChecksum ( string filePath )
{
using ( SHA256Managed hashAlgorithm = new SHA256Managed ( ) )
{
return GetChecksum ( filePath , hashAlgorithm ) ;
}
}
public static string GetChecksum ( string filePath , HashAlgorithm hashAlgorithm )
{
using ( FileStream fs = File . OpenRead ( filePath ) )
{
byte [ ] hash = hashAlgorithm . ComputeHash ( fs ) ;
return BitConverter . ToString ( hash ) . Replace ( "-" , "" ) ;
}
}
public static string CreateChecksumFile ( string filePath )
{
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
{
string outputFilePath = filePath + ".sha256" ;
2021-11-10 22:07:31 +13:00
string checksum = GetChecksum ( filePath ) ;
string fileName = Path . GetFileName ( filePath ) ;
string content = $"{checksum} {fileName}" ;
File . WriteAllText ( outputFilePath , content ) ;
2021-11-10 21:57:10 +13:00
return outputFilePath ;
}
return null ;
}
2021-11-24 17:37:17 +13:00
public static Task ForEachAsync < T > ( IEnumerable < T > inputEnumerable , Func < T , Task > asyncProcessor , int maxDegreeOfParallelism )
{
SemaphoreSlim throttler = new SemaphoreSlim ( maxDegreeOfParallelism , maxDegreeOfParallelism ) ;
IEnumerable < Task > tasks = inputEnumerable . Select ( async input = >
{
await throttler . WaitAsync ( ) ;
try
{
await asyncProcessor ( input ) ;
}
finally
{
throttler . Release ( ) ;
}
} ) ;
return Task . WhenAll ( tasks ) ;
}
2022-01-05 20:27:48 +13:00
public static bool SendFileToRecycleBin ( string filePath )
{
if ( ! string . IsNullOrEmpty ( filePath ) & & File . Exists ( filePath ) )
{
try
{
FileSystem . DeleteFile ( filePath , UIOption . OnlyErrorDialogs , RecycleOption . SendToRecycleBin ) ;
return true ;
}
catch
{
}
}
return false ;
}
2013-11-03 23:53:49 +13:00
}
2016-08-24 05:33:48 +12:00
}