## Batch, 182 bytes

 @set s=
 @set/ps=
 @set "t=%s:"=""%"
 @if "%t:"=""%"=="""=""""" goto g
 @for %%s in ("%s:"=%" "%t%")do @echo(%%~s>>_
 @for %%s in (_)do @set s=%%~zs
 @del _
 :g
 @cmd/cset/as/2-2*!!s

Testing for the empty string without breaking when quotes were present was cumbersome! Explanation:

 @set s=

Clear `s` as `set/p` leaves `s` unchanged if the input was empty.

 @set/ps=

Take input on STDIN into `s`.

 @set "t=%s:"=""%"

Try to quote all of the quotes in `s`. However, if `s` is empty, Batch throws a wobbly, and sets `t` to `"=""` instead, which still has an odd number of quotes.

 @if "%t:"=""%"=="""=""""" goto g

Quote all of the quotes in `t`, and compare the result to `""=""""`. This can only happen if `s` was empty, in which case we skip the measurement step.

 @for %%s in ("%s:"=%" "%t%")do @echo(%%~s>>_

Print `s` without quotes and `s` with quoted quotes on separate lines to a temporary file. The `(` is needed in case `s` only contains quotes.

 @for %%s in (_)do @set s=%%~zs

Obtain the length of the temporary file.

 @del _

Delete the temporary file.

 :g

Jump here if the input was empty.

 @cmd/cset/as/2-2*!!s

Halve and subtract 2 from the length of the temporary file. However if the input was empty then `s` will be treated as the numeric value zero, and the result of the expression is then zero as desired.

117 bytes without empty string support:

 @set/ps=
 @for %%s in ("%s:"=%" "%s:"=""%")do @echo(%%~s>>_
 @for %%s in (_)do @set s=%%~zs
 @del _
 @cmd/cset/as/2-2

93 bytes if support for `"`s is not necessary (84 bytes without `"` or empty string support):

 @set s=
 @set/ps=
 @set n=0
 :l
 @if not "%s%"=="" set/an+=1&set "s=%s:~1%"&goto l
 @echo %n%