powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Установка "компонента Windows"/"Роли на сервере" программно
3 сообщений из 3, страница 1 из 1
Установка "компонента Windows"/"Роли на сервере" программно
    #39415144
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если делать ручками:
Панель управления -> Программы -> Включение и отключение компонентов Windows

В окне Компоненты Windows:
Нашел компонент, проверил есть ли галка
Если нет, поставил нажал OK.
Ну и ждем, бывает долго, пока установится.

На Win сервере речь может идти об установки "роли сервера".
При этом также бывает нужно установить компонент(ы) от которого работоспособность устанавливаемого зависит.

Мне это надо сделать программно, желательно с "progress", ибо процесс как правило не быстрый.

Нечто подобное делал очень давно, но дальше XP/2003 метод никогда не работал
т.е. не актуально.
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
        Try
          Using file As System.IO.StreamWriter = _
           New System.IO.StreamWriter(IO.Path.Combine(temp_path, "ocm.txt"), _
           False, System.Text.Encoding.Default)
            file.WriteLine("[components]")
            file.WriteLine("<имя_компонента>=On")
          End Using
        Catch
        End Try
        ShellAndContinueNet("sysocmgr /i:" & IO.Path.Combine(windows_path, "inf\sysoc.inf") & " /u:" _
         & IO.Path.Combine(temp_path, "ocm.txt") & " /r", AppWinStyle.Hide)
        Try : IO.File.Delete(IO.Path.Combine(temp_path, "ocm.txt")) : Catch : End Try


(код вызывает системные окна, как бы я это делал из панели управления ручками и устанавливает <имя_компонента>.

Вот надо сие сделать для современных OS (начать хотя б с клиентской Win10, для сервера требуются "роли").
Да и лучше чтоб не через сомнительную cmd, хотя и это вариант.
Пока погуглив нашел:

Deployment Image Servicing and Management (DISM) API

cmd-вариант:
Включение и отключение компонентов Windows с помощью DISM

Оно?
Или есть еще какие варианты?
Что .Net говорит на эту тему?

Не повредил бы хороший пример без излишеств и лишних опций.
Т.е. надо сделать ровно то что я описал: "поставить галку на компонент" и "нажать OK", без указания образов, прообразов, хранилищ и т.п.
Если система захочет установочный CD, DVD, Windows Update, пусть сама это запрашивает и сама туда идет если сочтет нужным и т.д.
...
Рейтинг: 0 / 0
Установка "компонента Windows"/"Роли на сервере" программно
    #39416566
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну с DISM я в общем-то разобрался.

Код: 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.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
Imports System.Runtime.InteropServices

Module m_DismApi

  Public sessionOnline_Dism As Integer = DISM_SESSION_DEFAULT

  Private Const S_OK = 0

  ' DISM API Constants
  Public Const DISM_ONLINE_IMAGE As String = "DISM_{53BFAE52-B167-4E2F-A258-0A37B57FF845}"
  Public Const DISM_SESSION_DEFAULT As Integer = 0

  ' DISM API Enumerations
  Public Enum DismLogLevel
    DismLogErrors = 0
    DismLogErrorsWarnings = 1
    DismLogErrorsWarningsInfo = 2
  End Enum

  Public Enum DismPackageFeatureState
    DismStateNotPresent = 0
    DismStateUninstallPending = 1
    DismStateStaged = 2
    DismStateRemoved = 3
    DismStateInstalled = 4
    DismStateInstallPending = 5
    DismStateSuperseded = 6
    DismStatePartiallyInstalled = 7
  End Enum

  Public Enum DismPackageIdentifier
    DismPackageNone = 0
    DismPackageName = 1
    DismPackagePath = 2
  End Enum

  Public Enum DismRestartType
    DismRestartNo = 0
    DismRestartPossible = 1
    DismRestartRequired = 2
  End Enum

  ' DISM API Structures
  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode, Pack:=1)>
  Public Structure DismFeature
    Dim FeatureName As String
    Dim State As DismPackageFeatureState
  End Structure

  <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode, Pack:=1)>
  Public Structure DismFeatureInfo
    Dim FeatureName As String
    Dim State As DismPackageFeatureState
    Dim DisplayName As String
    Dim Description As String
    Dim RestartRequired As DismRestartType
    Dim CustomProperty As IntPtr
    Dim CustomPropertyCount As Integer
  End Structure

  ' DISM API Functions
  Public Declare Function DismCloseSession Lib "DismAPI" (ByVal Session As Integer) As Integer
  Public Declare Function DismDelete Lib "DismAPI" (ByVal DismStructure As IntPtr) As Integer
  Public Declare Unicode Function DismDisableFeature Lib "DismAPI" _
   (ByVal Session As Integer, ByVal FeatureName As String, ByVal PackageName As String, _
   ByVal RemovePayload As Boolean, ByVal CancelEvent As IntPtr, _
   ByVal Progress As DismProgressCallback, ByVal UserData As Object) As Integer
  Public Declare Unicode Function DismEnableFeature Lib "DismAPI" _
   (ByVal Session As Integer, ByVal FeatureName As String, ByVal Identifier As String, _
   ByVal PackageIdentifier As DismPackageIdentifier, ByVal LimitAccess As Boolean, _
   ByVal SourcePaths As String(), ByVal SourcePathCount As Integer, _
   ByVal EnableAll As Boolean, ByVal CancelEvent As IntPtr, _
   ByVal Progress As DismProgressCallback, ByVal UserData As Object) As Integer
  Public Declare Unicode Function DismGetFeatureInfo Lib "DismAPI" _
   (ByVal Session As Integer, ByVal FeatureName As String, ByVal Identifier As String, _
   ByVal PackageIdentifier As DismPackageIdentifier, ByRef FeatureInfo As IntPtr) As Integer
  Public Declare Unicode Function DismGetFeatureParent Lib "DismAPI" _
   (ByVal Session As Integer, ByVal FeatureName As String, ByVal Identifier As String, _
   ByVal PackageIdentifier As DismPackageIdentifier, ByRef Feature As IntPtr, ByRef Count As Integer) As Integer
  Public Declare Unicode Function DismGetFeatures Lib "DismAPI" _
   (ByVal Session As Integer, ByVal Identifier As String, _
   ByVal PackageIdentifier As DismPackageIdentifier, ByRef Feature As IntPtr, ByRef Count As Integer) As Integer
  Public Declare Unicode Function DismInitialize Lib "DismAPI" _
   (ByVal LogLevel As DismLogLevel, Optional ByVal LogFilePath As String = vbNullString, _
   Optional ByVal ScratchDirectory As String = vbNullString) As Integer
  Public Declare Unicode Function DismOpenSession Lib "DismAPI" _
   (ByVal ImagePath As String, ByVal WindowsDirectory As String, _
   ByVal SystemDrive As String, ByRef Session As Integer) As Integer
  Public Declare Function DismShutdown Lib "DismAPI" () As Integer

  ' A client-defined callback function that DISM API uses to report progress on time-consuming operations.
  Public Delegate Sub DismProgressCallback _
   (ByVal Current As Integer, ByVal Total As Integer, ByVal UserData As Object)

  Private Function FAILED(ByVal hr As Integer) As Boolean
    Return (hr < 0)
  End Function

  Public Function Dism_Start(ByRef err_text As String, _
   Optional ByVal LogFilePath As String = vbNullString, _
   Optional ByVal LogLevel As DismLogLevel = DismLogLevel.DismLogErrors) As Integer

    ' т.к. мы не закрываем sessionOnline_Dism, которую храним глобально и не выгружаем Dism
    ' необходимо вызвать Dism_Stop (в конце всех действий, чтоб не переоткрывать по 10 раз, тем более загрузка/выгрузка это ощутимое время)

    Dim hr As Integer = S_OK

    ' Initialize the API
    hr = DismInitialize(LogLevel, LogFilePath)
    If FAILED(hr) Then
      err_text = "DismInitialize Failed. Error " & RaiseAPIErrorByNumber(hr)
      Debug.Print(err_text)
      GoTo Cleanup
    End If

    ' Open a session against the running operating system (online image) 
    hr = DismOpenSession(DISM_ONLINE_IMAGE, vbNullString, vbNullString, sessionOnline_Dism)
    If FAILED(hr) Then
      err_text = "DismOpenSession Failed. Error " & RaiseAPIErrorByNumber(hr)
      Debug.Print(err_text)
      GoTo Cleanup
    End If

Cleanup:
    ' всю очистку делаем в Dism_Stop
    Return hr
  End Function

  Public Sub Dism_Stop()
    Dim hrLocal As Integer = S_OK

    ' Close the DismSession to free up resources tied to the online session
    hrLocal = DismCloseSession(sessionOnline_Dism)
    sessionOnline_Dism = DISM_SESSION_DEFAULT
    If FAILED(hrLocal) Then
      Debug.Print("DismCloseSession Failed. Error " & RaiseAPIErrorByNumber(hrLocal))
    End If

    ' Shutdown the DISM API to free up remaining resources
    hrLocal = DismShutdown()
    If FAILED(hrLocal) Then
      Debug.Print("DismShutdown Failed. Error " & RaiseAPIErrorByNumber(hrLocal))
    End If
  End Sub

  Public Function Dism_EnableWindowsFeature(ByRef err_text As String, _
   ByVal FeatureName As String, Optional ByVal bEnable As Boolean = True, _
   Optional ByVal ProgressCallback As DismProgressCallback = Nothing, _
   Optional ByVal UserData As Object = Nothing) As Integer

    Dim hr As Integer = S_OK
    Dim hrLocal As Integer = S_OK

    If bEnable Then
      ' Enable feature
      hr = DismEnableFeature(sessionOnline_Dism, FeatureName, vbNullString, _
       DismPackageIdentifier.DismPackageNone, False, Nothing, 0, True, IntPtr.Zero, _
       ProgressCallback, UserData)
      If FAILED(hr) Then
        err_text = "DismEnableFeature Failed. Error " & RaiseAPIErrorByNumber(hr)
        Debug.Print(err_text)
        GoTo Cleanup
      End If
    Else
      ' Disable feature
      hr = DismDisableFeature(sessionOnline_Dism, FeatureName, vbNullString, _
       False, IntPtr.Zero, ProgressCallback, UserData)
      If FAILED(hr) Then
        err_text = "DismDisableFeature Failed. Error " & RaiseAPIErrorByNumber(hr)
        Debug.Print(err_text)
        GoTo Cleanup
      End If
    End If

Cleanup:

    Return hr
  End Function

  Public Function Dism_GetWindowsFeatures(ByRef err_text As String, _
   ByRef Features() As DismFeature) As Integer

    Dim hr As Integer = S_OK
    Dim hrLocal As Integer = S_OK

    ' Get a list of all of the features
    Dim pFeatures As IntPtr = IntPtr.Zero
    Dim uiCount As Integer = 0
    hr = DismGetFeatures(sessionOnline_Dism, vbNullString, DismPackageIdentifier.DismPackageNone, pFeatures, uiCount)
    If FAILED(hr) Then
      err_text = "DismGetFeatures Failed. Error " & RaiseAPIErrorByNumber(hr)
      Debug.Print(err_text)
      GoTo Cleanup
    End If

    If uiCount = 0 Then GoTo Cleanup 'нет ни одной Feature

    ReDim Features(0 To uiCount - 1)
    If Is64bitProcess() Then
      For i As Integer = 0 To uiCount - 1
        Features(i) = CType(Marshal.PtrToStructure(New IntPtr(pFeatures.ToInt64 + i * Marshal.SizeOf(Features(0))), GetType(DismFeature)), DismFeature)
      Next
    Else
      For i As Integer = 0 To uiCount - 1
        Features(i) = CType(Marshal.PtrToStructure(New IntPtr(pFeatures.ToInt32 + i * Marshal.SizeOf(Features(0))), GetType(DismFeature)), DismFeature)
      Next
    End If

Cleanup:
    ' Delete the memory associated with the objects that were returned
    hrLocal = DismDelete(pFeatures)
    If FAILED(hrLocal) Then
      Debug.Print("DismDelete Failed. Error " & RaiseAPIErrorByNumber(hrLocal))
    End If

    Return hr
  End Function

  Public Function Dism_GetWindowsFeatureInfo(ByRef err_text As String, _
   ByVal FeatureName As String, ByRef FeatureInfo As DismFeatureInfo) As Integer

    Dim hr As Integer = S_OK
    Dim hrLocal As Integer = S_OK

    ' Get the feature info for FeatureName
    Dim pFeatureInfo As IntPtr = IntPtr.Zero
    hr = DismGetFeatureInfo(sessionOnline_Dism, FeatureName, vbNullString, _
     DismPackageIdentifier.DismPackageNone, pFeatureInfo)
    If FAILED(hr) Then
      err_text = "DismGetFeatureInfo Failed. Error " & RaiseAPIErrorByNumber(hr)
      Debug.Print(err_text)
      GoTo Cleanup
    End If
    FeatureInfo = CType(Marshal.PtrToStructure(pFeatureInfo, GetType(DismFeatureInfo)), DismFeatureInfo)

Cleanup:
    ' Delete the memory associated with the objects that were returned
    hrLocal = DismDelete(pFeatureInfo)
    If FAILED(hrLocal) Then
      Debug.Print("DismDelete Failed. Error " & RaiseAPIErrorByNumber(hrLocal))
    End If

    Return hr
  End Function

  Public Function Dism_GetWindowsFeatureParent(ByRef err_text As String, _
   ByVal FeatureName As String, ByRef Features() As DismFeature) As Integer

    Dim hr As Integer = S_OK
    Dim hrLocal As Integer = S_OK

    ' Get a list of parent features
    Dim pFeatures As IntPtr = IntPtr.Zero
    Dim uiCount As Integer = 0
    hr = DismGetFeatureParent(sessionOnline_Dism, FeatureName, vbNullString, DismPackageIdentifier.DismPackageNone, _
     pFeatures, uiCount)
    If FAILED(hr) Then
      err_text = "DismGetFeatures Failed. Error " & RaiseAPIErrorByNumber(hr)
      Debug.Print(err_text)
      GoTo Cleanup
    End If

    If uiCount = 0 Then GoTo Cleanup 'нет ни одной Feature

    ReDim Features(0 To uiCount - 1)
    If Is64bitProcess() Then
      For i As Integer = 0 To uiCount - 1
        Features(i) = CType(Marshal.PtrToStructure(New IntPtr(pFeatures.ToInt64 + i * Marshal.SizeOf(Features(0))), GetType(DismFeature)), DismFeature)
      Next
    Else
      For i As Integer = 0 To uiCount - 1
        Features(i) = CType(Marshal.PtrToStructure(New IntPtr(pFeatures.ToInt32 + i * Marshal.SizeOf(Features(0))), GetType(DismFeature)), DismFeature)
      Next
    End If

Cleanup:
    ' Delete the memory associated with the objects that were returned
    hrLocal = DismDelete(pFeatures)
    If FAILED(hrLocal) Then
      Debug.Print("DismDelete Failed. Error " & RaiseAPIErrorByNumber(hrLocal))
    End If

    Return hr
  End Function

End Module



+ полный тест-проект целиком в приложении (с выводом всех фич в комбобокс, опроса их по одной и возможности установки/удаления любой). Даб не быть голословным.

Есть ньюанс: на x64 надо компилировать строго в 64-битный код (32 битный exe-шник работать не будет).


Но эта штука штатно работает только на Win8.1/10 (вероятно и на 8=) и на серверах (фичи и роли). Пробовал на 2012R2, очевидно будет и на 2016-м.

А вот с Win7 задница. Во первых DISM там штатно то ли отсутсвует, то ли установлен черт знает где (у меня есть в System32/CompatTel но не уверен о его родном происхождении). У кого есть семерка, не глянете?
Путь этот конечно можно дописать через SetEnvironmentVariable("Path", varValue).
Но есть жирное НО. На Win7 не работает ключ /Enable-Feature /All при установке фичи (ни через API ни через Dism.exe -87 ошибка). Причем установка ADK как MS советует проблемы с /All не решает. Можно конечно извратиться, последовательно найти все ParentFeatures и доустановить поотдельности, но с учетом количества проблем стоит ли эту технику вообще иметь ввиду для 7-ки.
...
Рейтинг: 0 / 0
Установка "компонента Windows"/"Роли на сервере" программно
    #39417511
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коль уж тему начал.
Но есть жирное НО. На Win7 не работает ключ /Enable-Feature /All при установке фичи (ни через API ни через Dism.exe -87 ошибка). Причем установка ADK как MS советует проблемы с /All не решает. Можно конечно извратиться, последовательно найти все ParentFeatures и доустановить поотдельности, но с учетом количества проблем стоит ли эту технику вообще иметь ввиду для 7-ки.
Осилил я этот момент. На Win7 рекурсивно вычисляем все неустановленные Parent фичи, и засовываем в строку через ";".
Не знаю насколько это важно, но Parent всегда раньше чем Child.
Код: 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.
  Public Function Dism_GetWindowsFeatureFullList(ByRef err_text As String, ByVal FeatureName As String, _
   ByRef FeatureList As String, Optional ByVal bNotInstalledOnly As Boolean = False) As Integer

    'Возвращает строку фич FeatureList через ';', включая FeatureName и все Parent, причем Parent всегда стоит перед Child
    'bNotInstalledOnly -добавлять в строку только те фичи, которые еще не установлены

    Dim hr As Integer = S_OK

    Dim FeatureInfo As New DismFeatureInfo
    hr = Dism_GetWindowsFeatureInfo(err_text, FeatureName, FeatureInfo)
    If FAILED(hr) = False Then
      Dim Features() As DismFeature = Nothing
      hr = Dism_GetWindowsFeatureParentList(err_text, FeatureName, Features)
      If FAILED(hr) Then Return hr 'ошибок не допускаем
      ' теперь добавляем себя в самый конец
      If IsNothing(Features) Then
        ReDim Features(0 To 0)
        Debug.Print(FeatureInfo.FeatureName)
        Features(0).FeatureName = FeatureInfo.FeatureName
        Features(0).State = FeatureInfo.State
      Else
        For j As Integer = 0 To UBound(Features)
          If Features(j).FeatureName = FeatureInfo.FeatureName Then 'фича уже есть ранее в списке(теоретически может быть, хотя вряд ли)
            Debug.Print(FeatureInfo.FeatureName & " (skipped)")
            GoTo NoNeedToAdd
          End If
        Next
        ReDim Preserve Features(0 To UBound(Features) + 1)
        Debug.Print(FeatureInfo.FeatureName)
        Features(UBound(Features)).FeatureName = FeatureInfo.FeatureName
        Features(UBound(Features)).State = FeatureInfo.State
NoNeedToAdd:
      End If
      ' теперь составляем строку фич через ';', причем Parent всегда оказывается впереди child
      Debug.Print("Final list of features:")
      For i = 0 To UBound(Features)
        If bNotInstalledOnly AndAlso Features(i).State = DismPackageFeatureState.DismStateInstalled Then
          Debug.Print(Features(i).FeatureName & " (already installed)")
        Else
          Debug.Print(Features(i).FeatureName & " (OK)")
          FeatureList = AddUsingDelimiter(Features(i).FeatureName, FeatureList, ";")
        End If
      Next
    End If

    Return hr
  End Function

  Public Function Dism_GetWindowsFeatureParentList(ByRef err_text As String, ByVal FeatureName As String, _
   ByRef Features() As DismFeature) As Integer

    'Возвращает массив Features() всех Parent, Parent всегда стоит перед Child, работает рекурсивно
    'Одна и та же фича не может быть добавлена более одного раза

    Dim hr As Integer = S_OK

    Dim FeaturesParent() As DismFeature = Nothing
    hr = Dism_GetWindowsFeatureParent(err_text, FeatureName, FeaturesParent)
    If FAILED(hr) = False Then
      If IsNothing(FeaturesParent) = False Then
        For i As Integer = 0 To UBound(FeaturesParent)
          'сначала добавится родитель
          hr = Dism_GetWindowsFeatureParentList(err_text, FeaturesParent(i).FeatureName, Features)
          If FAILED(hr) Then Return hr 'ошибок не допускаем
          'потом добавляем себя (т.е. родитель в списке всегда стоит раньше child)
          If IsNothing(Features) Then
            ReDim Features(0 To 0)
            Debug.Print(FeaturesParent(i).FeatureName)
            Features(0) = FeaturesParent(i)
          Else
            For j As Integer = 0 To UBound(Features)
              If Features(j).FeatureName = FeaturesParent(i).FeatureName Then 'фича уже есть ранее в списке
                Debug.Print(FeaturesParent(i).FeatureName & " (skipped)")
                GoTo NoNeedToAdd
              End If
            Next
            ReDim Preserve Features(0 To UBound(Features) + 1)
            Debug.Print(FeaturesParent(i).FeatureName)
            Features(UBound(Features)) = FeaturesParent(i)
NoNeedToAdd:
          End If
        Next
      End If
    End If

    Return hr
  End Function

End Module


Строку эту подсовываем в DismEnableFeature function без многократных вызовов (To enable more than one feature, separate each feature name with a semicolon.)
Параметр EnableAll ставим строго в False (Note LimitAccess, SourcePaths, SourcePathCount, and EnableAll are only supported on Windows 8 and Windows Server 2012.) Собственно в MSDN все сказано.

И походу DISM на Win7 таки уже родной tool (pkgmgr рисует Dism-овский лог).
Хотя надо делать SetEnvironmentVariable (+ "System32/CompatTel" в 'Path'), иначе dismapi.dll не найдет.

Ну вот собственно все. Тест-проект с учетом сказанного прикладываю.
Там подправил еще несколько глюков: 1) Видимо не стоит передавать Object в API вместо IntPtr 2) Callback имеет свойство частенько глючить(во всяком случае на Win7 x86, на новых x64 не замечено), это когда Current>Total, Value>Max в приаттаченном ProgressBar и краш обеспечен, это надо обрабатывать 3) Любая ошибка >0 в Dism-функциях не ошибка, всегда надо проверять на FAILED (т.е. <0) а не S_OK.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Установка "компонента Windows"/"Роли на сервере" программно
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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