4

I am trying in execute netsh winsock reset catalog command in command prompt from an elevated(has admin privileage) c++ application.

HINSTANCE retVal = ShellExecute(NULL, "open", "cmd", "\c netsh winsock reset catalog > CUninstall.log", NULL, SW_NORMAL); 

It just opens the command prompt and nothing else happens. I have tried

HINSTANCE retVal = ShellExecute(NULL, "runas", "cmd", "\c netsh winsock reset catalog > CUninstall.log", NULL, SW_NORMAL); 

and

HINSTANCE retVal = ShellExecute(NULL, "open", "cmd", " netsh winsock reset catalog > CUninstall.log", NULL, SW_NORMAL); 
Akhil V Suku
  • 870
  • 2
  • 13
  • 34
  • Use `CreateProcess` instead. – Jonathan Potter Jan 25 '18 at 07:22
  • createprocess also does the same, no difference. – Akhil V Suku Jan 25 '18 at 07:33
  • 5
    `/c` is the switch character. – ACatInLove Jan 25 '18 at 07:40
  • @JonathanPotter: The `"runas"` argument to `ShellExecute` runs the new process with elevated privileges. `CreateProcess` can't do that in any documented way. There is however a lower level COM interface that's used internally by `ShellExecute`. In essense with their inept design and implementation of security, Microsoft, among other idiocies (it was so bad that a great many people *paid* to downgrade from Vista to XP), turned upside down which function is basic and which is a wrapper. – Cheers and hth. - Alf Jan 25 '18 at 07:55
  • 1
    @Cheersandhth.-Alf OP says his process is already elevated. – Jonathan Potter Jan 25 '18 at 08:21

3 Answers3

2

Switch character was causing the problem. It worked when switch character changed from \c to /c.

Form

HINSTANCE retVal = ShellExecute(NULL, "open", "cmd", "\c netsh winsock reset catalog > CUninstall.log", NULL, SW_NORMAL);

to

HINSTANCE retVal = ShellExecute(NULL, "open", "cmd", "/c netsh winsock reset catalog > CUninstall.log", NULL, SW_NORMAL);
Akhil V Suku
  • 870
  • 2
  • 13
  • 34
1

It took some trial and error to find the optimal way, so I would like to share my solution. Put aside my recomendation to use Asynchronized calls, here is my DoRun() function:

BOOL DoRun(WCHAR *command)
{
    BOOL Result = FALSE;
    DWORD retSize;
    LPTSTR pTemp = NULL;
    TCHAR Command[BUFSIZE] = L"";
    if (!(DeleteFile(RESULTS_FILE)))
    {
        //return L"Can't delete previous results";
    }
    _tcscpy_s(Command, L"/C ");
    _tcscat_s(Command, command);
    _tcscat_s(Command, L" >");
    _tcscat_s(Command, RESULTS_FILE);
    wprintf(L"Calling:\n%s\n", Command);
    Result = (BOOL) ShellExecute(GetActiveWindow(), L"OPEN", L"cmd", Command, NULL, 0L);
    if(!Result)
    {
        retSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_ARGUMENT_ARRAY,
            NULL,
            GetLastError(),
            LANG_NEUTRAL,
            (LPTSTR)&pTemp,
            0,
            NULL);
        MessageBox(NULL,pTemp,L"Error",MB_OK);
    }
    return Result;
}
Michael Haephrati
  • 3,660
  • 1
  • 33
  • 56
-1
func runElevated(interName, stateName string, isAdmin bool) {
    /*
        禁用无线网卡:netsh interface set interface WLAN disabled
        启用无线网卡:netsh interface set interface WLAN enabled
        禁用有线网卡:netsh interface set interface 以太网 disabled
        启用有线网卡:netsh interface set interface 以太网 enabled
    */
    var verb string
    if isAdmin {
        verb = "open"
    } else {
        verb = "runas"
    }
    exe := "C:\\Windows\\system32\\cmd.exe" // or "cmd"
    cwd, _ := os.Getwd()
    var cmdList = make([]string, 0)
    var cmdMap = map[string]string{"WLAN": "以太网", "enable": "disable", "以太网": "WLAN", "disable": "enable"}
    cmdList = append(cmdList, fmt.Sprintf("/c netsh interface set interface %s %s", interName, stateName))
    cmdList = append(cmdList, fmt.Sprintf("/c netsh interface set interface %s %s", cmdMap[interName], cmdMap[stateName]))

    verbPtr, _ := syscall.UTF16PtrFromString(verb)
    exePtr, _ := syscall.UTF16PtrFromString(exe)
    cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
    for _, k := range cmdList {
        argPtr, _ := syscall.UTF16PtrFromString(k)
        err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, windows.SW_HIDE)
        if err != nil {
            log.Fatalf("execute error, detail %s", err)
        }
    }
    log.Fatal("execute success...")
}
  • 1
    Please don't make more work for other people by vandalizing your posts. By posting on the Stack Exchange network, you've granted a non-revocable right, under the [CC BY-SA 4.0 license](https://creativecommons.org/licenses/by-sa/4.0/), for Stack Exchange to distribute that content (i.e. regardless of your future choices). By Stack Exchange policy, the non-vandalized version of the post is the one which is distributed. Thus, any vandalism will be reverted. If you want to know more about deleting a post please see: [How does deleting work?](https://meta.stackexchange.com/q/5221) – Adriaan Sep 22 '22 at 07:30
  • Additionally, if you decide to leave the answer visible, please read [answer] and [edit] your answer to contain an explanation as to why this code would actually solve the problem at hand. Always remember that you're not only solving the problem, but are also educating the OP and any future readers of this post. – Adriaan Sep 22 '22 at 07:31
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – abdo Salm Sep 27 '22 at 02:03