powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
12 сообщений из 12, страница 1 из 1
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638273
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я к чему спрашиваю.

Любой файл может быть автоматически отправлен на печать на заданный принтер вот так:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Private Sub CommandPrintTo_Click()
  Dim ret as long
  ret= ShellExecute(0, "printto", _
   Chr(34) & "C:\path\myfile.ext" & Chr(34), _
   Chr(34) & "MyPrinterName" & Chr(34), _
   "", SW_SHOWNORMAL)
   Debug.Print ret
   'ret>32 -успешно, ret<=32 -ошибка (коды возврата ShellExecute)
   'ret=31 -обычная ошибка, когда printto не определен
End Sub



Любой графический файл (bmp, jpg, png, tiff) на любой OS успешно печатается следующей командой:
Код: vbnet
1.
...\shell\printto\command=rundll32.exe C:\WINDOWS\system32\shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" "%3" "%4"



Задница состоит в том что это не всегда работает:
1) т.е. например пользователь поменял приложение по умолчанию
2) или например под MyUser как-то добился работы, а под System не хочет

У меня например на 7-ке ребенок наковырял, printto работает для jpg только под System, а под User err=31
А на 8-ке мне не удалось выбить правильную работу для того же jpg под System аккаунтом.
Ну т.е. бардак он и есть бардак.

В указанном случае jpg я могу вызвать rundll32.exe shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" в лоб, да хоть бы и через API:
15967000

Но есть случаи когда правильный printto кровь из носа необходим на системном уровне именно как verb="printto".
Т.е. к примеру
FaxDocument.ConnectedSubmit method
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Sub Main()
  Dim g_objFaxServer As New FAXCOMEXLib.FaxServer
  g_objFaxServer.Connect ("")
  Dim objFaxDocument As New FAXCOMEXLib.FaxDocument
  'We can create outgoing job from any printable file format, no dialog boxes
  objFaxDocument.Body = App.Path & "\test.jpg"
  objFaxDocument.Recipients.Add "74951234567", "74951234567"
  'Submit the document to the connected fax server
  objFaxDocument.ConnectedSubmit g_objFaxServer
End Sub

Здесь файл произвольного формата (jpg) передается методу ConnectedSubmit, который осуществляет печать jpg через "printto", как я расписал выше на принтер "Fax".
Но если verb="printto" испорчен, то будет ошибка, напрямую через API здесь не пихнешь никак (нужна родная автоматика).

Т.е.
1.
1) Есть экстеншн .jpg
2) Как мне программно узнать printto\command для него

2.
1) Есть экстеншн .jpg
2) Как мне программно задать printto\command для него

Ответ в msdn я искать пытался, но там похоже такой же бардак как и "в реестрах".
Четкой цепочки что и где надо прописать в реестре я не догоняю.
Идея состоит в том, чтобы перед выполнением printto задать его, а потом м.б. восстановить все "как было".
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638493
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77А на 8-ке мне не удалось выбить правильную работу для того же jpg под System аккаунтом.
Сделать удалось и проблему понял.
Проблема чисто восьмерошная.

Для старых систем достаточно:
Код: vbnet
1.
2.
3.
4.
5.
HKEY_CLASSES_ROOT\.jpg
default= jpegfile

HKEY_CLASSES_ROOT\jpegfile\shell\printto\command
default=rundll32.exe C:\WINDOWS\system32\shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" "%3" "%4"



Для Win 8.1 (и думаю для 8 тоже)
В реестре для тек. пользователя HKCU (а для System это HKEY_USERS\.DEFAULT\) должен быть ключ
Код: vbnet
1.
2.
3.
HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\.jpg
UserChoice=jpegfile
Hash=+37vx....(от чего зависит ХЗ)


Т.е. юзер должен ручками выбрать "Программу просмотра изображений через меню" в качестве дефолтной для данного типа (.jpg)
Причем если юзер=System, то это надо еще извернуться:
По умолчанию для System эти ключи не заданы и никакие printto соответственно не работают.

Код: vbnet
1.
psexec -i -s cmd.exe 'утилита Русиновича, запускает cmd под LocalSystem


после чего надо запустить из этой cmd какой-либо exe, кот. предоставит интерфейс проводника (сам explorer не катит).
Интерфейс этот есть в диалогах Open/Save (чтоб от имени System)
Оттуда через меню выбираем "Всегда открывать с помощью..."
После этого printto начинает работать из-под System (прописываются UserChoice+Hash).

Вот и вопрос реально ли эту ассоциацию (UserChoice) прописать программно.
Ручками-то считай нереально (то что я сделал это очень тяжело воспроизводимое извращение).
Но там hash -без него работать не будет (для каждого аккаунта и ассоциации он свой), у меня нет идей как его вычислить.
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638557
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77Но там hash -без него работать не будет (для каждого аккаунта и ассоциации он свой), у меня нет идей как его вычислить. http://yandex.ru/yandsearch?text=UserChoice hash&lr=213 ->
http://stackoverflow.com/questions/17946282/whats-the-hash-in-hkcu-software-microsoft-windows-currentversion-explorer-filee ->
http://stackoverflow.com/questions/16707684/how-to-set-default-browser-in-windows-8-using-c

привет от КО
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638735
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Antonariyпривет от КО
А кто такой КО? Расшифруй.
Antonariy http://stackoverflow.com/questions/17946282/whats-the-hash-in-hkcu-software-microsoft-windows-currentversion-explorer-filee ->
http://stackoverflow.com/questions/16707684/how-to-set-default-browser-in-windows-8-using-c
Я уже глядел эти ссылки.
Там говорится о DISM.exe которая экспотирует/импортирует дефолтные ассоциации для ext. Но дефолтные похоже не применяются к System аккаунту, по крайней мере настройка дефолтов через Win 8 GUI ничего для System не дает, надо указывать явно. А "явно" упирается в hash.
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638750
Фотография Antonariy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77А кто такой КО? Расшифруй.Капитан Очевидность.
Дмитрий77Но дефолтные похоже не применяются к System аккаунтуА если запустить DISM под System?
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638818
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AntonariyА если запустить DISM под System?
Не, DSIM похоже вообще не вариант.
Даже экспорт-импорт администратором ничего не меняет в тек. учетной записи.
http://www.outsidethebox.ms/14267/
авторВсе учетные записи, созданные после импорта параметров, получают заданные настройки ассоциаций файлов! Например, если в организации решили ассоциировать с изображениями, фото и видео традиционные приложения вместо современных, можно импортировать параметры в образ и развертывать его.

Я не случайно подчеркнул момент с новыми учетными записями, поскольку у имеющихся учетных записей не происходит переопределения уже заданных ассоциаций.
Причем применение походу происходит, когда юзер логинится в первый раз. А к System это неприменимо.

Это похоже нерешаемо. Если только узнать как генерируется hash.
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638874
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
8-ка вообще сильно недоработана.
Я вот другой баг кое-как осилил:
15989627
Программно удалять эти ключи не очень просто: надо уметь стать владельцем ветки реестра и назначить себе права на изменение ключей - коды нехилые получились.
Съедаемый TIFF (о котором я там говорю) в принципе я из любой графики делаю конвертацией, но мой TIFF фиговенький, потому что я не умею регулировать halftone - т.е. мое изображение получается темное и большое по объему данных. А вот "принтер" заточен под генерацию светлых, красивых и маловесомых тифов, поэтому objFaxDocument.ConnectedSubmit g_objFaxServer желательно подсовывать оригинальный jpg.
IFaxDocument::Body property
BodyWhen you send a fax from a client computer, the body has to be associated with an application that is installed on that computer, and the application has to support the PrintTo verb; otherwise, the fax will fail.
Посему желательно чтоб printto работал. Никакой клиент ручками это не настроит. Но при этом 90% с умным видом выберут "Run as NT Service".
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38638962
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О, есть хорошая новость.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.jpg
UserChoice=jpegfile
Hash= +37vxCpcfmE=

HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.tif
UserChoice=TIFImage.Document
Hash= vFzD+p5OrhY=



Я хочу сказать, что я проверил на 3-х компьютерах
1) Win 8.1 Enterprise x64
2) Win 8.1 Enterprise 32-бит
3) Win 8.1 x64 -ноут короче

Аккаунты на 2-х (x64) -один и тот же MS, на 32-бит -обычный другой, хотя о чем я
Одинаково: везде "System"!!!
Значения hash на всех 3-х компьютерах (и для jpg, и для tif) одинаковы.

Можно ли на это расчитывать?

Есть идеи, как они этот hash считают? (12 знаков)?


Считается наверно он из слов
SYSTEM TIFImage.Document
SYSTEM jpegfile

Меняться при всяких обновлениях наверно не должен, ключи реестра же не переписываются.
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38640351
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стабильностью Hash под SYSTEM аккаунтом (не меняется для разных машин) можно пользоваться.
Аккуратный фикс прилагаю (как вариант просто прикрепленный reg-файл).
HKEY_USERS, .DEFAULT -это как раз ветка реестра (настройки) учетной записи SYSTEM.
Я постарался аккуратно учесть всевозможные графические экстэншены для которых printto нормально поддерживается системой.
Фикс работает для Win 8.1 x64 и Win 8.1 32бит, по идее для Win 8 тоже должен работать (не проверял, а надо бы). Для <=Win7 не актуален.

Код: 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.
Private Function FixSingleSystemFileExtOnWin8(ByVal m_FileExt As String, _
 ByVal m_OpenWithProgids As String, ByVal m_ProgId As String, ByVal m_Hash As String) As Boolean
  Dim bResult As Boolean
  bResult = True
  
  bResult = bResult And CreateRegNoneValue(HKEY_USERS, _
   ".DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." & _
    m_FileExt & "\OpenWithProgids", m_OpenWithProgids, False)
  bResult = bResult And SetRegValue(HKEY_USERS, _
   ".DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." & _
   m_FileExt & "\UserChoice", "Hash", m_Hash, False)
  bResult = bResult And SetRegValue(HKEY_USERS, _
   ".DEFAULT\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." & _
   m_FileExt & "\UserChoice", "ProgId", m_ProgId, False)
  FixSingleSystemFileExtOnWin8 = bResult
End Function

Public Function FixSystemFileExtsOnWin8() As Boolean
  Dim bResult As Boolean
  bResult = True
  
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("bmp", "Paint.Picture", "Paint.Picture", "z79i+Bx/v9o=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("dib", "Paint.Picture", "Paint.Picture", "kMXrzo4z9XE=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("emf", "emffile", "emffile", "R0NdGDE22L8=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("gif", "giffile", "giffile", "dZh+jIWsxGY=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("jfif", "pjpegfile", "pjpegfile", "dU00qNUeYso=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("jpe", "jpegfile", "jpegfile", "UynoshOpfg8=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("jpeg", "jpegfile", "jpegfile", "tq2PMd1NSHU=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("jpg", "jpegfile", "jpegfile", "+37vxCpcfmE=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("jxr", "wdpfile", "wdpfile", "6LL9EOCzcPE=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("png", "pngfile", "pngfile", "TTV1utDZqrc=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("rle", "rlefile", "rlefile", "u0om9jVydUw=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("tif", "TIFImage.Document", "TIFImage.Document", "vFzD+p5OrhY=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("tiff", "TIFImage.Document", "TIFImage.Document", "PEKy96vwquk=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("wdp", "wdpfile", "wdpfile", "EP/9lD4HN78=")
  bResult = bResult And _
   FixSingleSystemFileExtOnWin8("wmf", "wmffile", "wmffile", "w/fsTCwPy5g=")
  
  FixSystemFileExtsOnWin8 = bResult
End Function
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38640367
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я тут немного поэкспериментировал и понял природу проблемы.
Сформулирую, пока свежо.

Под Win2012 R2 (серверный аналог 8.1), а также думаю под Win2012 (серверный аналог Win8) никаких фиксов не надо.
Нормально срабатывают дефолтные ассоциации (без UserChoice).
Дефолтные ассоциации на Win 8.1 указывают на новые Win8 GUI Apps, сырые и непродуманные, но "printto" они точно не поддерживают.
На серверах (2012R2) приложения магазина не устанавливаются и дефолтные ассоциации указывают ("по старинке") на корректные приложения рабочего стола, по этому все работает по дефолту.
На Win 8.1 дефолтные ассоциации срабатывают только для .emf , .wmf и .rle -для этих "хитрых форматов" разработчики нового Win8 GUI просто не добрались (или не додумались добраться).

Далее, я понимаю так.
Есть некие ОБЩИЕ ДЕФОЛТЫ . То что можно импортировать (поменять) через DISM.exe.
При создании новой учетной записи, ОБЩИЕ ДЕФОЛТЫ копируются в ДЕФОЛТЫ УЧЕТНОЙ ЗАПИСИ .
Но это касается только вновь создаваемых учеток.
Т.е. если я поменяю ОБЩИЕ ДЕФОЛТЫ через DISM.exe, то применить их к ДЕФОЛТАМ УЧЕТНОЙ ЗАПИСИ SYSTEM я не смогу, т.к. SYSTEM уже создана - при установке OS.
В этом проблема. По идее мне надо как-то поменять ДЕФОЛТЫ УЧЕТНОЙ ЗАПИСИ SYSTEM (уже созданной естественно).
Я не нашел, где они хранятся. В реестре похоже их нет.
Есть идеи?


Но фикс с UserChoice для System в принципе рабочий. Мой UserChoice полностью соответствует дефолтам серверной ОС (ссылается на стандартные приложения рабочего стола). Указывать приложения магазина в качестве дефолтных для System как минимум глупо, т.к. магазинные приложения под System не работают в принципе. Но именно это и сделано в Win8.1 (фактически без возможности исправить), думаю это ляп разработчиков OS.
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38640460
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77 В этом проблема. По идее мне надо как-то поменять ДЕФОЛТЫ УЧЕТНОЙ ЗАПИСИ SYSTEM (уже созданной естественно).
Я не нашел, где они хранятся. В реестре похоже их нет.
Есть идеи?

Прикол в том, что если для стандартной учетной записи поменять программу которой открывается файлы .ext любым из 3-х способов:
1) Через Win8 GUI: Settings -> Change PC Settings -> Search and Apps -> Defaults -> Choose Default Apps by the file type ->
2) Через панель управления: Programs -> Default Programs -> Make a file type always open in a specific program ->
3) Через меню файла: Open with -> Choose Default Program->
То во всем случаях создается ветка реестра
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ext
с "UserChoice"
А если эту ветку тупо удалить, то сделанный выбор сохраняется , т.е. он же и будет ДЕФОЛТ ТЕКУЩЕЙ НОРМАЛЬНОЙ УЧЕТНОЙ ЗАПИСИ . Т.е. оно этот выбор где-то еще держит кроме реестра.

А если то же самое проделать под System, доступен 3-й способ как я описал выше, то при удалении Explorer\FileExts\.ext
сделанный выбор НЕ СОХРАНЯЕТСЯ . Т.е. ассоциация перестает работать. Сделанный выбор держится только в "UserChoice" в реестре. А по "абсолютному дефолту" выбираются WIN8-GUI приложения.

Склоняюсь к мысли что мой фикс это вообще единственное что можно сделать (при наличии магазинных приложений).
...
Рейтинг: 0 / 0
А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
    #38640753
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чет меня заело на этой теме.
Неправильно я рассуждаю.

Правильно делать по-другому:
Берется ветка (на примере jpg)
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.jpg
Там смотрится параметр UserChoice
Он например будет "Microsoft.PhotoManager.Imagetype" (GUI8-Фотоальбом)
Идется в ветку
HKEY_CLASSES_ROOT\Microsoft.PhotoManager.Imagetype
И там смотрим чему равен
HKEY_CLASSES_ROOT\Microsoft.PhotoManager.Imagetype\shell\printto\command ->(default)
Для указанного случая verb отсутствует
Его можно туда дописать рабочей командой:
HKEY_CLASSES_ROOT\Microsoft.PhotoManager.imagetype\shell\printto\command
->(default)=rundll32.exe ...\shimgvw.dll,ImageView_PrintTo /pt "%1" "%2" "%3" "%4"
Это решает вопрос.

А вот если FileExts\.jpg отсутствует (как в случае System), то система ищет дефолт здесь:
HKEY_CLASSES_ROOT\.jpg\OpenWithProgids
А там для jpg 2 значения
1)jpegfile
2)Microsoft.PhotoManager.Imagetype
Вопрос: чем воспользуется система
Почему-то (ХЗ) она выберет 2)Microsoft.PhotoManager.Imagetype
Логично проверить оба варианта:
HKEY_CLASSES_ROOT\jpegfile\shell\printto\command ->(default)
HKEY_CLASSES_ROOT\Microsoft.PhotoManager.Imagetype\shell\printto\command ->(default)
и где отсутствует дописать рабочий printto

Короче, на базе этих знаний надо продумывать логику приложения.
По хорошему, при отсутствии printto я бы его прописывал перед печатью, а потом сразу же удалял.
Но сие возможно только при наличии прав админа, а у меня тенденция - делать под юзера.
Посему возможно делать только "в настройках". Потом фиг удалишь, а если юзер поменял дефолт то работать может перестать.
Далее, юзер может выбрать напр. IExplorer для открытия jpg.
IExplorer сам печатать по сути не умеет (на новых OS printto для него даже не прописываются).
Но printto для jpg никак не пойдет для html.
Можно конечно
printto\command->(default)=MyPrintManager "%1" "%2" "%3" "%4"
а MyPrintManager уже будет анализировать "%1" и запускать чего надо.

В общем это целое дело, кот. надо продумывать чтоб оно нормально работало и не сильно мусорило.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / А как прочитать/записать стандартный verb типа printto для заданного расширения напр. jpg
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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