Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Создать / удалить ярлык на рабочем столе программно. / 22 сообщений из 22, страница 1 из 1
04.06.2018, 20:21
    #39655192
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
В общем пока особо не искал, не думал.

Надо создать ярлык к запуску проги ...Program Files\Proga\Proga.exe на рабочий стол для "любого пользователя" (уже существующего, будующего, любого).

Полагаю лежать должен в ...\Users\Public\Desktop (именно там лежат все общие, есть еще ...\Users\Default\Desktop, но она пустая и полагаю не пойдет).

За меня всю жизнь это успешно делал инсталлятор (с удалением после деинсталляции), но в силу специфики задачи надо уметь "самому".

1) создать ярлык
2) удалить ярлык. Здесь еще вот чего б хотелось. Допустим юзер переименовал название ярлыка, сделал егойную копию, ну пусть на рабочем столе. Желательно чтоб удалялись все ярлыки ведущие к Proga\Proga.exe (хотя б на рабочем столе) независимо от имени файла .lnk.

Вот тыркнулся поиском по форуму.
Средства для работы с ярлыками
(под спойлером)
Сюда копать или куда еще?
В .Net прямого инструмента так полагаю нет.
А классические API (без Interface-ов) есть на эту тему? CreateObject("WScript.Shell" еще как из того же топика следует, но не люблю такой "простоты", и боюсь он второй задачи с грамотным удалением не решит.
...
Рейтинг: 0 / 0
04.06.2018, 21:25
    #39655220
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Для создания и размещения ярлыков в любом месте (рабочий стол, папки пользователя, главное меню и т.д.)
в WinAPI есть все нужные функции.
Удаление файла .lnk в заранее известном месте также не вызывает проблем.

Если пользователь создал и разместил неизвестно где копию ярлыка, то после удаления источника (к примеру, файла .exe),
этот ярлык становится нерабочим. Искать его - дурное дело. Пусть пользователь сам удаляет свой мусор.

На основе функций WinAPI я делал свои инсталляторы/деинсталляторы (на С++). Особых проблем там нет.
...
Рейтинг: 0 / 0
04.06.2018, 22:34
    #39655243
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
d7iДля создания и размещения ярлыков в любом месте (рабочий стол, папки пользователя, главное меню и т.д.)
в WinAPI есть все нужные функции.
Какие?
Я так понял, COM это единственный способ.
Creating and Modifying Shortcuts
но это 2003г.
(Речь идет о Win7 и выше)
...
Рейтинг: 0 / 0
04.06.2018, 23:02
    #39655255
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
...
Рейтинг: 0 / 0
04.06.2018, 23:09
    #39655261
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Если хотите пример, то вот на Power++

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
//---------------------------------------------------------------------------------------------------------------------------------------------------------
// Функция создания ярлыка 
// (папка ярлыка,имя ярлыка,файл ярлыка,аргументы файла,рабочая папка,комментарий,путь к иконке,номер иконки)
//---------------------------------------------------------------------------------------------------------------------------------------------------------
WBool CreateShortCut(const WChar * linkPath,const WChar * shortcutFile,const WChar * arguments,const WChar * workingDirectory,const WChar * description,const WChar * iconpath,const WLong icon)
{
    WBool result;
  HRESULT hres;
  IShellLink* psl;

  result = false;
  // указатель на IShellLink interface.
  hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
  if (SUCCEEDED(hres))
  {
    IPersistFile* ppf;
    // запрос IShellLink к IPersistFile interface для сохранения ярлыка
    hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
    if (SUCCEEDED(hres))
    {
       WUnicodeChar wsz[MAX_PATH];
       result = false;
       // файл ярлыка
       hres = psl->SetPath(shortcutFile);
       if(SUCCEEDED(hres))
       {
         if( arguments )        // аргументы файла ярлыка
           psl->SetArguments( arguments );
         if( workingDirectory ) // рабочая папка ярлыка
           psl->SetWorkingDirectory( workingDirectory );
         if( description )        // комментарий ярлыка
           psl->SetDescription( description );
         if(icon>0)  
           psl->SetIconLocation(iconpath,icon);
         // перевод из ANSI в Unicode.
         ::MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wsz, MAX_PATH);
         // сохранение ярлыка через IPersistFile::Save method.
         hres = ppf->Save(wsz, TRUE);
         result = SUCCEEDED(hres);
         // снятие указателя к IPersistFile.
         ppf->Release();
       }
    }
    // снятие указателя с IShellLink.
    psl->Release();
  }
  return result;
}



Главное - последовательность действий и вызываемые функции. Можно переделать под любой другой язык.
...
Рейтинг: 0 / 0
04.06.2018, 23:22
    #39655263
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Проверено на всех Windows от XP до 10.
Кстати, чтобы иконка ярлыка красиво отображалась в любом виде, она должна быть комбинированной и
содержать все размеры: 16х16,32х32,48х48,64х64,128х128,256х256.
...
Рейтинг: 0 / 0
04.06.2018, 23:35
    #39655266
d7i
d7i
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
И вдогонку. Чтобы программно определить нужную системную папку можно сделать функцию:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
//-------------------------------------------------------------------------------------------------------------------------------------------
// Функция получения папки ярлыка
//-------------------------------------------------------------------------------------------------------------------------------------------
WBool GetSpecialFolderLocation(WWindow * window,WInt nFolder,WString & folder)
{
  WBool handled;
  ITEMIDLIST * pidl( NULL );

  HRESULT result = ::SHGetSpecialFolderLocation(window->GetHandle(),nFolder, &pidl);
  if( SUCCEEDED(result) )
  {
     WChar * path = folder.Lock( MAX_PATH );
     handled = ::SHGetPathFromIDList( pidl, path );
     folder.Unlock();
  }
  else
    handled = false;
  if( pidl )
  {
     LPMALLOC pAllocObj;
     SHGetMalloc( &pAllocObj );
     pAllocObj->Free( pidl );
  }
  return handled;
}



Пример использования:

GetSpecialFolderLocation(this,CSIDL_DESKTOP,desktopFolder); // рабочий стол
GetSpecialFolderLocation(this,CSIDL_PROGRAMS,menuFolder); // меню "Пуск"

И т.д.
...
Рейтинг: 0 / 0
05.06.2018, 01:39
    #39655292
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Это работа установщика, а не программы. Сделайте пакет установки, там этот функционал как правило уже есть и его нужно просто включить или определить.
...
Рейтинг: 0 / 0
05.06.2018, 09:37
    #39655362
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
d7i,

Ну я понял Ваши ответы,
но это как бы не совсем "классические" API, которые в .Net/VB6 декларируются функциями и структурами (чего я люблю).
Т.е. кухня как не крути сводится к интерфейсам IShellLink и IPersistFile.

Ну осилим, я думаю.

Выпишу на всяк. случай полезные ссылки в столбик:

Creating and Modifying Shortcuts (vbaccelerator.com, проект C#)

Using IShellLink Interface to resolve a shortcut which has changed their drive letter (VB.Net)

How to create and resolve a shortcut

Средства для работы с ярлыками (на нашем форуме, под спойлером, C#)

Пошел ваять свой вариант. Сделаю, отчитаюсь.
===

d7iКстати, чтобы иконка ярлыка красиво отображалась в любом виде, она должна быть комбинированной и
содержать все размеры: 16х16,32х32,48х48,64х64,128х128,256х256.Ну, ясно дело, что если в exe, на кот. указывает ярлык и откуда иконка берется она именно такая, то она таковой и будет. Я ж не собираюсь ее рисовать сам своим кодом.

Roman MejtesЭто работа установщика, а не программы. Сделайте пакет установки, там этот функционал как правило уже есть и его нужно просто включить или определить.
Роман, я ж уточнил в первом же посте
За меня всю жизнь это успешно делал инсталлятор (с удалением после деинсталляции), но в силу специфики задачи надо уметь "самому".
Специфика такая:
У меня
Program Files\Proga\Proga.exe == Program Files\Windows Mail\WinMail.exe
При обновлении как минимум Win10 1703->1709->1803 винды не только "рушат компоненты" Winmail но в частности маньячно удаляют все ярлыки со ссылкой на этот путь (во всяком случае с рабочего стола и неважно какое имя у .lnk).
Задачей моей утилиты (уже установленной) в частности восстановить этот ярлык.
Да и обратная задача "маньячного удаления ярлыков" не лишняя, ибо утилита должна уметь не только восстанавливать, но и откатывать обратно к неработоспособному оригинальному состоянию (неработоспособный ярлык на рабочем столе это лишнее).
Инсталлятор утилиты с этими задачами нормально не справится, он только может установить ярлык один раз (при install), и удалить (при uninstall).
...
Рейтинг: 0 / 0
05.06.2018, 16:23
    #39655756
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Roman MejtesЭто работа установщика, а не программы. Сделайте пакет установки, там этот функционал как правило уже есть и его нужно просто включить или определить.

Не по адресу такие сообщения

Как делать нужно и правильно -- это ответы-аутсайдеры. Им в этих топиках не место.
...
Рейтинг: 0 / 0
05.06.2018, 16:45
    #39655780
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Дмитрий77Инсталлятор утилиты с этими задачами нормально не справится, он только может установить ярлык один раз (при install), и удалить (при uninstall).ты че такой дремучий? Не видел окно Удаление или ИЗМЕНЕНИЕ программы в винде?
Там кнопка есть - восстановить.
...
Рейтинг: 0 / 0
05.06.2018, 17:11
    #39655813
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Petro123Дмитрий77Инсталлятор утилиты с этими задачами нормально не справится, он только может установить ярлык один раз (при install), и удалить (при uninstall).ты че такой дремучий? Не видел окно Удаление или ИЗМЕНЕНИЕ программы в винде?
Там кнопка есть - восстановить.
Вот ни близко, ни около.
...
Рейтинг: 0 / 0
05.06.2018, 17:39
    #39655847
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Дмитрий77Вот ни близко, ни около.ты инженерным языком пиши))))
Правый клик на строке EF программа. Далее что видим?
...
Рейтинг: 0 / 0
05.06.2018, 18:24
    #39655896
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Petro123,
Панель управления\Программы\Программы и компоненты
>Правый клик на строке EF программа. Далее что видим?
Как правило видим "Удалить".
Реже еще "Изменить".
Еще реже "Восстановить".
От инсталлятора зависит.
Какое отношение к делу и к заданному вопросу?
У меня утилита, будучи УЖЕ УСТАНОВЛЕННОЙ, сама делает "Восстановить" ( чего надо, не себя саму , напр. будучи прописанной в автозагрузку через реестр или планировщик, или по кнопке "Восстановить" в ней самой). И в частности она должна "Восстановить" нужный ярлык, кот. имеет свойство тупо пропасть после очередного обновления/перезагрузки компа и в процессе эксплуатации уже установленной утилиты.
...
Рейтинг: 0 / 0
05.06.2018, 18:38
    #39655910
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Дмитрий77Как правило видим "Удалить".
Реже еще "Изменить".
Еще реже "Восстановить".
Угу. В инсталляторе галка ставится какую показывать кнопку))).
..
Отсюда ты пишешь велосипед.
И тебя предупредили.
А дальше сам.
Удачи!
...
Рейтинг: 0 / 0
05.06.2018, 21:21
    #39655960
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Сделаю, отчитаюсьМой модуль:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
Imports System.Runtime.InteropServices
Imports System.Text

Module m_IShellLink

#Region "Constants"

  'IShellLink::GetPath method
  <Flags()>
  Private Enum SLGP_FLAGS
    ''' <summary>Retrieves the standard short (8.3 format) file name</summary>
    SLGP_SHORTPATH = &H1
    ''' <summary>Retrieves the Universal Naming Convention (UNC) path name of the file</summary>
    SLGP_UNCPRIORITY = &H2
    ''' <summary>Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded</summary>
    SLGP_RAWPATH = &H4
    ''' <summary>Windows Vista and later. Retrieves the path, if possible, of the shortcut's target relative to the path set by a previous call to IShellLink::SetRelativePath</summary>
    SLGP_RELATIVEPRIORITY = &H8
  End Enum

  'Time Structures
  <StructLayout(LayoutKind.Sequential)>
  Private Structure FILETIME
    Dim dwLowDateTime As Integer
    Dim dwHighDateTime As Integer
  End Structure

  'File Management Structures
  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
  Private Structure WIN32_FIND_DATA
    Dim dwFileAttributes As Integer
    Dim ftCreationTime As FILETIME
    Dim ftLastAccessTime As FILETIME
    Dim ftLastWriteTime As FILETIME
    Dim nFileSizeHigh As Integer
    Dim nFileSizeLow As Integer
    Dim dwReserved0 As Integer
    Dim dwReserved1 As Integer
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> Dim cFileName As String
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=14)> Dim cAlternateFileName As String
  End Structure

  'IShellLink::Resolve method
  <Flags()>
  Private Enum SLR_FLAGS
    ''' <summary>
    ''' Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set,
    ''' the high-order word of fFlags can be set to a time-out value that specifies the
    ''' maximum amount of time to be spent resolving the link. The function returns if the
    ''' link cannot be resolved within the time-out duration. If the high-order word is set
    ''' to zero, the time-out duration will be set to the default value of 3,000 milliseconds
    ''' (3 seconds). To specify a value, set the high word of fFlags to the desired time-out
    ''' duration, in milliseconds.
    ''' </summary>
    SLR_NO_UI = &H1
    ''' <summary>Obsolete and no longer used</summary>
    SLR_ANY_MATCH = &H2
    ''' <summary>If the link object has changed, update its path and list of identifiers.
    ''' If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine
    ''' whether or not the link object has changed.</summary>
    SLR_UPDATE = &H4
    ''' <summary>Do not update the link information</summary>
    SLR_NOUPDATE = &H8
    ''' <summary>Do not execute the search heuristics</summary>
    SLR_NOSEARCH = &H10
    ''' <summary>Do not use distributed link tracking</summary>
    SLR_NOTRACK = &H20
    ''' <summary>Disable distributed link tracking. By default, distributed link tracking tracks
    ''' removable media across multiple devices based on the volume name. It also uses the
    ''' Universal Naming Convention (UNC) path to track remote file systems whose drive letter
    ''' has changed. Setting SLR_NOLINKINFO disables both types of tracking.</summary>
    SLR_NOLINKINFO = &H40
    ''' <summary>Call the Microsoft Windows Installer</summary>
    SLR_INVOKE_MSI = &H80
  End Enum

  'IPersistFile::Load method
  Private Const STGM_READ As UInteger = 0

  Private Const MAX_PATH = 260

#End Region


#Region "COM"

  'Shell Interfaces -> IShellLink
  ''' <summary>The IShellLink interface allows Shell links to be created, modified, and resolved</summary>
  <ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")>
  Private Interface IShellLinkW
    ''' <summary>Retrieves the path and file name of a Shell link object</summary>
    Sub GetPath(<Out(), MarshalAs(UnmanagedType.LPWStr)> pszFile As StringBuilder, cchMaxPath As Integer, ByRef pfd As WIN32_FIND_DATA, fFlags As SLGP_FLAGS)
    ''' <summary>Retrieves the list of item identifiers for a Shell link object</summary>
    Sub GetIDList(ByRef ppidl As IntPtr)
    ''' <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
    Sub SetIDList(pidl As IntPtr)
    ''' <summary>Retrieves the description string for a Shell link object</summary>
    Sub GetDescription(<Out(), MarshalAs(UnmanagedType.LPWStr)> pszName As StringBuilder, cchMaxName As Integer)
    ''' <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
    Sub SetDescription(<MarshalAs(UnmanagedType.LPWStr)> pszName As String)
    ''' <summary>Retrieves the name of the working directory for a Shell link object</summary>
    Sub GetWorkingDirectory(<Out(), MarshalAs(UnmanagedType.LPWStr)> pszDir As StringBuilder, cchMaxPath As Integer)
    ''' <summary>Sets the name of the working directory for a Shell link object</summary>
    Sub SetWorkingDirectory(<MarshalAs(UnmanagedType.LPWStr)> pszDir As String)
    ''' <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
    Sub GetArguments(<Out(), MarshalAs(UnmanagedType.LPWStr)> pszArgs As StringBuilder, cchMaxPath As Integer)
    ''' <summary>Sets the command-line arguments for a Shell link object</summary>
    Sub SetArguments(<MarshalAs(UnmanagedType.LPWStr)> pszArgs As String)
    ''' <summary>Retrieves the hot key for a Shell link object</summary>
    Sub GetHotkey(ByRef pwHotkey As Short)
    ''' <summary>Sets a hot key for a Shell link object</summary>
    Sub SetHotkey(wHotkey As Short)
    ''' <summary>Retrieves the show command for a Shell link object</summary>
    Sub GetShowCmd(ByRef piShowCmd As Integer)
    ''' <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
    Sub SetShowCmd(iShowCmd As Integer)
    ''' <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
    Sub GetIconLocation(<Out(), MarshalAs(UnmanagedType.LPWStr)> pszIconPath As StringBuilder, cchIconPath As Integer, ByRef piIcon As Integer)
    ''' <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
    Sub SetIconLocation(<MarshalAs(UnmanagedType.LPWStr)> pszIconPath As String, iIcon As Integer)
    ''' <summary>Sets the relative path to the Shell link object</summary>
    Sub SetRelativePath(<MarshalAs(UnmanagedType.LPWStr)> pszPathRel As String, dwReserved As Integer)
    ''' <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
    Sub Resolve(hwnd As IntPtr, fFlags As SLR_FLAGS)
    ''' <summary>Sets the path and file name of a Shell link object</summary>
    Sub SetPath(<MarshalAs(UnmanagedType.LPWStr)> pszFile As String)

  End Interface

  'COM Fundamentals -> Reference -> Interfaces -> IPersist
  <ComImport(), Guid("0000010c-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
  Private Interface IPersist
    <PreserveSig()>
    Sub GetClassID(ByRef pClassID As Guid)
  End Interface

  'COM Fundamentals -> Reference -> Interfaces -> IPersistFile
  <ComImport(), Guid("0000010b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
  Private Interface IPersistFile
    Inherits IPersist
    Shadows Sub GetClassID(ByRef pClassID As Guid)
    <PreserveSig()>
    Function IsDirty() As Integer

    ''' <summary>Opens the specified file and initializes an object from the file contents</summary>
    <PreserveSig()>
    Sub Load(<[In](), MarshalAs(UnmanagedType.LPWStr)> pszFileName As String, dwMode As UInteger)

    ''' <summary>Saves a copy of the object to the specified file</summary>
    <PreserveSig()>
    Sub Save(<[In](), MarshalAs(UnmanagedType.LPWStr)> pszFileName As String, <[In](), MarshalAs(UnmanagedType.Bool)> fRemember As Boolean)

    <PreserveSig()>
    Sub SaveCompleted(<[In](), MarshalAs(UnmanagedType.LPWStr)> pszFileName As String)

    <PreserveSig()>
    Sub GetCurFile(<[In](), MarshalAs(UnmanagedType.LPWStr)> ppszFileName As String)
  End Interface

  ' CLSID_ShellLink from ShlGuid.h 
  <ComImport(), Guid("00021401-0000-0000-C000-000000000046")> Private Class ShellLink
  End Class

#End Region


  Public Function CreateShortcut(ByVal pszShortcutPath As String, ByVal pszFileName As String, _
   Optional ByVal pszArguments As String = vbNullString, _
   Optional ByVal pszWorkingDirectory As String = vbNullString, _
   Optional ByVal pszDescription As String = vbNullString, _
   Optional ByVal pszIconPath As String = vbNullString, _
   Optional ByVal iIcon As Integer = 0) As Boolean
    'pszShortcutPath - string that specifies a path and file name of a shortcut
    'pszFileName - the path and file name for the target of a Shell link object
    'pszArguments - the command-line arguments for a Shell link object
    'pszWorkingDirectory - the name of the working directory for a Shell link object
    'pszDescription - the description string for a Shell link object
    'pszIconPath - the path of the file containing the icon
    'iIcon - the index of the icon

    Try
      If (Strings.Len(pszShortcutPath) = 0) Or _
       IO.Directory.Exists(IO.Path.GetDirectoryName(pszShortcutPath)) = False Then
        Return False
      End If

      Dim link As New ShellLink()
      'FileName
      DirectCast(link, IShellLinkW).SetPath(pszFileName)
      'Arguments
      If Strings.Len(pszArguments) > 0 Then DirectCast(link, IShellLinkW).SetArguments(pszArguments)
      'WorkingDirectory
      If Strings.Len(pszWorkingDirectory) = 0 Then
        'пытаемся взять WorkingDirectory из пути к pszFileName
        Try
          If (Strings.Len(pszFileName) > 0) Then pszWorkingDirectory = IO.Path.GetDirectoryName(pszFileName)
        Catch
        End Try
      End If
      If Strings.Len(pszWorkingDirectory) > 0 Then
        pszWorkingDirectory = GoodPath(pszWorkingDirectory) 'Add a trailing slash if none (поведение виндов)
        DirectCast(link, IShellLinkW).SetWorkingDirectory(pszWorkingDirectory)
      End If
      'Description
      If Strings.Len(pszDescription) > 0 Then DirectCast(link, IShellLinkW).SetDescription(pszDescription)
      'Icon (при отсутствии pszIconPath присваивается нулевая иконка из pszFileName)
      If Strings.Len(pszIconPath) > 0 Then DirectCast(link, IShellLinkW).SetIconLocation(pszIconPath, iIcon)
      'сохранение
      DirectCast(link, IPersistFile).Save(pszShortcutPath, True)
      Return True
    Catch
      Return False 'вряд ли оно споткнется...или об этом скажет
    End Try
  End Function

  Public Function GetShortcutTarget(ByVal pszShortcutPath As String) As String
    'путь к файлу, на кот. указывает ярлык
    Try
      Dim link As New ShellLink()
      DirectCast(link, IPersistFile).Load(pszShortcutPath, STGM_READ)
      Dim sb As New StringBuilder(MAX_PATH)
      Dim data As New WIN32_FIND_DATA
      DirectCast(link, IShellLinkW).GetPath(sb, sb.Capacity, data, 0)
      Return sb.ToString()
    Catch
      Return ""
    End Try
  End Function

  Public Sub RemoveShortcutsByTagretName(ByVal pszFolder As String, ByVal pszTargetName As String)
    'удаляет все ярлыки указывающие на имя pszTargetName по заданному пути pszFolder
    Dim ff As String() = IO.Directory.GetFiles(pszFolder, "*.lnk", IO.SearchOption.TopDirectoryOnly)
    For Each f As String In ff
      Dim sTarget As String = GetShortcutTarget(f)
      If Strings.Len(sTarget) > 0 Then
        If UCase(IO.Path.GetFileName(sTarget)) = UCase(pszTargetName) Then
          Try : IO.File.Delete(f) : Catch : End Try
        End If
      End If
    Next
  End Sub

  Private Function GoodPath(ByVal NewPath) As String
    Dim sPath As String
    'Add a trailing slash if none
    sPath = NewPath & IIf(Strings.Right(NewPath, 1) = "\", "", "\")
    GoodPath = sPath
  End Function


End Module

1) создать ярлык
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
    Dim pszShortcutPath As String = IO.Path.Combine(GetFolderPath(SpecialFolder.CommonDesktopDirectory), "Ярлык к Proga.lnk")
    Dim pszFileName As String = IO.Path.Combine(path_Proga, "Proga.exe")
    Dim pszArguments As String = ""
    Dim pszWorkingDirectory As String = GoodPath(path_Proga)
    Dim pszDescription As String = "Запустить Proga бла-бла-бла"
    Dim pszIconPath As String = pszFileName
    Dim iIcon As Integer = 0
    CreateShortcut(pszShortcutPath, pszFileName, pszArguments, pszWorkingDirectory, pszDescription, pszIconPath, iIcon)


  Public Function CreateShortcut(ByVal pszShortcutPath As String, ByVal pszFileName As String, _
   Optional ByVal pszArguments As String = vbNullString, _
   Optional ByVal pszWorkingDirectory As String = vbNullString, _
   Optional ByVal pszDescription As String = vbNullString, _
   Optional ByVal pszIconPath As String = vbNullString, _
   Optional ByVal iIcon As Integer = 0) As Boolean
    'pszShortcutPath - string that specifies a path and file name of a shortcut
    'pszFileName - the path and file name for the target of a Shell link object
    'pszArguments - the command-line arguments for a Shell link object
    'pszWorkingDirectory - the name of the working directory for a Shell link object
    'pszDescription - the description string for a Shell link object
    'pszIconPath - the path of the file containing the icon
    'iIcon - the index of the icon

    Try
      If (Strings.Len(pszShortcutPath) = 0) Or _
       IO.Directory.Exists(IO.Path.GetDirectoryName(pszShortcutPath)) = False Then
        Return False
      End If

      Dim link As New ShellLink()
      'FileName
      DirectCast(link, IShellLinkW).SetPath(pszFileName)
      'Arguments
      If Strings.Len(pszArguments) > 0 Then DirectCast(link, IShellLinkW).SetArguments(pszArguments)
      'WorkingDirectory
      If Strings.Len(pszWorkingDirectory) = 0 Then
        'пытаемся взять WorkingDirectory из пути к pszFileName
        Try
          If (Strings.Len(pszFileName) > 0) Then pszWorkingDirectory = IO.Path.GetDirectoryName(pszFileName)
        Catch
        End Try
      End If
      If Strings.Len(pszWorkingDirectory) > 0 Then
        pszWorkingDirectory = GoodPath(pszWorkingDirectory) 'Add a trailing slash if none (поведение виндов)
        DirectCast(link, IShellLinkW).SetWorkingDirectory(pszWorkingDirectory)
      End If
      'Description
      If Strings.Len(pszDescription) > 0 Then DirectCast(link, IShellLinkW).SetDescription(pszDescription)
      'Icon (при отсутствии pszIconPath присваивается нулевая иконка из pszFileName)
      If Strings.Len(pszIconPath) > 0 Then DirectCast(link, IShellLinkW).SetIconLocation(pszIconPath, iIcon)
      'сохранение
      DirectCast(link, IPersistFile).Save(pszShortcutPath, True)
      Return True
    Catch
      Return False 'вряд ли оно споткнется...или об этом скажет
    End Try
  End Function


2) удалить ярлык. Здесь еще вот чего б хотелось. Допустим юзер переименовал название ярлыка, сделал егойную копию, ну пусть на рабочем столе. Желательно чтоб удалялись все ярлыки ведущие к Proga\Proga.exe (хотя б на рабочем столе) независимо от имени файла .lnk.
Я привязываюсь к имени exe-шника, без выяснения пути, но можно модифицировать и сравнивать точный путь, это уж в зависимости от "задачи"
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
  RemoveShortcutsByTagretName(GetFolderPath(SpecialFolder.CommonDesktopDirectory), "Proga.exe") 'Common Desktop (As Admin!)
  RemovelShortcutsByTagretName(GetFolderPath(SpecialFolder.DesktopDirectory), "Proga.exe") 'Current User Desktop

  Public Sub RemoveShortcutsByTagretName(ByVal pszFolder As String, ByVal pszTargetName As String)
    'удаляет все ярлыки указывающие на имя pszTargetName по заданному пути pszFolder
    Dim ff As String() = IO.Directory.GetFiles(pszFolder, "*.lnk", IO.SearchOption.TopDirectoryOnly)
    For Each f As String In ff
      Dim sTarget As String = GetShortcutTarget(f)
      If Strings.Len(sTarget) > 0 Then
        If UCase(IO.Path.GetFileName(sTarget)) = UCase(pszTargetName) Then
          Try : IO.File.Delete(f) : Catch : End Try
        End If
      End If
    Next
  End Sub

  Public Function GetShortcutTarget(ByVal pszShortcutPath As String) As String
    'путь к файлу, на кот. указывает ярлык
    Try
      Dim link As New ShellLink()
      DirectCast(link, IPersistFile).Load(pszShortcutPath, STGM_READ)
      Dim sb As New StringBuilder(MAX_PATH)
      Dim data As New WIN32_FIND_DATA
      DirectCast(link, IShellLinkW).GetPath(sb, sb.Capacity, data, 0)
      Return sb.ToString()
    Catch
      Return ""
    End Try
  End Function
...
Рейтинг: 0 / 0
20.06.2018, 22:00
    #39663284
Cat2
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Дмитрий77Я так понял, COM это единственный способ.
Нет.

Пример создания URL программы , вызываемой через clickonce c http://10.32.147.2/myprograms/PC_Registration/

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
string URL = @"[InternetShortcut]
URL=http://10.32.147.2/myprograms/PC_Registration/PC_Registration.application
IconIndex=0
IconFile=" + Application.ExecutablePath;

            string url = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\УВТ.url";
            if (!File.Exists(url))
                File.Delete(url);
            File.WriteAllText(url, URL);
...
Рейтинг: 0 / 0
21.06.2018, 01:33
    #39663335
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Cat2,

что-то мутное ты вещаешь.
Речь шла о ярлыке к исполняемому файлу (.lnk).
А твой код просто пишет какую-то извини муть просто в файл с расширением .URL
И к слову скажем созданный таким образом "URL-ярлык" ни на какой URL не указывает.

Но раз уж тему дернул да еще с URL-ярлыком,
задам вопрос, озадачился тут на днях, не то чтоб кровь из носу но интерес есть.

Есть .chm файл справки, в нем html страница.
Можно ли создать html-ссылку, которая запускает
Program Files\Proga\Proga.exe
щелчком по ней (от текущего юзера, не более того)

(вариант с выводом диалогов предупреждений безопасности и т.п. не катит).

Скажем так, в некогда анонсированной "новой" справочной системе (справка в Висте и Win7), на которую MS благополучно забил палку в Win8,
такие ссылки типа "Откройте proga" и при щелчке по оной proga благополучно запускается, имеют место быть (формат выяснять не пытался).
Но вот можно ли подобное сделать в старом добром .chm?
(который по сути был и остается единственным нормальным форматом файла справки - всякие там pdf и web-справки меня ИМХО как юзера бесят).
...
Рейтинг: 0 / 0
21.06.2018, 02:09
    #39663338
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Есть .chm файл справки, в нем html страница.
Можно ли создать html-ссылку, которая запускает
Program Files\Proga\Proga.exe
щелчком по ней (от текущего юзера, не более того)

(вариант с выводом диалогов предупреждений безопасности и т.п. не катит).
Ответ МОЖНО.
Код: vbnet
1.
file:///C:/Program Files/Proga/proga.exe


Запускает. Из .chm без всяких предупреждений и ругани. Ссылка в html-коде выглядит так: file:///C:/Program%20Files/Proga/proga.exe
Это хорошо.
Но мне нужно так.
Код: vbnet
1.
file:///%ProgramFiles%/Proga/proga.exe


В html получается: file:///%25Program%20Files%25/Proga/proga.exe
Не работает.

Поясню, на Win8/8.1/10 всегда C:/Program Files и первый вариант прокатит 100% , но предполагается совместная эксплуатация с Win7, где еще есть способ водрузить систему на диск D: не переобозванный в C: (ну, я по крайней мере так делал).
...
Рейтинг: 0 / 0
21.06.2018, 09:44
    #39663406
Ролг Хупин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Petro123Дмитрий77Инсталлятор утилиты с этими задачами нормально не справится, он только может установить ярлык один раз (при install), и удалить (при uninstall).ты че такой дремучий? Не видел окно Удаление или ИЗМЕНЕНИЕ программы в винде?
Там кнопка есть - восстановить.

А где такое "окно Удаление или ИЗМЕНЕНИЕ программы в винде " ?
...
Рейтинг: 0 / 0
21.06.2018, 10:08
    #39663426
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Ролг Хупин,
Ну Иван Иваныч! ))
Изменить в контексте было Восстановить и там галки по добавлению или удалению компонентов.
Проводник - кнопа Удалить или изменить программу.
Там подсказка: Для удаления программы выделите её и Щёлкните Заменить, Удалить, Восстановить.
Или в чем вопрос?
...
Рейтинг: 0 / 0
21.06.2018, 19:07
    #39663790
Дмитрий77
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Создать / удалить ярлык на рабочем столе программно.
Ролг Хупин,

Имелся ввиду стандартный апплет панели управления, где вы обычно удаляете приложения.
Но к вопросу программного создания/исследования ярлыка (shortcut) это никакого отношения не имеет.

Вопрос программного создания/исследования ярлыка мной решен на должном уровне, о чем отчитался выше.

Но все же интересует можно ли создать hyperlink с применением переменных
Так работает:
Код: vbnet
1.
file:///C:/Program Files/Proga/proga.exe

Так НЕ работает:
Код: vbnet
1.
file:///%ProgramFiles%/Proga/proga.exe


Т.е. типа "ярлык на запуск" в html-chm справке.

В вистовкой справке html-код такой штуки выглядит так:
Код: html
1.
2.
3.
4.
<p class="para"><a class="shellExecuteLink" 
href="shortcut:&quot;%25programfiles%25\windows mail\winmail.exe&quot;" title="Click to open Windows Mail">
<img src="mshelp://help/?id=Microsoft.Windows.Resources.ShellExecuteTopicIcon"> 
Click to open <span class="notLocalizable">Windows</span> Mail.</a></p>


Но она заумная, и будучи выдернутой из контекста не работает.
А стандартная file:/// не воспринимает %ProgramFiles% (во всяком случае при вызове из .chm)
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Создать / удалить ярлык на рабочем столе программно. / 22 сообщений из 22, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]