Вы должны войти, чтобы создавать сообщения и темы.

Несколько разных вопросов по программированию на C#

◄Страница 2 из 3►

Сергей, написал Вам на почту.

В любой непонятной ситуации переходи на beta  © Win 10 Tweaker
Цитата: Сергей от 02.09.2022, 08:59

No_hammer, еще уточнение. Во всех старых проектах, которые были созданы еще в Visual Studio 2019 есть пункт Ссылки. Я перешел на VS2022 и тут продолжил, и в новых проектах новой версии IDE уже создаются проекты без Ссылок. А старые проекты, загруженные в VS2022 отображаются с пунктом Ссылки. Может подскажете, в чем тут дело?

Приветствую.
Это зависит не от студии, а от типа проекта. "Ссылка" есть у проектов .Net Framework, а у проектов .Net (5-6) слегка другая структура проекта и работа с зависимостью.

По видимому (из нагугленного за пару минут), System.Configuration.Install есть только для .Net Framework, а у вас видимо проект в .Net.

Adler, спасибо за ответ. Не подскажете, что мне сейчас сделать, чтобы подключить System.Configuration.Install к проекту в NET6? Или это не возможно?

Вероятно что никак. Разве что есть какой нибудь форк для .Net или альтернативное решение.
Как вариант, поищите на GitHub какие-то альтернативные решения.

Adler, спасибо большое за ответ. Конечно, странно это, но как уж есть. Я погуглил - тоже не нашел решения, хотя оно должно быть. Кстати, в саму службу System.Configuration.Install добавляется автоматически при добавлении инсталлера, как в уроке Хачатура. Я пытался к проекту добавить класс Установщика (Добавить компонент)  это тоже добавляет, но не в приложение WInForms, тут это выдает ошибку. Странно это, Microsoft намудрила

Хачатур, я ответил Вам на почте, нужны уточнения как быть

Спасибо, ссылку нашел, буду пробовать. Хотя, если это не займет Вашего времени надолго, можно пример на PowerShell? На случай, если что-то не сработает, как вот подключение System.Configuration.Install в версии до последней core работало, а в версиях NET5 и 6 уже не работает? Команды на PowerShell стопудово сработают

Сейчас поищу код для внешних HDD / SSD, но попутно в тему даю пример того, что как код будет выглядеть на C# и как на PowerShell.
Коды ниже – это для флешек, сразу говорю, для внешних накопителей и жёстких дисков не подойдёт.

C#

Создаём в проекте EjectUSB и добавляем туда это:

using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace НазваниеПрограммы
{
    public class EjectUSB
    {
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern IntPtr CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        uint dwShareMode,
        IntPtr SecurityAttributes,
        uint dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile
        );

        [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
        private static extern bool DeviceIoControl(
            IntPtr hDevice,
            uint dwIoControlCode,
            IntPtr lpInBuffer,
            uint nInBufferSize,
            IntPtr lpOutBuffer,
            uint nOutBufferSize,
            out uint lpBytesReturned,
            IntPtr lpOverlapped
        );

        [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)]
        private static extern bool DeviceIoControl(
            IntPtr hDevice,
            uint dwIoControlCode,
            byte[] lpInBuffer,
            uint nInBufferSize,
            IntPtr lpOutBuffer,
            uint nOutBufferSize,
            out uint lpBytesReturned,
            IntPtr lpOverlapped
        );

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr hObject);

        private IntPtr handle = IntPtr.Zero;

        const uint GENERIC_READ = 0x80000000;
        const uint GENERIC_WRITE = 0x40000000;
        const int FILE_SHARE_READ = 0x1;
        const int FILE_SHARE_WRITE = 0x2;
        const int FSCTL_LOCK_VOLUME = 0x00090018;
        const int FSCTL_DISMOUNT_VOLUME = 0x00090020;
        const int IOCTL_STORAGE_EJECT_MEDIA = 0x2D4808;
        const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x002D4804;

        public IntPtr USBEject(string driveLetter)
        {
            string filename = @"\\.\" + driveLetter[0] + ":";
            return CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, 0x3, 0, IntPtr.Zero);
        }

        public bool Eject(IntPtr handle)
        {
            bool result = false;

            if (LockVolume(handle) && DismountVolume(handle))
            {
                PreventRemovalOfVolume(handle, false);
                result = AutoEjectVolume(handle);
            }
            CloseHandle(handle);
            return result;
        }

        private bool LockVolume(IntPtr handle)
        {
            uint byteReturned;

            for (int i = 0; i < 10; i++)
            {
                if (DeviceIoControl(handle, FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero))
                {
                    System.Windows.Forms.MessageBox.Show("Lock success!");
                    return true;
                }
                Thread.Sleep(500);
            }
            return false;
        }

        private bool PreventRemovalOfVolume(IntPtr handle, bool prevent)
        {
            byte[] buf = new byte[1];
            uint retVal;

            buf[0] = (prevent) ? (byte)1 : (byte)0;
            return DeviceIoControl(handle, IOCTL_STORAGE_MEDIA_REMOVAL, buf, 1, IntPtr.Zero, 0, out retVal, IntPtr.Zero);
        }

        private bool DismountVolume(IntPtr handle)
        {
            uint byteReturned;
            return DeviceIoControl(handle, FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
        }

        private bool AutoEjectVolume(IntPtr handle)
        {
            uint byteReturned;
            return DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, out byteReturned, IntPtr.Zero);
        }

        private bool CloseVolume(IntPtr handle)
        {
            return CloseHandle(handle);
        }
    }
}

И вызываем вот так:

EjectUSB eject = new EjectUSB();
eject.Eject(eject.USBEject("G:"));


PowerShell:

Скопировано(New-Object -comObject Shell.Application).NameSpace(17).ParseName('G:\').InvokeVerb('Eject')

В любой непонятной ситуации переходи на beta  © Win 10 Tweaker

А вот и простенький PowerShell, чтобы извлечь внешний HDD / SSD

Скрипт.ps1

$vol = get-wmiobject -Class Win32_Volume | where{$_.Name -eq 'G:\'}
$vol.DriveLetter = $null
$vol.Put()
$vol.Dismount($false, $false)


Само собой букву диска СкопированоG:\ нужно менять на своё.

В любой непонятной ситуации переходи на beta  © Win 10 Tweaker

Хачатур, большое Вам спасибо, буду "курить" Ваши инструкции. Это очень замечательно, эмоционально добавилось желания делать все ка надо. ))

Лайкнул XpucT
XpucT

Приветствую🖐 .

Цитата: Adler от 02.09.2022, 13:06

Вероятно что никак. Разве что есть какой нибудь форк для .Net или альтернативное решение.
Как вариант, поищите на GitHub какие-то альтернативные решения.

Я ранее задался вопросом, о том что как решается задачи с развертыванием приложений на С#. И есть ли готовые инструменты для этого? Первое что выдает Гугл 🙂 это как раз "System.Configuration.Install". Первое что я понял, этот API отсутствует в NetCore(в то время я начинал изучать программирование с 3.1), как и некоторые другие API. Образовался следующий вопрос, а они(Microsoft), что их выбросили что ли эти API, когда отказались развивать Net framework? Так вот оказывается что нет. Насколько я понимаю, они эти API упаковали в отдельный Nuget пакет который связан с Windows. Так как они(Microsoft) не хотели оставлять в кроссплатформенной реализации ядра .NET, пул API , который не является кроссплатформенным. Собственно сам пакет Nuget + немного информации и ещё чуть-чуть. Что интересно, что по идеи есть и обратный пакет, который должен вроде как позволять дергать из Net framework API .NET . Вот ссылка на Nuget . Что касается вопроса развертывания приложения, я предлагаю обратить внимание на WiX Toolset . Сам по себе это сложный в освоении инструмент. Основанный на XML описании, инсталлятор .msi, и вроде как  использовался Microsoft для установки Microsoft Оffice. Есть его C# обёртка в виде пакета Wixsharp . Надеюсь информация была полезна. ✨

 

P.S Эту информацию нужно проверить. Ничего из этого я не успел протестировать. Так что как говорится кому интересно, проверяйте руками ✌

Лайкнули XpucT, Adler и Владислав
XpucTAdlerВладислав

Viktor, большое Вам спасибо! Очень, конечно очень полезная информация, я потестирую обязательно! Спасибо еще раз!

Viktor, по сегодняшнему Вашему посту уточняю, что в пакете Microsoft.Windows.Compatibility не содержится System.Configuration.Install. После добавления пакета к проекту по прежнему не распознает using с этим пространством имен. Самое обидное, что на MSDN ничего не сказано про это пространство в net5 и 6, просто что оно там есть и все. Можно типа использовать, как любое другое доступное пространство, типа System.

Привет 🖐 Сергей.  Да действительно поторопился с ответом,🤷  но с другой стороны стороны, если отправить в поисковую строку пакетов Nuget System.Configuration.Install, можно обнаружить пакет Core.System.Configuration.Install. Возможно это то, что вас интересует. 🔎

◄Страница 2 из 3►