1
1
using System ;
2
- using System . Text ;
3
2
using System . Runtime . InteropServices ;
4
- using Accessibility ;
5
3
using System . Runtime . InteropServices . ComTypes ;
6
4
using Flow . Launcher . Plugin . Program . Logger ;
5
+ using Windows . Win32 . Foundation ;
6
+ using Windows . Win32 . UI . Shell ;
7
+ using Windows . Win32 . Storage . FileSystem ;
7
8
8
9
namespace Flow . Launcher . Plugin . Program . Programs
9
10
{
10
11
class ShellLinkHelper
11
12
{
12
- [ Flags ( ) ]
13
- public enum SLGP_FLAGS
14
- {
15
- SLGP_SHORTPATH = 0x1 ,
16
- SLGP_UNCPRIORITY = 0x2 ,
17
- SLGP_RAWPATH = 0x4
18
- }
19
-
20
- [ StructLayout ( LayoutKind . Sequential , CharSet = CharSet . Auto ) ]
21
- public struct WIN32_FIND_DATAW
22
- {
23
- public uint dwFileAttributes ;
24
- public long ftCreationTime ;
25
- public long ftLastAccessTime ;
26
- public long ftLastWriteTime ;
27
- public uint nFileSizeHigh ;
28
- public uint nFileSizeLow ;
29
- public uint dwReserved0 ;
30
- public uint dwReserved1 ;
31
- [ MarshalAs ( UnmanagedType . ByValTStr , SizeConst = 260 ) ]
32
- public string cFileName ;
33
- [ MarshalAs ( UnmanagedType . ByValTStr , SizeConst = 14 ) ]
34
- public string cAlternateFileName ;
35
- }
36
-
37
- [ Flags ( ) ]
38
- public enum SLR_FLAGS
39
- {
40
- SLR_NO_UI = 0x1 ,
41
- SLR_ANY_MATCH = 0x2 ,
42
- SLR_UPDATE = 0x4 ,
43
- SLR_NOUPDATE = 0x8 ,
44
- SLR_NOSEARCH = 0x10 ,
45
- SLR_NOTRACK = 0x20 ,
46
- SLR_NOLINKINFO = 0x40 ,
47
- SLR_INVOKE_MSI = 0x80
48
- }
49
-
50
-
13
+
51
14
// Reference : http://www.pinvoke.net/default.aspx/Interfaces.IShellLinkW
52
- /// The IShellLink interface allows Shell links to be created, modified, and resolved
53
- [ ComImport ( ) , InterfaceType ( ComInterfaceType . InterfaceIsIUnknown ) , Guid ( "000214F9-0000-0000-C000-000000000046" ) ]
54
- interface IShellLinkW
55
- {
56
- /// <summary>Retrieves the path and file name of a Shell link object</summary>
57
- void GetPath ( [ Out ( ) , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszFile , int cchMaxPath , ref WIN32_FIND_DATAW pfd , SLGP_FLAGS fFlags ) ;
58
- /// <summary>Retrieves the list of item identifiers for a Shell link object</summary>
59
- void GetIDList ( out IntPtr ppidl ) ;
60
- /// <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
61
- void SetIDList ( IntPtr pidl ) ;
62
- /// <summary>Retrieves the description string for a Shell link object</summary>
63
- void GetDescription ( [ Out ( ) , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszName , int cchMaxName ) ;
64
- /// <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
65
- void SetDescription ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszName ) ;
66
- /// <summary>Retrieves the name of the working directory for a Shell link object</summary>
67
- void GetWorkingDirectory ( [ Out ( ) , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszDir , int cchMaxPath ) ;
68
- /// <summary>Sets the name of the working directory for a Shell link object</summary>
69
- void SetWorkingDirectory ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszDir ) ;
70
- /// <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
71
- void GetArguments ( [ Out ( ) , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszArgs , int cchMaxPath ) ;
72
- /// <summary>Sets the command-line arguments for a Shell link object</summary>
73
- void SetArguments ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszArgs ) ;
74
- /// <summary>Retrieves the hot key for a Shell link object</summary>
75
- void GetHotkey ( out short pwHotkey ) ;
76
- /// <summary>Sets a hot key for a Shell link object</summary>
77
- void SetHotkey ( short wHotkey ) ;
78
- /// <summary>Retrieves the show command for a Shell link object</summary>
79
- void GetShowCmd ( out int piShowCmd ) ;
80
- /// <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
81
- void SetShowCmd ( int iShowCmd ) ;
82
- /// <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
83
- void GetIconLocation ( [ Out ( ) , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszIconPath ,
84
- int cchIconPath , out int piIcon ) ;
85
- /// <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
86
- void SetIconLocation ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszIconPath , int iIcon ) ;
87
- /// <summary>Sets the relative path to the Shell link object</summary>
88
- void SetRelativePath ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszPathRel , int dwReserved ) ;
89
- /// <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
90
- void Resolve ( ref Accessibility . _RemotableHandle hwnd , SLR_FLAGS fFlags ) ;
91
- /// <summary>Sets the path and file name of a Shell link object</summary>
92
- void SetPath ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszFile ) ;
93
- }
94
-
95
15
[ ComImport ( ) , Guid ( "00021401-0000-0000-C000-000000000046" ) ]
96
16
public class ShellLink
97
17
{
@@ -102,29 +22,40 @@ public class ShellLink
102
22
public string arguments = string . Empty ;
103
23
104
24
// Retrieve the target path using Shell Link
105
- public string retrieveTargetPath ( string path )
25
+ public unsafe string retrieveTargetPath ( string path )
106
26
{
107
27
var link = new ShellLink ( ) ;
108
28
const int STGM_READ = 0 ;
109
29
( ( IPersistFile ) link ) . Load ( path , STGM_READ ) ;
110
- var hwnd = new _RemotableHandle ( ) ;
111
- ( ( IShellLinkW ) link ) . Resolve ( ref hwnd , 0 ) ;
30
+ var hwnd = new HWND ( IntPtr . Zero ) ;
31
+ ( ( IShellLinkW ) link ) . Resolve ( hwnd , 0 ) ;
112
32
113
33
const int MAX_PATH = 260 ;
114
- StringBuilder buffer = new StringBuilder ( MAX_PATH ) ;
34
+ char [ ] buffer = new char [ MAX_PATH ] ;
115
35
116
36
var data = new WIN32_FIND_DATAW ( ) ;
117
- ( ( IShellLinkW ) link ) . GetPath ( buffer , buffer . Capacity , ref data , SLGP_FLAGS . SLGP_SHORTPATH ) ;
118
- var target = buffer . ToString ( ) ;
37
+ var target = string . Empty ;
38
+ fixed ( char * bufferChar = buffer )
39
+ {
40
+ ( ( IShellLinkW ) link ) . GetPath ( ( PWSTR ) bufferChar , MAX_PATH , & data , ( uint ) SLGP_FLAGS . SLGP_SHORTPATH ) ;
41
+ int validLength = Array . IndexOf ( buffer , '\0 ' ) ;
42
+ if ( validLength < 0 ) validLength = MAX_PATH ;
43
+ target = new string ( buffer , 0 , validLength ) ;
44
+ }
119
45
120
46
// To set the app description
121
- if ( ! String . IsNullOrEmpty ( target ) )
47
+ if ( ! string . IsNullOrEmpty ( target ) )
122
48
{
123
49
try
124
50
{
125
- buffer = new StringBuilder ( MAX_PATH ) ;
126
- ( ( IShellLinkW ) link ) . GetDescription ( buffer , MAX_PATH ) ;
127
- description = buffer . ToString ( ) ;
51
+ char [ ] buffer1 = new char [ MAX_PATH ] ;
52
+ fixed ( char * buffer1Char = buffer1 )
53
+ {
54
+ ( ( IShellLinkW ) link ) . GetDescription ( ( PWSTR ) buffer1Char , MAX_PATH ) ;
55
+ int validLength = Array . IndexOf ( buffer1 , '\0 ' ) ;
56
+ if ( validLength < 0 ) validLength = MAX_PATH ;
57
+ description = new string ( buffer1 , 0 , validLength ) ;
58
+ }
128
59
}
129
60
catch ( COMException e )
130
61
{
@@ -134,9 +65,14 @@ public string retrieveTargetPath(string path)
134
65
e ) ;
135
66
}
136
67
137
- buffer . Clear ( ) ;
138
- ( ( IShellLinkW ) link ) . GetArguments ( buffer , MAX_PATH ) ;
139
- arguments = buffer . ToString ( ) ;
68
+ char [ ] buffer2 = new char [ MAX_PATH ] ;
69
+ fixed ( char * buffer2Char = buffer2 )
70
+ {
71
+ ( ( IShellLinkW ) link ) . GetArguments ( ( PWSTR ) buffer2Char , MAX_PATH ) ;
72
+ int validLength = Array . IndexOf ( buffer2 , '\0 ' ) ;
73
+ if ( validLength < 0 ) validLength = MAX_PATH ;
74
+ arguments = new string ( buffer2 , 0 , validLength ) ;
75
+ }
140
76
}
141
77
142
78
// To release unmanaged memory
0 commit comments