SetWindowLong & SetLayeredWindowAttributes не работает на другом пользователе C#

Целью является

Я хочу изменить непрозрачность некоторых приложений (целей), работающих на Win XP.

Ситуация

  • Я вошел в Win XP как учетная запись пользователя AD (активный каталог) (some-domain\username)
  • большинство целевых приложений запускаются как локальный пользователь или другой пользователь рекламы

Проблема и мой вопрос

SetWindowLong & SetLayeredWindowAttributes не работает с целевым приложением, работающим под учетной записью другого пользователя. Но он работает на целевом приложении, которое работает под той же учетной записью пользователя (зарегистрированной учетной записью пользователя)

Как изменить прозрачность окна другого приложения, которая запускается под другой учетной записью пользователя?

Приложение для иллюстрации

Это приложение в форме выигрыша (назовем его OpaciToggler.exe). У меня есть 2 кнопки (btnRunSomething и btnHideThatThing) и текстовое поле (txtPid). Так просто.

Когда я щелкаю btnRunSomething, он запускает.exe от имени другого пользователя. Все подробности в app.config. В этом случае я запускаю это приложение (OpaciToggler.exe, из debug/bin) от имени другого пользователя (localComputer \ user1)

TxtPid для ручного ввода pid. Обычно я открываю диспетчер задач (win > run > taskmgr) и нахожу pid (на вкладке процесса) любого приложения (цели), с которым я хочу протестировать, а затем введите его здесь.

Когда я нажимаю btnHideThatThing, он переключает непрозрачность целевого приложения (чей pid в txtPid)

Код C#

Вот как я называю целевое приложение.

    private void btnRunSomething_Click(object sender, EventArgs e)
    {
        System.Diagnostics.Process p = new System.Diagnostics.Process();

        p.StartInfo.Domain = ConfigurationManager.AppSettings["StartInfoDomain"]; 
        p.StartInfo.UserName = ConfigurationManager.AppSettings["StartInfoUserName"]; 

        p.StartInfo.FileName = ConfigurationManager.AppSettings["StartInfoFileName"];
        p.StartInfo.Arguments = ConfigurationManager.AppSettings["StartInfoArguments"];

        System.String rawPassword = ConfigurationManager.AppSettings["StartInfoPassword"];
        System.Security.SecureString encPassword = new System.Security.SecureString();

        foreach (System.Char c in rawPassword)
        {
            encPassword.AppendChar(c);
        }

        p.StartInfo.Password = encPassword;
        p.StartInfo.UseShellExecute = false;

        p.Start();
    }

Вот как я пытаюсь назвать непрозрачность

    private void btnHideThatThing_Click(object sender, EventArgs e)
    {
        // manual input pid 
        int pid = int.Parse(txtPid.Text);
        IntPtr mwh = Process.GetProcessById(pid).MainWindowHandle;
        doHideThing(mwh);  

        // doHideThing(Process.GetProcessById(int.Parse(txtPid.Text)).MainWindowHandle);
    }

Спрятать метод

    private void doHideThing(IntPtr hndl)
    {
        SetWindowLong(hndl, GWL_EXSTYLE, GetWindowLong(hndl, GWL_EXSTYLE) ^ WS_EX_LAYERED).ToString();
        // _whatNow = Marshal.GetLastWin32Error();

        SetLayeredWindowAttributes(hndl, 0, (255 * 20) / 100, LWA_ALPHA).ToString();
        // _whatNow = Marshal.GetLastWin32Error();

        RedrawWindow(hndl, IntPtr.Zero, IntPtr.Zero,
            RedrawWindowFlags.Erase | RedrawWindowFlags.Invalidate |
            RedrawWindowFlags.Frame | RedrawWindowFlags.AllChildren);            
    }

другие коды

    private const int GWL_EXSTYLE = -20;
    private const int GWL_STYLE = -16;
    private const int WS_EX_LAYERED = 0x80000;
    private const int LWA_ALPHA = 0x2;
    private const int LWA_COLORKEY = 0x1;

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32.dll", SetLastError = true)]
    static extern bool RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, RedrawWindowFlags flags);

Перечисление RedrawWindowFlags (я не помню, где это взять)

[Flags()]
enum RedrawWindowFlags : uint
{
    /// <summary>
    /// Invalidates the rectangle or region that you specify in lprcUpdate or hrgnUpdate.
    /// You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_INVALIDATE invalidates the entire window.
    /// </summary>
    Invalidate = 0x1,

    /// <summary>Causes the OS to post a WM_PAINT message to the window regardless of whether a portion of the window is invalid.</summary>
    InternalPaint = 0x2,

    /// <summary>
    /// Causes the window to receive a WM_ERASEBKGND message when the window is repainted.
    /// Specify this value in combination with the RDW_INVALIDATE value; otherwise, RDW_ERASE has no effect.
    /// </summary>
    Erase = 0x4,

    /// <summary>
    /// Validates the rectangle or region that you specify in lprcUpdate or hrgnUpdate.
    /// You can set only one of these parameters to a non-NULL value. If both are NULL, RDW_VALIDATE validates the entire window.
    /// This value does not affect internal WM_PAINT messages.
    /// </summary>
    Validate = 0x8,

    NoInternalPaint = 0x10,

    /// <summary>Suppresses any pending WM_ERASEBKGND messages.</summary>
    NoErase = 0x20,

    /// <summary>Excludes child windows, if any, from the repainting operation.</summary>
    NoChildren = 0x40,

    /// <summary>Includes child windows, if any, in the repainting operation.</summary>
    AllChildren = 0x80,

    /// <summary>Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values, to receive WM_ERASEBKGND and WM_PAINT messages before the RedrawWindow returns, if necessary.</summary>
    UpdateNow = 0x100,

    /// <summary>
    /// Causes the affected windows, which you specify by setting the RDW_ALLCHILDREN and RDW_NOCHILDREN values, to receive WM_ERASEBKGND messages before RedrawWindow returns, if necessary.
    /// The affected windows receive WM_PAINT messages at the ordinary time.
    /// </summary>
    EraseNow = 0x200,

    Frame = 0x400,

    NoFrame = 0x800
}

Пример, тест и результат теста

  • вошел в Win XP как домен A\ad_user1
  • запустить приложение OpaciToggler.exe (Instance1, запустить как домен A\ad_user1)
  • Затем я нажимаю кнопку запустить что-то Он открывает другой файл OpaciToggler.exe (Instance2), запускается под другой учетной записью пользователя (запускается как localcomputer\l_user1) ИЛИ щелкните правой кнопкой мыши по файлу.exe, а затем нажмите "Запуск от имени".

Instance1

  • pid: 1234
  • запустить как: домен A\ad_user1
  • txtPid: 5678 (Экземпляр2, не работает)
  • txtPid: 1234 (самостоятельно, работает)
  • txtPid: любой pid, запущенный с той же учетной записью (например, notepad.exe, calc.exe и т. д., работает)

instance2

  • pid: 5678
  • запустить как: локальный компьютер \ l_user1
  • txtPid: 1234 (Экземпляр 1, не работает)
  • txtPid: 5678 (самостоятельно, работает)
  • txtPid: любой pid, запущенный с той же учетной записью (localcomputer\l_user1) (например: notepad.exe, calc.exe и т. д., не работает!!)

Опять мой вопрос

Как изменить прозрачность окна другого приложения, которая запускается под другой учетной записью пользователя?

Спасибо и извините за мой плохой английский:(.

0 ответов

Другие вопросы по тегам